40 #if defined( OSNAME_LINUX ) 43 #elif defined( OSNAME_CYGWIN ) 48 # include <Pcan_usb.h> 52 # include <Pcan_usb.h> 55 # error "FIXME: support for PEAK CAN devices in other systems than linux/cygwin is not provided yet!" 69 #if defined( OSNAME_LINUX ) 70 # define USE_HANDLES( H_ ) (H_), 71 # define USE_HANDLE( H_ ) (H_) 76 # define USE_HANDLES( H_ ) 77 # define USE_HANDLE( H_ ) 92 #define SDH_CANSERIAL_PEAK_DEBUG 1 98 #if SDH_CANSERIAL_PEAK_DEBUG 132 #if defined( OSNAME_LINUX ) 144 #if defined( OSNAME_LINUX ) 146 # define M_CMSG_MSG() m_cmsg.Msg 149 # define M_CMSG_MSG() m_cmsg 165 if ( _timeout < 0.0 )
170 baudrate = _baudrate;
171 SetTimeout( _timeout );
173 id_write = _id_write;
174 strncpy(m_device, device, 64);
176 ungetch_valid =
false;
183 if ( _timeout < 0.0 )
186 #if defined( OSNAME_LINUX ) 187 if ( _peak_handle ==
NULL )
192 pimpl->peak_handle = _peak_handle;
194 SetTimeout( _timeout );
196 id_write = _id_write;
198 ungetch_valid =
false;
236 if (pimpl->peak_handle ==
NULL)
239 DBG( dbg <<
"Opening PEAK CAN baudrate: " << baudrate <<
", id_read: 0x" << std::hex << id_read <<
", id_write: 0x" << id_write << std::dec <<
"\n" );
241 #if defined( OSNAME_LINUX ) 242 pimpl->peak_handle = LINUX_CAN_Open((
char*) m_device, O_RDWR );
243 if (pimpl->peak_handle ==
NULL)
245 pimpl->rc = nGetLastError();
247 pimpl->peak_handle =
NULL;
254 pimpl->rc = CAN_Init(
USE_HANDLES( pimpl->peak_handle ) WORD(BaudrateToBaudrateCode(baudrate)), CAN_INIT_TYPE_ST);
257 #if ! defined( OSNAME_LINUX ) 258 pimpl->peak_handle =
NULL;
261 baudrate, m_device, GetLastErrorMessage() ) );
264 pimpl->rc = CAN_ResetFilter(
USE_HANDLE(pimpl->peak_handle) );
267 #if ! defined( OSNAME_LINUX ) 268 pimpl->peak_handle =
NULL;
271 (
unsigned int) id_read, m_device, GetLastErrorMessage() ) );
274 pimpl->rc = CAN_MsgFilter(
USE_HANDLES(pimpl->peak_handle) DWORD(id_read), DWORD(id_read), MSGTYPE_STANDARD);
277 #if ! defined( OSNAME_LINUX ) 278 pimpl->peak_handle =
NULL;
281 (
unsigned int) id_read, m_device, GetLastErrorMessage() ) );
285 pimpl->M_CMSG_MSG().LEN = 0;
286 pimpl->m_cmsg_next = 0;
294 return ( pimpl->peak_handle!=
NULL );
301 if ( pimpl->peak_handle ==
NULL )
304 CAN_Close(
USE_HANDLE( pimpl->peak_handle ) );
305 pimpl->peak_handle =
NULL;
313 case 1000000:
return CAN_BAUD_1M;
314 case 800000:
return CAN_BAUD_500K;
315 case 500000:
return CAN_BAUD_500K;
316 case 250000:
return CAN_BAUD_250K;
317 case 125000:
return CAN_BAUD_125K;
318 case 100000:
return CAN_BAUD_100K;
319 case 50000:
return CAN_BAUD_50K;
320 case 20000:
return CAN_BAUD_20K;
321 case 10000:
return CAN_BAUD_10K;
322 case 5000:
return CAN_BAUD_5K;
331 assert( pimpl->peak_handle !=
NULL );
335 len = int( strlen( ptr ) );
340 Int32 len_cmsgs = len/8 + (((len%8)!=0) ? 1 : 0);
345 for (
int i=0; i < len_cmsgs; i++)
348 cmsg.ID = DWORD(id_write);
349 cmsg.LEN = min( 8, len-i*8 );
350 cmsg.MSGTYPE = MSGTYPE_STANDARD;
351 for ( j=0; j<cmsg.LEN; j++ )
352 cmsg.DATA[ j ] = *(ptr++);
357 #if defined( OSNAME_LINUX ) 358 pimpl->rc = LINUX_CAN_Write_Timeout(pimpl->peak_handle, &cmsg, pimpl->timeout_us );
360 pimpl->rc = CAN_Write( &cmsg );
365 i, (
int)len_cmsgs, m_device, GetLastErrorMessage() ) );
367 DBG( dbg <<
"cCANSerial_PEAK::write wrote CAN frame ID:0x" << std::hex << cmsg.ID <<
" LEN=" <<
int(cmsg.LEN) <<
" DATA (hex):" <<
cHexByteString( (
char const*) cmsg.DATA, cmsg.LEN ) <<
" bytes_written:" << (i*8+cmsg.LEN) <<
"/" << len <<
"\n" );
377 assert( pimpl->peak_handle !=
NULL );
379 char* data = (
char*) _data;
381 #if ! defined( OSNAME_LINUX ) 393 for ( ; pimpl->m_cmsg_next < pimpl->M_CMSG_MSG().LEN && bytes_read <
size; pimpl->m_cmsg_next++, bytes_read++ )
394 *data++ = pimpl->M_CMSG_MSG().DATA[ pimpl->m_cmsg_next ];
397 if ( bytes_read < size )
402 pimpl->M_CMSG_MSG().LEN = 0;
403 pimpl->m_cmsg_next = 0;
404 #if defined( OSNAME_LINUX ) 406 if ( r_timeout_us == 0 )
409 if ( return_on_less_data )
412 pimpl->rc = LINUX_CAN_Read_Timeout( pimpl->peak_handle, &(pimpl->m_cmsg), 0 );
417 pimpl->rc = LINUX_CAN_Read_Timeout( pimpl->peak_handle, &(pimpl->m_cmsg), -1 );
423 pimpl->rc = LINUX_CAN_Read_Timeout( pimpl->peak_handle, &(pimpl->m_cmsg), r_timeout_us );
426 pimpl->rc = CAN_Read( &(pimpl->m_cmsg) );
435 if (pimpl->rc==0xFFFFFFFF)
445 pimpl->M_CMSG_MSG().LEN = 0;
448 if ( pimpl->rc == CAN_ERR_QRCVEMPTY )
451 #if ! defined( OSNAME_LINUX ) 452 if ( return_on_less_data && bytes_read > 0 )
458 if ( r_timeout_us == 0 || start_time.
Elapsed_us() < r_timeout_us)
465 m_device, GetLastErrorMessage() ) );
469 if ( pimpl->M_CMSG_MSG().MSGTYPE != MSGTYPE_STANDARD )
471 pimpl->M_CMSG_MSG().LEN = 0;
472 if ( pimpl->M_CMSG_MSG().MSGTYPE == MSGTYPE_EXTENDED || pimpl->M_CMSG_MSG().MSGTYPE == MSGTYPE_RTR )
474 cerr <<
"Ignoring invalid CAN message of type " << pimpl->M_CMSG_MSG().MSGTYPE <<
"\n"; cerr.flush();
479 pimpl->rc = (DWORD(pimpl->M_CMSG_MSG().DATA[0])<<24) | (DWORD(pimpl->M_CMSG_MSG().DATA[1])<<16) | (DWORD(pimpl->M_CMSG_MSG().DATA[2])<<8) | DWORD(pimpl->M_CMSG_MSG().DATA[3]);
481 m_device, GetLastErrorMessage() ) );
485 if ( pimpl->M_CMSG_MSG().ID != DWORD(id_read) )
487 pimpl->M_CMSG_MSG().LEN = 0;
489 (
unsigned int) pimpl->M_CMSG_MSG().ID, (
unsigned int) id_read ) );
493 for ( ; pimpl->m_cmsg_next < pimpl->M_CMSG_MSG().LEN && bytes_read <
size; pimpl->m_cmsg_next++, bytes_read++ )
494 *data++ = pimpl->M_CMSG_MSG().DATA[ pimpl->m_cmsg_next ];
496 DBG( dbg <<
"cCANSerial_PEAK::Read read CAN frame ID:0x" << std::hex << pimpl->M_CMSG_MSG().ID <<
" LEN=" << int(pimpl->M_CMSG_MSG().LEN) <<
" DATA (hex):" <<
cHexByteString( (
char const*) pimpl->M_CMSG_MSG().DATA, pimpl->M_CMSG_MSG().LEN ) <<
" bytes_read:" << bytes_read <<
"/" << size <<
"\n" );
499 }
while ( bytes_read < size && !return_on_less_data );
510 #if defined( OSNAME_LINUX ) 511 pimpl->timeout_us = int( _timeout * 1E6 );
519 static char return_msg[512];
521 snprintf( return_msg, 511,
"error 0x%x = %d = \"%s\"", (
int) dw, (
int) dw,
PEAK_strerror( (DWORD) pimpl->rc ) );
virtual char const * GetErrorMessage(tErrorCode dw)
Interface of auxilliary utility functions for SDHLibrary-CPP.
Interface of class #SDH::cCANSerial_PEAK, class to access CAN bus via PEAK card on cygwin/linux...
dummy class for (debug) stream output of bytes as list of hex values
PCAN_HANDLE peak_handle
the internal handle to the driver
virtual void SetTimeout(double _timeout)
set the timeout for next readline() calls (negative value means: no timeout, wait for ever) ...
int tErrorCode
type of the error code, DWORD on windows and int on Linux/cygwin
Derived exception class for low-level CAN PEAK related exceptions.
int write(char const *ptr, int len=0)
Write data to a previously opened port.
#define NAMESPACE_SDH_START
~cCANSerial_PEAK()
destructor: clean up
Interface of auxilliary utility functions for SDHLibrary-CPP.
int BaudrateToBaudrateCode(unsigned long baudrate)
Translate a baudrate given as unsigned long into a baudrate code for struct termios.
virtual tErrorCode GetErrorNumber()
ssize_t Read(void *data, ssize_t size, long timeout_us, bool return_on_less_data)
bool IsOpen(void)
Return true if interface to CAN PEAK is open.
#define USING_NAMESPACE_SDH
void SetTimeout(double _timeout)
set the timeout for next readline() calls (negative value means: no timeout, wait for ever) ...
cCANSerial_PEAK(cCANSerial_PEAK const &other)
private copy constructor without implementation, since copying of cCANSerial_PEAK objects makes no se...
char const * PEAK_strerror(DWORD rc)
#define NAMESPACE_SDH_END
This file contains settings to make the SDHLibrary compile on differen systems:
DWORD rc
last return code of calls to Peak functions
Very simple class to measure elapsed time.
void Close(void)
Close the previously opened CAN PEAK interface port.
Class for short, fixed maximum length text messages.
void * PCAN_HANDLE
Linux libpcan uses HANDLE where Windows Pcan_usb.h uses no handle at all:
#define DEFINE_TO_CASECOMMAND(_c)
long Elapsed_us(void) const
Return time in micro seconds elapsed between the time stored in the object and now.
internal hardware specific implementation details of the lowlevel PEAK CAN interface ...
tDeviceHandle GetHandle()
int32_t Int32
signed integer, size 4 Byte (32 Bit)
NAMESPACE_SDH_START typedef void * tDeviceHandle
generic device handle for CAN devices