86 # ifndef NTCAN_BAUD_1000
89 # define NTCAN_BAUD_1000 0
90 # define NTCAN_BAUD_800 14
91 # define NTCAN_BAUD_500 2
92 # define NTCAN_BAUD_250 4
93 # define NTCAN_BAUD_125 6
94 # define NTCAN_BAUD_100 7
95 # define NTCAN_BAUD_50 9
96 # define NTCAN_BAUD_20 11
97 # define NTCAN_BAUD_10 13
154 #define SDH_CANSERIAL_ESD_DEBUG 1
160 #if SDH_CANSERIAL_ESD_DEBUG
161 # define DBG( ... ) \
187 if ( _timeout < 0.0 )
191 pimpl->ntcan_handle = NTCAN_HANDLE(NTCAN_INVALID_HANDLE);
193 baudrate = _baudrate;
194 SetTimeout( _timeout );
196 id_write = _id_write;
198 ungetch_valid =
false;
207 if ( _timeout < 0.0 )
210 if ( _ntcan_handle ==
tDeviceHandle(NTCAN_HANDLE(NTCAN_INVALID_HANDLE)) )
214 pimpl->ntcan_handle = *(NTCAN_HANDLE*)(_ntcan_handle);
217 SetTimeout( _timeout );
219 id_write = _id_write;
221 ungetch_valid =
false;
286 if ( pimpl->ntcan_handle == NTCAN_HANDLE(NTCAN_INVALID_HANDLE) )
291 DBG( dbg <<
"Opening ESD CAN net: " << net <<
", baudrate: " << baudrate <<
", id_read: 0x" << std::hex << id_read <<
", id_write: 0x" << id_write << std::dec <<
"\n" );
292 pimpl->rc = canOpen( net,
298 &(pimpl->ntcan_handle) );
300 if (pimpl->rc != NTCAN_SUCCESS)
303 pimpl->ntcan_handle = NTCAN_HANDLE(NTCAN_INVALID_HANDLE);
307 pimpl->rc = canSetBaudrate( pimpl->ntcan_handle, BaudrateToBaudrateCode( baudrate ) );
308 if (pimpl->rc != NTCAN_SUCCESS)
309 throw new cCANSerial_ESDException(
cMsg(
"Could not set baudrate to %lu on ESD CAN net %d: %s", baudrate, net, GetLastErrorMessage() ) );
312 pimpl->rc = canIdAdd( pimpl->ntcan_handle, id_read );
313 if (pimpl->rc != NTCAN_SUCCESS)
314 throw new cCANSerial_ESDException(
cMsg(
"Could not add CAN ID 0x%03x on ESD CAN net %d: %s", (
unsigned int) id_read, net, GetLastErrorMessage() ) );
317 pimpl->m_cmsg.len = 0;
318 pimpl->m_cmsg.msg_lost = 0;
319 pimpl->m_cmsg_next = 0;
327 return ( pimpl->ntcan_handle != NTCAN_HANDLE(NTCAN_INVALID_HANDLE) );
334 if ( pimpl->ntcan_handle == NTCAN_HANDLE(NTCAN_INVALID_HANDLE) )
337 canClose( pimpl->ntcan_handle );
338 pimpl->ntcan_handle = NTCAN_HANDLE(NTCAN_INVALID_HANDLE);
346 case 1000000:
return NTCAN_BAUD_1000;
347 case 800000:
return NTCAN_BAUD_800;
348 case 500000:
return NTCAN_BAUD_500;
349 case 250000:
return NTCAN_BAUD_250;
350 case 125000:
return NTCAN_BAUD_125;
351 case 100000:
return NTCAN_BAUD_100;
352 case 50000:
return NTCAN_BAUD_50;
353 case 20000:
return NTCAN_BAUD_20;
354 case 10000:
return NTCAN_BAUD_10;
363 assert( pimpl->ntcan_handle != NTCAN_HANDLE(NTCAN_INVALID_HANDLE) );
367 len = int( strlen( ptr ) );
372 int len_cmsgs = len/8 + (((len%8)!=0) ? 1 : 0);
381 CMSG* cmsg =
new CMSG[ len_cmsgs ];
383 CMSG cmsg[ len_cmsgs ];
385 for (
int i=0; i < len_cmsgs; i++)
387 cmsg[i].id = id_write;
388 cmsg[i].len = min( 8, len-i*8 );
389 for (
int j=0; j<cmsg[i].len; j++ )
390 cmsg[i].data[ j ] = *(ptr++);
392 DBG( dbg <<
"cCANSerial_ESD::write writing CAN frame id:0x" << std::hex << cmsg[i].
id <<
" len=" <<
int(cmsg[i].len) <<
" DATA (hex):" <<
cHexByteString( (
char const*) cmsg[i].data, cmsg[i].len ) <<
" bytes_written:" << (i*8+cmsg[i].len) <<
"/" << len <<
"\n" );
399 int len_cmsgs_save = len_cmsgs;
400 pimpl->rc = canWrite( pimpl->ntcan_handle, cmsg, (int32_t*) &len_cmsgs,
NULL );
405 if (pimpl->rc != NTCAN_SUCCESS)
406 throw new cCANSerial_ESDException(
cMsg(
"Could not write %d CMSGs on ESD CAN net %d: %s", (
int)len_cmsgs, net, GetLastErrorMessage() ) );
408 if ( len_cmsgs != len_cmsgs_save )
409 throw new cCANSerial_ESDException(
cMsg(
"Could only send %d/%d CMSGs on ESD CAN net %d", (
int)len_cmsgs, (
int)len_cmsgs_save, net ) );
418 assert( pimpl->ntcan_handle != NTCAN_HANDLE(NTCAN_INVALID_HANDLE) );
420 char* data = (
char*) _data;
429 if (
long(pimpl->timeout_ms) * 1000L != timeout_us )
431 SetTimeout(
double(timeout_us) / 1E6 );
442 for ( ; pimpl->m_cmsg_next < pimpl->m_cmsg.len && bytes_read <
size; pimpl->m_cmsg_next++, bytes_read++ )
443 *data++ = pimpl->m_cmsg.data[ pimpl->m_cmsg_next ];
445 if ( bytes_read <
size )
449 pimpl->m_cmsg.len = 0;
450 pimpl->m_cmsg_next = 0;
451 if ( timeout_us == 0 )
452 pimpl->rc = canTake( pimpl->ntcan_handle, &(pimpl->m_cmsg), (int32_t*) &len_cmsgs );
454 pimpl->rc = canRead( pimpl->ntcan_handle, &(pimpl->m_cmsg), (int32_t*) &len_cmsgs,
NULL );
456 if (pimpl->rc != NTCAN_SUCCESS)
459 DBG( dbg <<
"cCANSerial_ESD::Read read CAN frame id:0x" << std::hex << pimpl->m_cmsg.id <<
" len=" <<
int(pimpl->m_cmsg.len) <<
" data (hex):" <<
cHexByteString( (
char const*) pimpl->m_cmsg.data, pimpl->m_cmsg.len ) <<
" bytes_read:" << bytes_read <<
"/" <<
size <<
"\n" );
462 if ( len_cmsgs != 1 && timeout_us != 0 )
464 if ( len_cmsgs > 0 && pimpl->m_cmsg.id != id_read )
465 throw new cCANSerial_ESDException(
cMsg(
"Invalid CAN ID 0x%03x received, expected 0x%03x", (
unsigned int) pimpl->m_cmsg.id, (
unsigned int) id_read ) );
467 for ( ; pimpl->m_cmsg_next < pimpl->m_cmsg.len && bytes_read <
size; pimpl->m_cmsg_next++, bytes_read++ )
468 *data++ = pimpl->m_cmsg.data[ pimpl->m_cmsg_next ];
471 while ( bytes_read <
size && !return_on_less_data );
480 if ( _timeout < 0.0 )
484 pimpl->timeout_ms = int32_t(_timeout * 1000.0);
486 if ( pimpl->ntcan_handle != NTCAN_HANDLE(NTCAN_INVALID_HANDLE) )
491 pimpl->rc = canIoctl( pimpl->ntcan_handle, NTCAN_IOCTL_SET_RX_TIMEOUT, &(pimpl->timeout_ms) );
493 if ( pimpl->rc != NTCAN_SUCCESS )
501 static char return_msg[512];
503 snprintf( return_msg, 511,
"error 0x%x = %d = \"%s\"", dw, dw,
ESD_strerror( (NTCAN_RESULT) dw ) );