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

Last change on this file since 9029 was 8864, checked in by tbretz, 17 years ago
*** empty log message ***
File size: 7.1 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
81 virtual bool HasError() const;
82
83private:
84 //
85 // Handle can objects arrived at the CanOpen interface
86 //
87 virtual void HandleSDO(BYTE_t node, BYTE_t cmd, WORD_t idx, BYTE_t subidx, LWORD_t data, const timeval_t &tv)=0;
88 virtual void HandlePDO1(BYTE_t node, const BYTE_t *data, const timeval_t &tv)=0;
89 virtual void HandlePDO2(BYTE_t node, const BYTE_t *data, const timeval_t &tv)=0;
90 virtual void HandlePDO3(BYTE_t node, const BYTE_t *data, const timeval_t &tv)=0;
91 virtual void HandlePDO4(BYTE_t node, const BYTE_t *data, const timeval_t &tv)=0;
92 virtual void HandleNodeguard(BYTE_t node, const timeval_t &tv)=0;
93 virtual void HandleEmergency(BYTE_t node, const timeval_t &tv)=0;
94
95 // Handle message arrived at the CanOpen interface and split into can objects
96 virtual void HandleCanMessage(WORD_t cobid, const BYTE_t *data, const timeval_t &tv);
97
98public:
99 CanOpen();
100 virtual ~CanOpen();
101
102 void SetInterface(Interface *f) { fInterface=f; } // Set Handle to the interface
103
104 // Send a Process Data Object (PDO) to the CanOpen bus
105 void SendPDO1(BYTE_t node, BYTE_t data[8]);
106 void SendPDO2(BYTE_t node, BYTE_t data[8]);
107 void SendPDO3(BYTE_t node, BYTE_t data[8]);
108 void SendPDO4(BYTE_t node, BYTE_t data[8]);
109 void SendPDO1(BYTE_t node,
110 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
111 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
112 void SendPDO2(BYTE_t node,
113 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
114 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
115 void SendPDO3(BYTE_t node,
116 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
117 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
118 void SendPDO4(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
122 // Send a Service Data Object (SDO) to a CanOpen device (aka. write parameter)
123 void SendSDO(BYTE_t node, WORD_t idx, BYTE_t subidx, BYTE_t val, bool store);
124 void SendSDO(BYTE_t node, WORD_t idx, BYTE_t subidx, WORD_t val, bool store);
125 void SendSDO(BYTE_t node, WORD_t idx, BYTE_t subidx, LWORD_t val, bool store);
126
127 void SendSDO(BYTE_t node, WORD_t idx, BYTE_t val, bool store) { SendSDO(node, idx, 0, val, store); }
128 void SendSDO(BYTE_t node, WORD_t idx, WORD_t val, bool store) { SendSDO(node, idx, 0, val, store); }
129 void SendSDO(BYTE_t node, WORD_t idx, LWORD_t val, bool store) { SendSDO(node, idx, 0, val, store); }
130
131 // Send other objects
132 void SendNMT(BYTE_t node, BYTE_t cmd);
133 void SendNodeguard(BYTE_t node);
134
135 // Request a Service Data Object (SDO) from a CanOpen device (aka. read parameter)
136 void RequestSDO(BYTE_t node, WORD_t idx, BYTE_t subidx=0);
137
138 // Enable interface for pass-through of a kind of can-object
139 void EnableSdoRx(BYTE_t node);
140 void EnablePdo1Rx(BYTE_t node);
141 void EnablePdo2Rx(BYTE_t node);
142 void EnablePdo3Rx(BYTE_t node);
143 void EnablePdo4Rx(BYTE_t node);
144 void EnableEmcy(BYTE_t node);
145 void EnableNodeguard(BYTE_t node);
146
147 // Enable interface for pass-through of a can-object
148 void EnableCanMsg(BYTE_t node, BYTE_t fcode, int flag=TRUE);
149
150 // Wait until the next Pdo object has arrived
151 void WaitForNextPdo1(BYTE_t node) { node -= 1; fPdoCond[node][0].Wait(); }
152 void WaitForNextPdo2(BYTE_t node) { node -= 1; fPdoCond[node][1].Wait(); }
153 void WaitForNextPdo3(BYTE_t node) { node -= 1; fPdoCond[node][2].Wait(); }
154 void WaitForNextPdo4(BYTE_t node) { node -= 1; fPdoCond[node][3].Wait(); }
155
156 // Wait for arrival of a return to a given Sdo (or all axpected Sdos)
157 bool WaitForSdos(WORDS_t ms=500);
158 bool WaitForSdo(BYTE_t node, WORD_t idx, BYTE_t subidx, WORDS_t ms=500);
159
160 virtual int StopWaitingForSDO() const { return FALSE; }
161
162 // Low level function to send rawcan frames
163 void SendCanFrame(WORD_t cobid, BYTE_t m[8], BYTE_t rtr=0);
164 void SendCanFrame(WORD_t cobid,
165 BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
166 BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
167
168 // Extract the CanOpen message from the message delivered by the interface
169 void HandleMessage(const Message &msg, const timeval_t &tv);
170
171 // Compile CobId from node and function code
172 WORD_t CobId(BYTE_t node, BYTE_t fcode) const;
173
174 ClassDef(CanOpen, 0) // implementation of the can open layer
175};
176
177#endif
Note: See TracBrowser for help on using the repository browser.