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

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