diff --git a/src/include/configuration.h b/src/include/configuration.h index eddc2379..1f49ae76 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -227,7 +227,7 @@ ELEM_(bool, HamlibXONXOFFflow, "HAMLIBXONXOFFFLOW", 0) \ ELEM_(int, HamlibRetries, "HAMLIBRETRIES", 2) \ ELEM_(int, HamlibTimeout, "HAMLIBTIMEOUT", 10) \ - ELEM_(int, HamlibWait, "HAMLIBWAIT", 50) \ + ELEM_(int, HamlibWait, "HAMLIBWAIT", 5) \ ELEM_(int, HamlibWriteDelay, "HAMLIBWRITEDELAY", 0) \ ELEM_(int, HamlibSideband, "HAMLIBSIDEBAND", 0) /* SIDEBAND_RIG */ \ /* Operator */ \ diff --git a/src/include/ptt.h b/src/include/ptt.h index 4b53ae9d..b028b9d5 100644 --- a/src/include/ptt.h +++ b/src/include/ptt.h @@ -55,13 +55,17 @@ struct termios; +#ifdef __MINGW32__ +# include "serial.h" +#endif + class PTT { public: // The ptt_t enums must be defined even if the corresponding // code is not compiled. New tags go to the end of the list. enum ptt_t { PTT_INVALID = -1, PTT_NONE, PTT_HAMLIB, PTT_MEMMAP, - PTT_RIGCAT, PTT_TTY, PTT_PARPORT, PTT_UHROUTER, PTT_RIGCAT_HW + PTT_RIGCAT, PTT_TTY, PTT_PARPORT, PTT_UHROUTER }; PTT(ptt_t dev = PTT_NONE); @@ -81,6 +85,10 @@ private: int uhfd[2]; // ptt #endif +#ifdef __MINGW32__ + Cserial serPort; +#endif + void close_all(void); void open_tty(void); diff --git a/src/include/rigxml.h b/src/include/rigxml.h index 999ce3dd..084905a5 100644 --- a/src/include/rigxml.h +++ b/src/include/rigxml.h @@ -29,7 +29,7 @@ struct DATA { int shiftbits; void clear() { size = 0; - dtype = ""; + dtype.clear(); max = 199999999; min = 0; resolution = 1.0; @@ -51,7 +51,12 @@ struct XMLIOS { std::string ok; std::string bad; void clear() { - SYMBOL = str1 = str2 = info = ok = bad = ""; + SYMBOL.clear(); + str1.clear(); + str2.clear(); + info.clear(); + ok.clear(); + bad.clear(); size = fill1 = fill2 = 0; data.clear(); }; @@ -74,7 +79,7 @@ struct XMLRIG { bool echo; bool cmdptt; void clear() { - port = ""; + port.clear(); baud = 1200; dtr = false; dtrptt = false; diff --git a/src/include/serial.h b/src/include/serial.h index ec3fe903..b2fb20bb 100644 --- a/src/include/serial.h +++ b/src/include/serial.h @@ -121,7 +121,7 @@ public: void Timeout(int tm) { timeout = tm; return; }; int Timeout() { return timeout; }; - void FlushBuffer() {}; + void FlushBuffer(); void Device (std::string dev) { device = dev;}; std::string Device() { return device;}; diff --git a/src/rigcontrol/hamlib.cxx b/src/rigcontrol/hamlib.cxx index 049416a1..7e99a4c6 100644 --- a/src/rigcontrol/hamlib.cxx +++ b/src/rigcontrol/hamlib.cxx @@ -209,7 +209,7 @@ bool hamlib_init(bool bPtt) return false; } - MilliSleep(200); + MilliSleep(500); try { need_freq = true; diff --git a/src/rigcontrol/ptt.cxx b/src/rigcontrol/ptt.cxx index 87d879e4..deef2f53 100644 --- a/src/rigcontrol/ptt.cxx +++ b/src/rigcontrol/ptt.cxx @@ -171,12 +171,28 @@ void PTT::close_all(void) void PTT::open_tty(void) { -#if HAVE_TTYPORT +#ifdef __MINGW32__ + serPort.Device(progdefaults.PTTdev); + serPort.RTS(progdefaults.RTSplus); + serPort.DTR(progdefaults.DTRplus); + serPort.RTSptt(progdefaults.RTSptt); + serPort.DTRptt(progdefaults.DTRptt); + if (serPort.OpenPort() == false) { + LOG_ERROR("Cannot open serial port %s", rigio.Device().c_str()); + pttfd = -1; + return; + } + LOG_DEBUG("Serial port %s open", progdefaults.PTTdev.c_str()); + pttfd = -1; // just a dummy return for this implementation + +#else + +# if HAVE_TTYPORT string pttdevName = progdefaults.PTTdev; -#ifdef __CYGWIN__ +# ifdef __CYGWIN__ // convert to Linux serial port naming com_to_tty(pttdevName); -#endif +# endif if ((pttfd = open(pttdevName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY)) < 0) { LOG_ERROR("Could not open \"%s\": %s", pttdevName.c_str(), strerror(errno)); @@ -201,23 +217,32 @@ void PTT::open_tty(void) ioctl(pttfd, TIOCMSET, &status); LOG_DEBUG("Serial port %s open; status = %02X, %s", progdefaults.PTTdev.c_str(), status, uint2bin(status, 8)); -#endif // HAVE_TTYPORT +# endif // HAVE_TTYPORT +#endif // __MINGW32__ } void PTT::close_tty(void) { -#if HAVE_TTYPORT +#ifdef __MINGW32__ + serPort.ClosePort(); + LOG_DEBUG("Serial port %s closed", progdefaults.PTTdev.c_str()); +#else +# if HAVE_TTYPORT if (pttfd >= 0) { tcsetattr(pttfd, TCSANOW, oldtio); close(pttfd); } delete oldtio; -#endif +# endif // HAVE_TTYPORT +#endif // __MINGW32__ } void PTT::set_tty(bool ptt) { -#if HAVE_TTYPORT +#ifdef __MINGW32__ + serPort.SetPTT(ptt); +#else +# if HAVE_TTYPORT int status; ioctl(pttfd, TIOCMGET, &status); @@ -242,7 +267,8 @@ void PTT::set_tty(bool ptt) } LOG_DEBUG("Status %02X, %s", status & 0xFF, uint2bin(status, 8)); ioctl(pttfd, TIOCMSET, &status); -#endif +# endif // HAVE_TTYPORT +#endif // __MINGW32__ } #if HAVE_PARPORT diff --git a/src/rigcontrol/rigio.cxx b/src/rigcontrol/rigio.cxx index e2cb896f..4051e580 100644 --- a/src/rigcontrol/rigio.cxx +++ b/src/rigcontrol/rigio.cxx @@ -63,7 +63,7 @@ int readtimeout, readwait; bool hexout(const string& s, int retnbr) { - LOG_DEBUG("cmd = %s", str2hex(s.data(), s.length())); + LOG_DEBUG("cmd %d bytes = %s", s.length(), str2hex(s.data(), s.length())); for (int n = 0; n < progdefaults.RigCatRetries; n++) { int num = 0; @@ -74,9 +74,9 @@ bool hexout(const string& s, int retnbr) rigio.FlushBuffer(); rigio.WriteBuffer(sendbuff, s.size()); if (progdefaults.RigCatECHO == true) { - MilliSleep(10); +// MilliSleep(50); num = rigio.ReadBuffer (replybuff, s.size()); - LOG_DEBUG("echoed = %s", str2hex(replybuff, num)); + LOG_DEBUG("echoed %d bytes = %s", num, str2hex(replybuff, num)); } // wait before trying to read response if ((readwait = progdefaults.RigCatWait) > 0) @@ -275,10 +275,13 @@ long long fm_freqdata(DATA d, size_t p) num = (int)(d.resolution * 100); den = 100; if (d.dtype == "BCD") { - if (d.reverse == true) + if (d.reverse == true) { + // LOG_INFO("BCD reverse"); return (long long int)(fm_bcd_be(p, d.size) * num / den); - else + } else { + // LOG_INFO("BCD normal"); return (long long int)(fm_bcd(p, d.size) * num / den); + } } else if (d.dtype == "BINARY") { if (d.reverse == true) return (long long int)(fm_binary_be(p, d.size) * num / den); @@ -318,62 +321,69 @@ long long rigCAT_getfreq() } modeCmd = *itrCmd; - + if ( modeCmd.str1.empty() == false) strCmd.append(modeCmd.str1); if (modeCmd.str2.empty() == false) strCmd.append(modeCmd.str2); - if (modeCmd.info.size()) { - list::iterator preply = reply.begin(); - while (preply != reply.end()) { - if (preply->SYMBOL == modeCmd.info) { - XMLIOS rTemp = *preply; - size_t p = 0, pData = 0; - size_t len = rTemp.str1.size(); - -// send the command - if (hexout(strCmd, rTemp.size ) == false) { - return -1; - } - -// check the pre data string - if (len) { - for (size_t i = 0; i < len; i++) - if ((char)rTemp.str1[i] != (char)replybuff[i]) { - return 0; - } - p = len; - } - if (rTemp.fill1) p += rTemp.fill1; - pData = p; - if (rTemp.data.dtype == "BCD") { - p += rTemp.data.size / 2; - if (rTemp.data.size & 1) p++; - } else - p += rTemp.data.size; -// check the post data string - len = rTemp.str2.size(); - if (rTemp.fill2) p += rTemp.fill2; - if (len) { - for (size_t i = 0; i < len; i++) - if ((char)rTemp.str2[i] != (char)replybuff[p + i]) { - return 0; - } - } -// convert the data field - long long f = fm_freqdata(rTemp.data, pData); - if ( f >= rTemp.data.min && f <= rTemp.data.max) { - return f; - } - else { + if (modeCmd.info.size() == 0) + return 0; + + for (list::iterator preply = reply.begin(); preply != reply.end(); ++preply) { + if (preply->SYMBOL != modeCmd.info) + continue; + + XMLIOS rTemp = *preply; + size_t p = 0, pData = 0; + size_t len = rTemp.str1.size(); + + // send the command + if (hexout(strCmd, rTemp.size ) == false) { + LOG_ERROR("Hexout failed"); + return -1; + } + + // check the pre data string + if (len) { + for (size_t i = 0; i < len; i++) { + if ((char)rTemp.str1[i] != (char)replybuff[i]) { + LOG_WARN("failed pre data string test @ %d", i); return 0; } } - preply++; + p = len; + } + if (rTemp.fill1) p += rTemp.fill1; + pData = p; + if (rTemp.data.dtype == "BCD") { + p += rTemp.data.size / 2; + if (rTemp.data.size & 1) p++; + } else + p += rTemp.data.size; + // check the post data string + len = rTemp.str2.size(); + if (rTemp.fill2) p += rTemp.fill2; + if (len) { + for (size_t i = 0; i < len; i++) + if ((char)rTemp.str2[i] != (char)replybuff[p + i]) { + LOG_WARN("failed post data string test @ %d", i); + return 0; + } + } + // convert the data field + long long f = fm_freqdata(rTemp.data, pData); + if ( f >= rTemp.data.min && f <= rTemp.data.max) { + LOG_INFO("freq value returned %ld", (long)f); + return f; + } + else { + LOG_WARN("freq value failed %ld", f); + return 0; } } + return 0; } diff --git a/src/rigcontrol/serial.cxx b/src/rigcontrol/serial.cxx index 483e90fd..40f6cbce 100644 --- a/src/rigcontrol/serial.cxx +++ b/src/rigcontrol/serial.cxx @@ -283,7 +283,9 @@ BOOL Cserial::OpenPort() if(hComm == INVALID_HANDLE_VALUE) return FALSE; + ConfigurePort( baud, 8, FALSE, NOPARITY, ONESTOPBIT); + return TRUE; } @@ -360,6 +362,12 @@ int Cserial::ReadChars (unsigned char *buf, int nchars, int msec) return ReadData (buf, nchars); } +void Cserial::FlushBuffer() +{ + unsigned char c; + while (ReadByte(c) == true); +} + /////////////////////////////////////////////////////// // Function name : Cserial::WriteByte // Description : Writes a Byte to teh selected port @@ -413,26 +421,108 @@ BOOL Cserial::SetCommunicationTimeouts( if((bPortReady = GetCommTimeouts (hComm, &CommTimeoutsSaved))==0) { return FALSE; } + LOG_INFO("\n\ +COMMTIMOUT Original values:\n\ + Read Interval Timeout............... %ld\n\ + Read Total Timeout Multiplier....... %ld\n\ + Read Total Timeout Constant Timeout. %ld\n\ + Write Total Timeout Constant........ %ld\n\ + Write Total Timeout Multiplier...... %ld", + CommTimeoutsSaved.ReadIntervalTimeout, + CommTimeoutsSaved.ReadTotalTimeoutMultiplier, + CommTimeoutsSaved.ReadTotalTimeoutConstant, + CommTimeoutsSaved.WriteTotalTimeoutConstant, + CommTimeoutsSaved.WriteTotalTimeoutMultiplier); - CommTimeouts.ReadIntervalTimeout = ReadIntervalTimeout; - CommTimeouts.ReadTotalTimeoutMultiplier = ReadTotalTimeoutMultiplier; - CommTimeouts.ReadTotalTimeoutConstant = ReadTotalTimeoutConstant; - CommTimeouts.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant; - CommTimeouts.WriteTotalTimeoutMultiplier = WriteTotalTimeoutMultiplier; - - bPortReady = SetCommTimeouts (hComm, &CommTimeouts); - - if(bPortReady ==0) { - CloseHandle(hComm); - return FALSE; - } - - return TRUE; + CommTimeouts.ReadIntervalTimeout = ReadIntervalTimeout; + CommTimeouts.ReadTotalTimeoutMultiplier = ReadTotalTimeoutMultiplier; + CommTimeouts.ReadTotalTimeoutConstant = ReadTotalTimeoutConstant; + CommTimeouts.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant; + CommTimeouts.WriteTotalTimeoutMultiplier = WriteTotalTimeoutMultiplier; + + bPortReady = SetCommTimeouts (hComm, &CommTimeouts); + + if(bPortReady ==0) { + CloseHandle(hComm); + return FALSE; + } + + return TRUE; } BOOL Cserial::SetCommTimeout() { -// return SetCommunicationTimeouts (500L, 0L, 0L, 0L, 0L); - return SetCommunicationTimeouts ( MAXDWORD, 0L, 0L, 100L, 0L); +/* + * ReadIntervalTimeout + * + * The maximum time allowed to elapse between the arrival of two bytes on the + * communications line, in milliseconds. During a ReadFile operation, the time + * period begins when the first byte is received. If the interval between the + * arrival of any two bytes exceeds this amount, the ReadFile operation is + * completed and any buffered data is returned. A value of zero indicates that + * interval time-outs are not used. + * + * A value of MAXDWORD, combined with zero values for both the + * ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies + * that the read operation is to return immediately with the bytes that have + * already been received, even if no bytes have been received. + * + * ReadTotalTimeoutMultiplier + * + * The multiplier used to calculate the total time-out period for read + * operations, in milliseconds. For each read operation, this value is + * multiplied by the requested number of bytes to be read. + * + * ReadTotalTimeoutConstant + * + * A constant used to calculate the total time-out period for read operations, + * in milliseconds. For each read operation, this value is added to the product + * of the ReadTotalTimeoutMultiplier member and the requested number of bytes. + * + * A value of zero for both the ReadTotalTimeoutMultiplier and + * ReadTotalTimeoutConstant members indicates that total time-outs are not + * used for read operations. + * + * WriteTotalTimeoutMultiplier + * + * The multiplier used to calculate the total time-out period for write + * operations, in milliseconds. For each write operation, this value is + * multiplied by the number of bytes to be written. + * + * WriteTotalTimeoutConstant + * + * A constant used to calculate the total time-out period for write operations, + * in milliseconds. For each write operation, this value is added to the product + * of the WriteTotalTimeoutMultiplier member and the number of bytes to be + * written. + * + * A value of zero for both the WriteTotalTimeoutMultiplier and + * WriteTotalTimeoutConstant members indicates that total time-outs are not + * used for write operations. + * + * Remarks + * + * If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier to + * MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than zero and + * less than MAXDWORD, one of the following occurs when the ReadFile function + * is called: + * + * If there are any bytes in the input buffer, ReadFile returns immediately + * with the bytes in the buffer. + * + * If there are no bytes in the input buffer, ReadFile waits until a byte + * arrives and then returns immediately. + * + * If no bytes arrive within the time specified by ReadTotalTimeoutConstant, + * ReadFile times out. +*/ +// return SetCommunicationTimeouts (0, 500L, 0L, 100L, 0L ); + return SetCommunicationTimeouts ( + 0L, // Read Interval Timeout + 50l, // Read Total Timeout Multiplier + 0l, // Read Total Timeout Constant + 50L, // Write Total Timeout Constant + 0L // Write Total Timeout Multiplier + ); } /////////////////////////////////////////////////////// @@ -445,11 +535,11 @@ BOOL Cserial::SetCommTimeout() { // Argument : BYTE Parity // Argument : BYTE StopBits /////////////////////////////////////////////////////// -BOOL Cserial::ConfigurePort(DWORD BaudRate, - BYTE ByteSize, - DWORD dwParity, - BYTE Parity, - BYTE StopBits) +BOOL Cserial::ConfigurePort(DWORD BaudRate, + BYTE ByteSize, + DWORD dwParity, + BYTE Parity, + BYTE StopBits) { if((bPortReady = GetCommState(hComm, &dcb))==0) { LOG_ERROR("GetCommState Error on %s", device.c_str()); @@ -457,36 +547,42 @@ BOOL Cserial::ConfigurePort(DWORD BaudRate, return FALSE; } - dcb.BaudRate = BaudRate; - dcb.ByteSize = ByteSize; - dcb.Parity = Parity ; - dcb.StopBits = StopBits; - dcb.fBinary = TRUE; - dcb.fDsrSensitivity = FALSE; - dcb.fParity = dwParity; - dcb.fOutX = FALSE; - dcb.fInX = FALSE; - dcb.fNull = FALSE; - dcb.fAbortOnError = TRUE; - dcb.fOutxCtsFlow = FALSE; - dcb.fOutxDsrFlow = FALSE; - + dcb.BaudRate = BaudRate; + dcb.ByteSize = ByteSize; + dcb.Parity = Parity ; + dcb.StopBits = StopBits; + dcb.fBinary = TRUE; + dcb.fDsrSensitivity = FALSE; + dcb.fParity = dwParity; + dcb.fOutX = FALSE; + dcb.fInX = FALSE; + dcb.fNull = FALSE; + dcb.fAbortOnError = TRUE; + dcb.fOutxCtsFlow = FALSE; + dcb.fOutxDsrFlow = FALSE; + if (dtr) dcb.fDtrControl = DTR_CONTROL_ENABLE; else - dcb.fDtrControl = DTR_CONTROL_DISABLE; - dcb.fDsrSensitivity = FALSE; - if (rts) + dcb.fDtrControl = DTR_CONTROL_DISABLE; + + dcb.fDsrSensitivity = FALSE; + + if (rtscts) dcb.fRtsControl = RTS_CONTROL_ENABLE; - else - dcb.fRtsControl = RTS_CONTROL_DISABLE; - + else { + if (rts) + dcb.fRtsControl = RTS_CONTROL_ENABLE; + else + dcb.fRtsControl = RTS_CONTROL_DISABLE; + } + bPortReady = SetCommState(hComm, &dcb); if(bPortReady == 0) { CloseHandle(hComm); return FALSE; } - return SetCommTimeout(); + return SetCommTimeout(); } /////////////////////////////////////////////////////// @@ -495,10 +591,15 @@ BOOL Cserial::ConfigurePort(DWORD BaudRate, /////////////////////////////////////////////////////// void Cserial::SetPTT(bool b) { - if(hComm == INVALID_HANDLE_VALUE) + if(hComm == INVALID_HANDLE_VALUE) { + LOG_ERROR("Invalid handle"); return; + } if ( !(dtrptt || rtsptt) ) return; + LOG_INFO("PTT = %d, DTRptt = %d, DTR = %d, RTSptt = %d, RTS = %d", + b, dtrptt, dtr, rtsptt, rts); + if (b == true) { // ptt enabled if (dtrptt && dtr) dcb.fDtrControl = DTR_CONTROL_DISABLE;