Ignore:
Timestamp:
01/16/08 14:07:42 (17 years ago)
Author:
tbretz
Message:
*** empty log message ***
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Cosy/candrv/canopen.cc

    r2518 r8813  
    1818!   Author(s): Thomas Bretz <mailto:tbretz@astro.uni-wuerzburg.de>, 2003
    1919!
    20 !   Copyright: MAGIC Software Development, 2000-2003
     20!   Copyright: MAGIC Software Development, 2000-2008
    2121!
    2222!
     
    3232#include "canopen.h"
    3333
    34 #include <iostream> // cout
    35 #include <iomanip>  // setw, setfill
     34#include "MLog.h"
     35#include "MLogManip.h"
     36
     37#include "interface.h"
    3638
    3739ClassImp(CanOpen);
     
    4446// PDO combinations
    4547//
    46 CanOpen::CanOpen(const char *dev, const int baud, MLog &out) : VmodIcan(dev, baud, out)
    47 {
    48     lout << "- CanOpen initialized." << endl;
     48CanOpen::CanOpen() : fInterface(0)
     49{
     50    gLog << inf << "- CanOpen initialized." << endl;
    4951}
    5052
     
    5557CanOpen::~CanOpen()
    5658{
    57     lout << "- CanOpen destroyed." << endl;
    58 }
    59 
    60 // --------------------------------------------------------------------------
    61 //
    62 // This overloads VmodIcan::HandleCanMessage. It is called if a can
     59    gLog << inf << "- CanOpen destroyed." << endl;
     60}
     61
     62// --------------------------------------------------------------------------
     63//
     64// Start the interface
     65//
     66void CanOpen::Start()
     67{
     68    if (fInterface)
     69        fInterface->Start();
     70}
     71
     72// --------------------------------------------------------------------------
     73//
     74// Stop the interface
     75//
     76void CanOpen::Stop()
     77{
     78    if (fInterface)
     79        fInterface->Stop();
     80}
     81
     82// --------------------------------------------------------------------------
     83//
     84// This overloads Interface::HandleCanMessage. It is called if a can
    6385// message was received with all message relevant data (COBId, data, time)
    6486// It distributes the data depending on its function code to several
     
    6991//  HandlePDO1/2/3/4:handles received PDOs
    7092//
    71 void CanOpen::HandleCanMessage(WORD_t cobid, BYTE_t *data, timeval_t *tv)
     93void CanOpen::HandleCanMessage(WORD_t cobid, const BYTE_t *data, const timeval_t &tv)
    7294{
    7395    const WORD_t fcode = cobid >> 7;
     
    105127            const WORD_t  subidx = data[3];
    106128
     129            cout << "SND NODE: " << (int)node << " " << flush;
    107130            HandleSDO(node, cmd, idx, subidx, dat, tv);
    108131
     
    145168// --------------------------------------------------------------------------
    146169//
     170// Does a basic message processing and hadles the so called command (cmd)
     171// stamp of the message. This is some kind of message type which is send
     172// by the can interface
     173//
     174void CanOpen::HandleMessage(const Message &msg, const timeval_t &tv)
     175{
     176    //
     177    // Decode message
     178    //
     179    const WORD_t desc  = msg.data[2]<<8 | msg.data[3];
     180    const BYTE_t rtr   = (desc>>4)&1;
     181    const BYTE_t len   = desc&0xf;
     182    const WORD_t cobid = desc>>5;
     183
     184    switch (msg.cmd) // FROM mican.h
     185    {
     186    case M_MSG_LOST:
     187        cout << "Interface reports: " << dec << (int)msg.data[0] << " msg(s) lost!" << endl;
     188        return;
     189
     190    case M_BCAN_TX_con:  /* confirm (+/-) transmission */
     191        cout << "Interface reports: CTXcon=0x35" << endl;
     192        cout << "This normally means, that the transmission of the following CAN frame failed:" << hex << endl;
     193        cout << "Descr: 0x" << cobid << dec;
     194        cout << "  Rtr: "   << (rtr?"Yes":"No");
     195        cout << "  Len: "   << (int)len << endl;
     196        return;
     197
     198    case M_BCAN_EVENT_ind:
     199        cout << "Interface reports: CEVTind=0x37: " << hex;
     200        switch (msg.data[0]) // error indicator
     201        {
     202        case 0x01:
     203            cout << "Error interrup occured" << endl;
     204            cout << "This means noisy network normally. Please check the bus termination." << endl;
     205            switch (msg.data[1]) // msg type (board depending)
     206            {
     207            case 2: // SJA1000
     208                cout << dec;
     209                cout << "ModeReg=" << (int)msg.data[2] << ", ";
     210                cout << "StatReg=" << (int)msg.data[3] << ", ";
     211                cout << "RxErrCnt=" << (int)msg.data[4] << ", ";
     212                cout << "TxErrCnt=" << (int)msg.data[5] << endl;
     213            }
     214            //FIXME? TerminateApp();
     215            return;
     216        case 0x02:
     217            cout << "Overrun interrup occured" << endl;
     218            return;
     219        case 0x04:
     220            cout << "Interrupts lost" << endl;
     221            return;
     222        case 0x08:
     223            cout << "Send queue full" << endl;
     224            return;
     225        case 0x10:
     226            cout << "CANbus bus-error" << endl;
     227            return;
     228        }
     229        return;
     230    case M_BCAN_RX_ind:
     231        //
     232        // Message is a message from the Can bus
     233        //
     234        //cout << "HandleCanMessage " << cobid << endl;
     235        HandleCanMessage(cobid, &msg.data[4], tv);
     236        return;
     237    }
     238
     239    //
     240    // Nothing of the above happened
     241    //
     242    cout << hex;
     243    cout << "Cmd=0x"    << (int)msg.cmd << ":  ";
     244    cout << "Descr: 0x" << cobid << dec;
     245    cout << "  Rtr: "   << (rtr?"Yes":"No");
     246    cout << "  Len: "   << (int)len << endl;
     247
     248    cout << "As Raw Data:" << hex << setfill('0');
     249    for (int i=0; i<msg.len; i++)
     250        cout << " " << setw(2) << (int)(msg.data[i]) << flush;
     251    cout << endl;
     252}
     253
     254bool CanOpen::WaitForSdos(WORDS_t ms)
     255{
     256    // 0: unlimited
     257    // <0: don't do a real wait.
     258    if (ms<0)
     259    {
     260        fSdoList.DelAll();
     261        return true;
     262    }
     263
     264    MTimeout t(ms);
     265    while (fSdoList.IsPending() &&
     266           !StopWaitingForSDO() &&
     267           !t.HasTimedOut())
     268        usleep(1);
     269
     270    bool rc = true;
     271    if (ms && t.HasTimedOut())
     272    {
     273        cout << "WaitForSdos timed out." << endl;
     274        rc = false;
     275    }
     276    /*
     277     if (StopWaitingForSDO())
     278     {
     279     cout << "WaitForSdos stopped." << endl;
     280     rc = false;
     281     }
     282     */
     283    if ((ms && t.HasTimedOut()) || StopWaitingForSDO())
     284        fSdoList.DelAll();
     285
     286    return rc;
     287}
     288
     289bool CanOpen::WaitForSdo(BYTE_t node, WORD_t idx, BYTE_t subidx, WORDS_t ms)
     290{
     291    // 0: unlimited
     292    // <0: don't do a real wait.
     293
     294    if (ms<0)
     295    {
     296        fSdoList.Del(node, idx, subidx);
     297        return true;
     298    }
     299
     300    MTimeout t(ms);
     301    while (fSdoList.IsPending(node, idx, subidx) &&
     302           !StopWaitingForSDO() &&
     303           !t.HasTimedOut())
     304        usleep(1);
     305
     306    bool rc = true;
     307    if (ms && t.HasTimedOut())
     308    {
     309        cout << "WaitForSdo Node #" << (int)node << " " << idx << "/" << (int)subidx << " timed out." << endl;
     310        rc = false;
     311    }
     312    /*
     313     if (StopWaitingForSDO())
     314     {
     315     cout << "WaitForSdo Node #" << (int)node << " " << idx << "/" << (int)subidx << " stopped." << endl;
     316     rc = false;
     317     }
     318     */
     319    if ((ms && t.HasTimedOut()) || StopWaitingForSDO())
     320        fSdoList.Del(node, idx, subidx);
     321
     322    return rc;
     323}
     324
     325// --------------------------------------------------------------------------
     326//
    147327// Enables can messaged for a given node ID and function code.
    148328//
     
    152332        return;
    153333
    154     EnableCobId(CobId(node, fcode), flag);
     334    if (fInterface)
     335        fInterface->EnableCobId(CobId(node, fcode), flag);
    155336}
    156337
     
    260441//
    261442void CanOpen::SendPDO1(BYTE_t node,
    262               BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
    263               BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0)
     443              BYTE_t m0, BYTE_t m1, BYTE_t m2, BYTE_t m3,
     444              BYTE_t m4, BYTE_t m5, BYTE_t m6, BYTE_t m7)
    264445{
    265446    BYTE_t msg[8] = { m0, m1, m2, m3, m4, m5, m6, m7 };
     
    272453//
    273454void CanOpen::SendPDO2(BYTE_t node,
    274               BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
    275               BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0)
     455              BYTE_t m0, BYTE_t m1, BYTE_t m2, BYTE_t m3,
     456              BYTE_t m4, BYTE_t m5, BYTE_t m6, BYTE_t m7)
    276457{
    277458    BYTE_t msg[8] = { m0, m1, m2, m3, m4, m5, m6, m7 };
     
    284465//
    285466void CanOpen::SendPDO3(BYTE_t node,
    286               BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
    287               BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0)
     467              BYTE_t m0, BYTE_t m1, BYTE_t m2, BYTE_t m3,
     468              BYTE_t m4, BYTE_t m5, BYTE_t m6, BYTE_t m7)
    288469{
    289470    BYTE_t msg[8] = { m0, m1, m2, m3, m4, m5, m6, m7 };
     
    296477//
    297478void CanOpen::SendPDO4(BYTE_t node,
    298               BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
    299               BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0)
     479              BYTE_t m0, BYTE_t m1, BYTE_t m2, BYTE_t m3,
     480              BYTE_t m4, BYTE_t m5, BYTE_t m6, BYTE_t m7)
    300481{
    301482    BYTE_t msg[8] = { m0, m1, m2, m3, m4, m5, m6, m7 };
     
    394575// --------------------------------------------------------------------------
    395576//
     577// This is IcSendReqBCAN from the Janz software
     578//
     579//  /*
     580//   * IcSendReqBCAN - Send a CANbus message
     581//   *
     582//   * Issue request to send a CAN message. <Spec> controls whether to send with
     583//   * or without spec/confirmation.
     584//   * .CS
     585//   *    spec     action
     586//   *      0      send only
     587//   *      1      send with confirmation to the host.
     588//   *      2      send and echo message to the host.
     589//   *      3      send and generate both echo and confirmation.
     590//   * .CE
     591//   *
     592//   * SERVICE: CTXreq, CTXCreq, CTXEreq, CTXCEreq
     593//   *
     594//   * NOTE:
     595//   * Raw ICANOS version of the firmware only.
     596//   */
     597//
     598void CanOpen::SendCanFrame(WORD_t cobid, BYTE_t m[8], BYTE_t rtr)
     599{
     600    if (fInterface)
     601        fInterface->SendCanFrame(cobid, m, rtr);
     602}
     603
     604// --------------------------------------------------------------------------
     605//
     606// Sends a can frame with the given cobid and the given eight bytes
     607// through the can network
     608//
     609void CanOpen::SendCanFrame(WORD_t cobid,
     610                           BYTE_t m0, BYTE_t m1, BYTE_t m2, BYTE_t m3,
     611                           BYTE_t m4, BYTE_t m5, BYTE_t m6, BYTE_t m7)
     612{
     613    BYTE_t msg[8] = { m0, m1, m2, m3, m4, m5, m6, m7 };
     614    SendCanFrame(cobid, msg);
     615}
     616
     617// --------------------------------------------------------------------------
     618//
    396619// Decodes node and function code into a CobId
    397620//
Note: See TracChangeset for help on using the changeset viewer.