source: trunk/MagicSoft/Cosy/candrv/canopen.h@ 9488

Last change on this file since 9488 was 9439, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 7.3 KB
Line 
1#ifndef COSY_CanOpen
2#define COSY_CanOpen
3
4#ifndef ROOT_TCondition
5#include <TCondition.h>
6#endif
7
8#ifdef __CINT__
9typedef Byte_t BYTE_t;
10typedef UShort_t WORD_t;
11typedef Short_t WORDS_t;
12typedef UInt_t LWORD_t;
13typedef Int_t LWORDS_t;
14struct Message;
15struct FastMessage;
16#else
17#include "gendef.h"
18#include "dpm.h"
19#endif
20
21#ifndef COSY_SdoList
22#include "sdolist.h"
23#endif
24
25#ifndef COSY_MTimeout
26#include "MTimeout.h"
27#endif
28
29//#define FALSE 0
30//#define TRUE 1
31
32// CAL Function Codes
33// COB-ID = function code | node-id (5bits)
34#define kNMT 0x0 // only with COB-ID 0
35#define kSYNC 0x1 // only with COB-ID 0
36#define kTIMESTAMP 0x2 // only with COB-ID 0
37
38#define kEMERGENCY 0x1
39#define kPDO1_TX 0x3
40#define kPDO2_TX 0x5
41#define kPDO3_TX 0x7
42#define kPDO4_TX 0x9
43#define kSDO_RX 0xb // this is used to set data of the shaft encoder
44#define kSDO_TX 0xc // this is used to request data from the shaft encoder
45#define kNodeguard 0xe
46
47// NMT: no answer to NMT command
48// cob-id=0, command (byte), id (byte)
49#define kNMT_START 0x01 // change to operational state (start)
50#define kNMT_STOP 0x02 // change to prepared state (stop)
51#define kNMT_PREOP 0x80 // enter pre operational state
52#define kNMT_RESET 0x81 // reset node (set parameter to power on values)
53#define kNMT_REINIT 0x82 // reset communication of node (set communication parameters to power on values)
54
55// command for SDOs
56#define kSDO_LEN4 0x3
57#define kSDO_LEN2 0xb
58#define kSDO_LEN1 0xf
59
60#define kSDO_RXm4 0x22 // this is used with SDO_TX to send a maximum of 4 bytes
61#define kSDO_RX4 0x20|kSDO_LEN4 // this is used with SDO_TX to send 4 bytes
62#define kSDO_RX2 0x20|kSDO_LEN2 // this is used with SDO_TX to send 2 bytes
63#define kSDO_RX1 0x20|kSDO_LEN1 // this is used with SDO_TX to send 1 byte
64#define kSDO_RX_DATA 0x40 // this is used to request parameters from the encoder
65#define kSDO_TX4 0x40|kSDO_LEN4 // answer to 0x40 with 4 bytes of data
66#define kSDO_TX3 0x40|kSDO_LEN2 // answer to 0x40 with 2 bytes of data
67#define kSDO_TX1 0x40|kSDO_LEN1 // answer to 0x40 with 1 byte of data
68#define kSDO_TX_OK 0x60 // answer to a SDO_TX message
69#define kSDO_TX_ERROR 0x80 // error message (instead of 0x60)
70
71#define kWaitUnlimited 0
72#define kDontWait (-1)
73
74class Interface;
75
76typedef struct timeval timeval_t;
77
78class CanOpen
79{
80private:
81 Interface *fInterface; // Handle to the I/O interface
82 PendingSDOList fSdoList; // List for pending SDOs
83 TCondition fPdoCond[32][4]; // one for every PDO of every node
84
85protected:
86 virtual void Start(); // Start CanOpen communication
87 virtual void Stop(); // Stop CanOpen communcation
88
89 virtual bool HasError() const;
90
91private:
92 //
93 // Handle can objects arrived at the CanOpen interface
94 //
95 virtual void HandleSDO(BYTE_t node, BYTE_t cmd, WORD_t idx, BYTE_t subidx, LWORD_t data, const timeval_t &tv)=0;
96 virtual void HandlePDO1(BYTE_t node, const BYTE_t *data, const timeval_t &tv)=0;
97 virtual void HandlePDO2(BYTE_t node, const BYTE_t *data, const timeval_t &tv)=0;
98 virtual void HandlePDO3(BYTE_t node, const BYTE_t *data, const timeval_t &tv)=0;
99 virtual void HandlePDO4(BYTE_t node, const BYTE_t *data, const timeval_t &tv)=0;
100 virtual void HandleNodeguard(BYTE_t node, const timeval_t &tv)=0;
101 virtual void HandleEmergency(BYTE_t node, const timeval_t &tv)=0;
102
103 // Handle message arrived at the CanOpen interface and split into can objects
104 virtual void HandleCanMessage(WORD_t cobid, const BYTE_t *data, const timeval_t &tv);
105
106public:
107 CanOpen();
108 virtual ~CanOpen();
109
110 void SetInterface(Interface *f) { fInterface=f; } // Set Handle to the interface
111 Bool_t HasConnection() const;
112
113 // Send a Process Data Object (PDO) to the CanOpen bus
114 void SendPDO1(BYTE_t node, BYTE_t data[8]);
115 void SendPDO2(BYTE_t node, BYTE_t data[8]);
116 void SendPDO3(BYTE_t node, BYTE_t data[8]);
117 void SendPDO4(BYTE_t node, BYTE_t data[8]);
118 void SendPDO1(BYTE_t node,
119 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
120 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
121 void SendPDO2(BYTE_t node,
122 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
123 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
124 void SendPDO3(BYTE_t node,
125 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
126 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
127 void SendPDO4(BYTE_t node,
128 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
129 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
130
131 // Send a Service Data Object (SDO) to a CanOpen device (aka. write parameter)
132 void SendSDO(BYTE_t node, WORD_t idx, BYTE_t subidx, BYTE_t val, bool store);
133 void SendSDO(BYTE_t node, WORD_t idx, BYTE_t subidx, WORD_t val, bool store);
134 void SendSDO(BYTE_t node, WORD_t idx, BYTE_t subidx, LWORD_t val, bool store);
135
136 void SendSDO(BYTE_t node, WORD_t idx, BYTE_t val, bool store) { SendSDO(node, idx, 0, val, store); }
137 void SendSDO(BYTE_t node, WORD_t idx, WORD_t val, bool store) { SendSDO(node, idx, 0, val, store); }
138 void SendSDO(BYTE_t node, WORD_t idx, LWORD_t val, bool store) { SendSDO(node, idx, 0, val, store); }
139
140 // Send other objects
141 void SendNMT(BYTE_t node, BYTE_t cmd);
142 void SendNodeguard(BYTE_t node);
143
144 // Request a Service Data Object (SDO) from a CanOpen device (aka. read parameter)
145 void RequestSDO(BYTE_t node, WORD_t idx, BYTE_t subidx=0);
146
147 // Enable interface for pass-through of a kind of can-object
148 void EnableSdoRx(BYTE_t node);
149 void EnablePdo1Rx(BYTE_t node);
150 void EnablePdo2Rx(BYTE_t node);
151 void EnablePdo3Rx(BYTE_t node);
152 void EnablePdo4Rx(BYTE_t node);
153 void EnableEmcy(BYTE_t node);
154 void EnableNodeguard(BYTE_t node);
155
156 // Enable interface for pass-through of a can-object
157 void EnableCanMsg(BYTE_t node, BYTE_t fcode, int flag=TRUE);
158
159 // Wait until the next Pdo object has arrived
160 void WaitForNextPdo1(BYTE_t node) { node -= 1; fPdoCond[node][0].Wait(); }
161 void WaitForNextPdo2(BYTE_t node) { node -= 1; fPdoCond[node][1].Wait(); }
162 void WaitForNextPdo3(BYTE_t node) { node -= 1; fPdoCond[node][2].Wait(); }
163 void WaitForNextPdo4(BYTE_t node) { node -= 1; fPdoCond[node][3].Wait(); }
164
165 // Wait for arrival of a return to a given Sdo (or all axpected Sdos)
166 bool WaitForSdos(WORDS_t ms=500);
167 bool WaitForSdo(BYTE_t node, WORD_t idx, BYTE_t subidx, WORDS_t ms=500);
168
169 virtual int StopWaitingForSDO() const { return FALSE; }
170
171 // Low level function to send rawcan frames
172 void SendCanFrame(WORD_t cobid, BYTE_t m[8], BYTE_t rtr=0);
173 void SendCanFrame(WORD_t cobid,
174 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
175 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
176
177 // Extract the CanOpen message from the message delivered by the interface
178 void HandleMessage(const Message &msg, const timeval_t &tv);
179
180 // Compile CobId from node and function code
181 WORD_t CobId(BYTE_t node, BYTE_t fcode) const;
182
183 ClassDef(CanOpen, 0) // implementation of the can open layer
184};
185
186#endif
Note: See TracBrowser for help on using the repository browser.