Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 215 → Rev 216

/common/SerialPort.h
32,7 → 32,12
// ---- Include Files -------------------------------------------------------
 
#include <stddef.h>
#include <stdint.h>
 
#if defined( WIN32 )
#include <windows.h>
#endif
 
/**
* @addtogroup SerialPort
* @{
75,9 → 80,9
 
//------------------------------------------------------------------------
// Sets the timeout to use when waiting for data. 0 = infinite
// The timeout is specified in 1/10ths of a second.
// The timeout is specified in milliseconds.
 
bool SetTimeout( uint8_t timeout );
bool SetTimeout( unsigned timeout );
 
//------------------------------------------------------------------------
// Writes data to the serial port.
100,7 → 105,11
 
//------------------------------------------------------------------------
 
#if defined( WIN32 )
HANDLE m_serialHndl;
#else
int m_fd;
#endif
};
 
// ---- Inline Functions ----------------------------------------------------
/common/mingw/Error.h
0,0 → 1,47
/****************************************************************************
*
* Copyright (c) 2003 Dave Hylands
* All Rights Reserved
*
* Permission is granted to any individual or institution to use, copy, or
* redistribute this software so long as it is not sold for profit, and that
* this copyright notice is retained.
*
****************************************************************************/
/**
*
* @file Error.h
*
* @brief Functions to aid in the process of error handling.
*
****************************************************************************/
/**
* @defgroup Error Error Handling function.
*
* @brief Contains function to aid in the error handling process.
*
****************************************************************************/
 
#if !defined( ERROR_H )
#define ERROR_H ///< Include Guard
 
// ---- Include Files -------------------------------------------------------
 
#if !defined( _WINDOWS_ )
# include <windows.h>
#endif
 
/**
* @addtogroup Error
* @{
*/
 
//---------------------------------------------------------------------------
 
char *GetErrorStr( DWORD errNum, char *errStr, size_t maxLen );
char *GetLastErrorStr( char *errStr, size_t maxLen );
 
/** @} */
 
#endif // ERROR_H
 
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: mingw/SerialPort.cpp
===================================================================
--- mingw/SerialPort.cpp (nonexistent)
+++ mingw/SerialPort.cpp (revision 216)
@@ -0,0 +1,349 @@
+/****************************************************************************
+*
+* Copyright (c) 2009 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file SerialPort.cpp
+*
+* @brief This file implements the SerialPort class using the posix
+* API, which is supported by cygwin and linux.
+*
+****************************************************************************/
+
+// ---- Include Files -------------------------------------------------------
+
+#include "Log.h"
+#include "SerialPort.h"
+#include "Str.h"
+#include "Error.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <windows.h>
+
+// ---- Public Variables ----------------------------------------------------
+
+// ---- Private Constants and Types -----------------------------------------
+// ---- Private Variables ---------------------------------------------------
+// ---- Private Function Prototypes -----------------------------------------
+// ---- Functions -----------------------------------------------------------
+
+/**
+ * @addtogroup SerialPort
+ * @{
+ */
+
+//***************************************************************************
+/**
+* Constructor
+*/
+
+SerialPort::SerialPort()
+ : m_serialHndl( INVALID_HANDLE_VALUE )
+{
+}
+
+//***************************************************************************
+/**
+* Destructor
+*/
+
+SerialPort::~SerialPort()
+{
+ Close();
+}
+
+//***************************************************************************
+/**
+* Closes a previously opened serial port
+*/
+
+void SerialPort::Close()
+{
+ if ( m_serialHndl != INVALID_HANDLE_VALUE )
+ {
+ CloseHandle( m_serialHndl );
+
+ m_serialHndl = INVALID_HANDLE_VALUE;
+ }
+
+} // Close
+
+//***************************************************************************
+/**
+* Opens a serial port.
+*/
+
+bool SerialPort::Open( const char *devName, const char *param )
+{
+ DWORD err;
+ char errStr[ 200 ];
+ char dcbParam[ 40 ];
+
+ LogVerbose( "Port: '%s' Param: %s\n", devName, param );
+
+ m_serialHndl = CreateFile( devName, // lpFileName
+ GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
+ 0, // dwShareMode
+ NULL, // lpSecurityAttributes
+ OPEN_EXISTING, // dwCreationDisposition
+ 0, // dwFlagsAndAttributes
+ NULL ); // hTemplateFile
+
+ if ( m_serialHndl == INVALID_HANDLE_VALUE )
+ {
+ err = GetLastError();
+
+ LogError( "Unable to open COM port '%s'.\n", devName );
+ LogError( "%s", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ return false;
+ }
+
+ DCB dcb;
+ COMMTIMEOUTS timeouts;
+
+ memset( &dcb, 0, sizeof( dcb ));
+ dcb.DCBlength = sizeof( dcb );
+
+ memset( &timeouts, 0, sizeof( timeouts ));
+
+ if ( !GetCommState( m_serialHndl, &dcb ))
+ {
+ err = GetLastError();
+
+ LogError( "Call to GetCommState failed for '%s'.\n", devName );
+ LogError( "%s", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ Close();
+ return false;
+ }
+
+ if ( !GetCommTimeouts( m_serialHndl, &timeouts ))
+ {
+ err = GetLastError();
+
+ LogError( "Call to GetCommTimeouts failed for '%s'.\n", devName );
+ LogError( "%s", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ Close();
+ return false;
+ }
+
+ dcb.BaudRate = 19200;
+ dcb.ByteSize = 8;
+ dcb.Parity = NOPARITY;
+ dcb.StopBits = ONESTOPBIT;
+
+ dcb.fBinary = 1;
+ dcb.fParity = 0;
+
+ dcb.fOutX = 0;
+ dcb.fOutxCtsFlow = 0;
+ dcb.fOutxDsrFlow = 0;
+ dcb.fInX = 0;
+
+ dcb.fDtrControl = DTR_CONTROL_ENABLE;
+ dcb.fRtsControl = RTS_CONTROL_ENABLE;
+ dcb.fDsrSensitivity = 0;
+ dcb.fTXContinueOnXoff = 1;
+
+ timeouts.ReadIntervalTimeout = 1;
+ timeouts.ReadTotalTimeoutMultiplier = 1;
+
+ // COM1: baud=9600 parity=N data=8 stop=1
+
+ snprintf( dcbParam, sizeof( dcbParam ), "baud=%s", param );
+
+ if ( !BuildCommDCBAndTimeouts( dcbParam, &dcb, &timeouts ))
+ {
+ err = GetLastError();
+
+ LogError( "Unable to parse COM parameters: '%s'.\n", param );
+ LogError( "%s", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ Close();
+ return false;
+ }
+
+ char parityChar;
+
+ switch ( dcb.Parity )
+ {
+ case EVENPARITY: parityChar = 'E'; break;
+ case ODDPARITY: parityChar = 'O'; break;
+ case NOPARITY: parityChar = 'N'; break;
+ case MARKPARITY: parityChar = 'M'; break;
+ case SPACEPARITY: parityChar = 'S'; break;
+ default: parityChar = '*'; break;
+ }
+
+ const char *stopStr;
+
+ switch ( dcb.StopBits )
+ {
+ case ONESTOPBIT: stopStr = "1"; break;
+ case ONE5STOPBITS: stopStr = "1.5"; break;
+ case TWOSTOPBITS: stopStr = "2"; break;
+ default: stopStr = "*"; break;
+ }
+
+ if ( !SetCommState( m_serialHndl, &dcb ))
+ {
+ err = GetLastError();
+
+ LogError( "Call to SetCommState failed for '%s'.\n", devName );
+ LogError( "%s", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ Close();
+ return false;
+ }
+
+ if ( !SetCommTimeouts( m_serialHndl, &timeouts ))
+ {
+ err = GetLastError();
+
+ LogError( "Call to SetCommTimeouts failed for '%s'.\n", devName );
+ LogError( "%s", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ Close();
+ return false;
+ }
+
+ return true;
+
+} // Open
+
+//***************************************************************************
+/**
+* Reads data from the serial port.
+*/
+
+size_t SerialPort::Read( void *buf, size_t bufSize )
+{
+ DWORD bytesRead;
+ DWORD err;
+ char errStr[ 200 ];
+
+ if ( m_serialHndl == INVALID_HANDLE_VALUE )
+ {
+ return 0;
+ }
+ GetLastError();
+ SetLastError( 0 );
+
+ if ( !ReadFile( m_serialHndl, buf, bufSize, &bytesRead, NULL ))
+ {
+ err = GetLastError();
+
+ LogError( "SerialPort::Read failed: %s\n", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ return 0;
+ }
+
+#if 0
+ if ( bytesRead == 0 )
+ {
+ err = GetLastError();
+ Log( "************* Read returning 0 %s", GetErrorStr( err, errStr, sizeof( errStr)) );
+ }
+#endif
+
+ return bytesRead;
+
+} // Read
+
+//***************************************************************************
+/**
+* Sets the timeout to use when waiting for data. 0 = infinite
+* The timeout is specified in milliseconds.
+*/
+bool SerialPort::SetTimeout( unsigned timeout )
+{
+ DWORD err;
+ char errStr[ 200 ];
+ COMMTIMEOUTS timeouts;
+
+ if ( m_serialHndl == INVALID_HANDLE_VALUE )
+ {
+ return false;
+ }
+
+ if ( !GetCommTimeouts( m_serialHndl, &timeouts ))
+ {
+ err = GetLastError();
+
+ LogError( "Call to GetCommTimeouts failed.\n" );
+ LogError( "%s", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ return false;
+ }
+
+ timeouts.ReadIntervalTimeout = timeout;
+ timeouts.ReadTotalTimeoutMultiplier = timeout;
+
+ if ( !SetCommTimeouts( m_serialHndl, &timeouts ))
+ {
+ err = GetLastError();
+
+ LogError( "Call to SetCommTimeouts failed.\n" );
+ LogError( "%s", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ return false;
+ }
+
+ return true;
+
+} // SetTimeout
+
+//***************************************************************************
+/**
+* Writes data to the serial port.
+*/
+
+size_t SerialPort::Write( const void *buf, size_t bytesToWrite )
+{
+ DWORD bytesWritten;
+ DWORD err;
+ char errStr[ 200 ];
+
+ if ( !WriteFile( m_serialHndl, buf, bytesToWrite, &bytesWritten, NULL ))
+ {
+ err = GetLastError();
+
+ LogError( "SerialPort::Write failed: %s\n", GetErrorStr( err, errStr, sizeof( errStr )));
+
+ return 0;
+
+ }
+
+ return bytesWritten;
+
+} // Write
+
+//***************************************************************************
+/**
+* Resets the target
+*/
+
+void SerialPort::StrobeRTS( int strobeWidthInMsec )
+{
+ (void)strobeWidthInMsec;
+
+ LogError( "SerialPort::StrobeRTS not implemented yet\n" );
+
+} // StrobeRTS
+
+/** @} */
+
Index: mingw/Error.cpp
===================================================================
--- mingw/Error.cpp (nonexistent)
+++ mingw/Error.cpp (revision 216)
@@ -0,0 +1,87 @@
+/****************************************************************************
+*
+* Copyright (c) 2003 Dave Hylands
+* All Rights Reserved
+*
+* Permission is granted to any individual or institution to use, copy, or
+* redistribute this software so long as it is not sold for profit, and that
+* this copyright notice is retained.
+*
+****************************************************************************/
+/**
+*
+* @file Error.cpp
+*
+* @brief Implements the error helper functions.
+*
+****************************************************************************/
+
+// ---- Include Files -------------------------------------------------------
+
+#include "Error.h"
+#include "Str.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+// ---- Public Variables ----------------------------------------------------
+// ---- Private Constants and Types -----------------------------------------
+// ---- Private Variables ---------------------------------------------------
+// ---- Private Function Prototypes -----------------------------------------
+// ---- Functions -----------------------------------------------------------
+
+/**
+ * @addtogroup Error
+ * @{
+ */
+
+
+//***************************************************************************
+/**
+* Translates error number @a errNum into a string.
+*
+* @returns A pointer to errStr.
+*/
+
+char *GetErrorStr
+(
+ DWORD errNum, ///< Error number to get the string version for.
+ char *errStr, ///< Place to store the error string.
+ size_t maxLen ///< Max length that can be written into errStr.
+)
+{
+ if ( FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, // dwFlags
+ 0, // lpSource
+ errNum, // dwMessageId
+ GetUserDefaultLangID(), // dwlanguageId
+ errStr, // lpBuffer
+ maxLen, // nSize
+ NULL ) == 0 ) // arguments
+ {
+ StrPrintf( errStr, maxLen, "*** Unknown Error: %d ***", errNum );
+ }
+
+ return errStr;
+
+} // GetErrorStr
+
+//***************************************************************************
+/**
+* Translates the result of calling @a GetLastError() into a string.
+*
+* @returns A pointer to errStr.
+*/
+
+char *GetLastErrorStr
+(
+ char *errStr, ///< Place to store the error string.
+ size_t maxLen ///< Max length that can be written into errStr.
+)
+{
+ return GetErrorStr( GetLastError(), errStr, maxLen );
+
+} // GetLastErrorStr
+
+/** @} */
+
+
/mingw/Error.cpp
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: posix/SerialPort.cpp
===================================================================
--- posix/SerialPort.cpp (revision 215)
+++ posix/SerialPort.cpp (revision 216)
@@ -234,12 +234,17 @@
//***************************************************************************
/**
* Sets the timeout to use when waiting for data. 0 = infinite
-* The timeout is specified in 1/10ths of a second.
+* The timeout is specified in milliseconds.
*/
-bool SerialPort::SetTimeout( uint8_t timeout )
+bool SerialPort::SetTimeout( unsigned timeout )
{
struct termios attr;
+ if ( m_fd < 0 )
+ {
+ return false;
+ }
+
if ( tcgetattr( m_fd, &attr ) < 0 )
{
LogError( "B: Call to tcgetattr failed: %s\n", strerror( errno ));
@@ -253,7 +258,16 @@
}
else
{
- attr.c_cc[ VTIME ] = timeout; // timeout in tenths of a second
+ // Note. termios only supports timeouts specified in tenths of
+ // a second, so we need convert from milliseconds.
+
+ timeout = ( timeout + 99 ) / 100;
+ if ( timeout > 255 )
+ {
+ timeout = 255;
+ }
+
+ attr.c_cc[ VTIME ] = (uint8_t)timeout; // timeout in tenths of a second
attr.c_cc[ VMIN ] = 0;
}
/common/BioloidCommandLine.cpp
336,13 → 336,13
return true;
}
 
Log( "%s %d ", devType->devTypeStr, id );
if (( err = m_device.Ping()) == Bioloid::ERROR_NONE )
{
Log( "Response Received\n" );
Log( "%s %d Response Received\n", devType->devTypeStr, id );
}
else
{
Log( "%s %d ", devType->devTypeStr, id );
PrintError( err );
}
}
/common/BioloidBus.cpp
79,15 → 79,38
{
uint8_t ch;
 
#if 0
int i;
 
for ( i = 0; i < 10; i++ )
{
if ( ReadByte( &ch ))
{
break;
}
}
if ( i >= 10 )
{
LogError( "BioloidBus::ReadStatusPacket: ReadByte returned false\n");
return false;
}
#else
if ( !ReadByte( &ch ))
{
//LogError( "BioloidBus::ReadStatusPacket: ReadByte returned false\n");
return false;
}
#endif
 
err = pkt->ProcessChar( ch );
 
} while ( err == Bioloid::ERROR_NOT_DONE );
 
if ( err != Bioloid::ERROR_NONE )
{
Log( "BioloidBus::ReadStatusPacket err = %d\n", err );
}
 
return err == Bioloid::ERROR_NONE;
}