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