linuxcan.cpp
Go to the documentation of this file.
00001 /*
00002 * Unpublished Copyright (c) 2009-2017 AutonomouStuff, LLC, All Rights Reserved.
00003 *
00004 * This file is part of the Kvaser ROS 1.0 driver which is released under the MIT license.
00005 * See file LICENSE included with this software or go to https://opensource.org/licenses/MIT for full license details.
00006 */
00007 
00008 #include <kvaser_interface.h>
00009 #include <canlib.h>
00010 
00011 using namespace std;
00012 using namespace AS::CAN;
00013 
00014 //Default constructor.
00015 KvaserCan::KvaserCan() :
00016         handle(NULL)
00017 {
00018   handle = malloc(sizeof(canHandle));
00019 }
00020 
00021 //Default destructor.
00022 KvaserCan::~KvaserCan()
00023 {
00024   if (handle != NULL)
00025   {
00026     close();
00027   }
00028 
00029   free(handle);
00030 }
00031 
00032 return_statuses KvaserCan::open(const int& hardware_id,
00033                                    const int& circuit_id,
00034                                    const int& bitrate,
00035                                    const bool& echo_on)
00036 {
00037   if (handle == NULL)
00038   {
00039     return INIT_FAILED;
00040   }
00041 
00042   if (!on_bus)
00043   {
00044     canHandle *h = (canHandle *) handle;
00045 
00046     int numChan;
00047     if (canGetNumberOfChannels(&numChan) != canOK)
00048     {
00049       return INIT_FAILED;
00050     }
00051 
00052     unsigned int serial[2];
00053     unsigned int channel_number;
00054     int channel = -1;
00055 
00056     for (int idx = 0; idx < numChan; idx++)
00057     {
00058       if (canGetChannelData(idx, canCHANNELDATA_CARD_SERIAL_NO, &serial, sizeof(serial)) == canOK)
00059       {
00060         if (serial[0] == (unsigned int) hardware_id)
00061         {
00062           if (canGetChannelData(idx, canCHANNELDATA_CHAN_NO_ON_CARD, &channel_number, sizeof(channel_number)) == canOK)
00063           {
00064             if (channel_number == (unsigned int) circuit_id)
00065             {
00066               channel = idx;
00067             }
00068           }
00069         }
00070       }
00071     }
00072 
00073     if (channel == -1)
00074     {
00075       return BAD_PARAM;
00076     }
00077 
00078     // Open channel
00079     *h = canOpenChannel(channel, canOPEN_ACCEPT_VIRTUAL);
00080     if (*h < 0)
00081     {
00082       return INIT_FAILED;
00083     }
00084 
00085     // Set bit rate and other parameters
00086     long freq;
00087     switch (bitrate)
00088     {
00089       case 125000: freq = canBITRATE_125K; break;
00090       case 250000: freq = canBITRATE_250K; break;
00091       case 500000: freq = canBITRATE_500K; break;
00092       case 1000000: freq = canBITRATE_1M; break;
00093       default:
00094       {
00095         return  BAD_PARAM;
00096       }
00097     }
00098 
00099     if (canSetBusParams(*h, freq, 0, 0, 0, 0, 0) < 0)
00100     {
00101       return BAD_PARAM;
00102     }
00103 
00104     // Linuxcan defaults to echo on, so if you've opened the same can channel
00105     // from multiple interfaces they will receive the messages that each other
00106     // send.  Turn it off here if desired.
00107     if (!echo_on)
00108     {
00109       unsigned char off = 0;
00110       canIoCtl(*h, canIOCTL_SET_LOCAL_TXECHO, &off, 1);
00111     }
00112 
00113     // Set output control
00114     canSetBusOutputControl(*h, canDRIVER_NORMAL);
00115     canBusOn(*h);
00116     on_bus = true;
00117   }
00118 
00119   return OK;
00120 }
00121 
00122 bool KvaserCan::is_open()
00123 {
00124   if (handle == NULL)
00125   {
00126     return false;
00127   }
00128   else
00129   {
00130     if (on_bus)
00131     {
00132       return true;
00133     }
00134     else
00135     {
00136       return false;
00137     }
00138   }
00139 }
00140 
00141 return_statuses KvaserCan::close()
00142 {
00143   if (handle == NULL)
00144   {
00145     return INIT_FAILED;
00146   }
00147 
00148   canHandle *h = (canHandle *) handle;
00149 
00150   // Close the channel
00151   if (canClose(*h) != canOK)
00152   {
00153     return CLOSE_FAILED;
00154   }
00155 
00156   on_bus = false;
00157 
00158   return OK;
00159 }
00160 
00161 return_statuses KvaserCan::read(long *id,
00162                                    unsigned char *msg,
00163                                    unsigned int *size,
00164                                    bool *extended,
00165                                    unsigned long *time)
00166 {
00167   if (handle == NULL)
00168   {
00169     return INIT_FAILED;
00170   }
00171 
00172   canHandle *h = (canHandle *) handle;
00173 
00174   bool done = false;
00175   return_statuses ret_val = INIT_FAILED;
00176   unsigned int flag = 0;
00177 
00178   while (!done)
00179   {
00180     canStatus ret = canRead(*h, id, msg, size, &flag, time);
00181 
00182     if (ret == canERR_NOTINITIALIZED)
00183     {
00184       ret_val = CHANNEL_CLOSED;
00185       on_bus = false;
00186       done = true;
00187     }
00188     else if (ret == canERR_NOMSG)
00189     {
00190       ret_val = NO_MESSAGES_RECEIVED;
00191       done = true;
00192     }
00193     else if (ret != canOK)
00194     {
00195       ret_val = READ_FAILED;
00196       done = true;
00197     }
00198     else if (!(flag & 0xF9))
00199     {
00200       // Was a received message with actual data
00201       ret_val = OK;
00202       done = true;
00203     }
00204     // Else a protocol message, such as a TX ACK, was received
00205     // Keep looping until one of the other conditions above is met
00206   }
00207 
00208   if (ret_val == OK)
00209   {
00210     *extended = ((flag & canMSG_EXT) > 0);
00211   }
00212 
00213   return ret_val;
00214 }
00215 
00216 return_statuses KvaserCan::write(const long& id,
00217                                     unsigned char *msg,
00218                                     const unsigned int& size,
00219                                     const bool& extended)
00220 {
00221   if (handle == NULL)
00222   {
00223     return INIT_FAILED;
00224   }
00225 
00226   canHandle *h = (canHandle *) handle;
00227 
00228   unsigned int flag;
00229 
00230   if (extended)
00231   {
00232     flag = canMSG_EXT;
00233   }
00234   else
00235   {
00236     flag = canMSG_STD;
00237   }
00238 
00239   canStatus ret = canWrite(*h, id, msg, size, flag);
00240 
00241   return (ret == canOK) ? OK : WRITE_FAILED;
00242 }


kvaser_interface
Author(s): Joshua Whitley , Daniel Stanek
autogenerated on Fri Jun 21 2019 19:31:13