MinGW serial i/o, hamlib, rigcat mods

pull/2/head
David Freese 2009-04-20 11:02:24 -05:00
rodzic a9c21e513e
commit 63ccc2f24d
8 zmienionych plików z 258 dodań i 108 usunięć

Wyświetl plik

@ -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 */ \

Wyświetl plik

@ -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);

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;};

Wyświetl plik

@ -209,7 +209,7 @@ bool hamlib_init(bool bPtt)
return false;
}
MilliSleep(200);
MilliSleep(500);
try {
need_freq = true;

Wyświetl plik

@ -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

Wyświetl plik

@ -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<XMLIOS>::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<XMLIOS>::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;
}

Wyświetl plik

@ -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;