23 * the industrial property and similar rights of Beckhoff Automation GmbH. |
23 * the industrial property and similar rights of Beckhoff Automation GmbH. |
24 * |
24 * |
25 *****************************************************************************/ |
25 *****************************************************************************/ |
26 |
26 |
27 /** \file |
27 /** \file |
28 * Canopen-over-EtherCAT Sdo request functions. |
28 * Canopen over EtherCAT SDO request functions. |
29 */ |
29 */ |
30 |
30 |
31 /*****************************************************************************/ |
31 /*****************************************************************************/ |
32 |
32 |
33 #include <linux/module.h> |
33 #include <linux/module.h> |
35 |
35 |
36 #include "sdo_request.h" |
36 #include "sdo_request.h" |
37 |
37 |
38 /*****************************************************************************/ |
38 /*****************************************************************************/ |
39 |
39 |
40 /** Default timeout in ms to wait for Sdo transfer responses. |
40 /** Default timeout in ms to wait for SDO transfer responses. |
41 */ |
41 */ |
42 #define EC_SDO_REQUEST_RESPONSE_TIMEOUT 3000 |
42 #define EC_SDO_REQUEST_RESPONSE_TIMEOUT 3000 |
43 |
43 |
44 /*****************************************************************************/ |
44 /*****************************************************************************/ |
45 |
45 |
57 EC_SDO_REQUEST_ERROR // EC_REQUEST_FAILURE |
57 EC_SDO_REQUEST_ERROR // EC_REQUEST_FAILURE |
58 }; |
58 }; |
59 |
59 |
60 /*****************************************************************************/ |
60 /*****************************************************************************/ |
61 |
61 |
62 /** Sdo request constructor. |
62 /** SDO request constructor. |
63 */ |
63 */ |
64 void ec_sdo_request_init( |
64 void ec_sdo_request_init( |
65 ec_sdo_request_t *req /**< Sdo request. */ |
65 ec_sdo_request_t *req /**< SDO request. */ |
66 ) |
66 ) |
67 { |
67 { |
68 req->data = NULL; |
68 req->data = NULL; |
69 req->mem_size = 0; |
69 req->mem_size = 0; |
70 req->data_size = 0; |
70 req->data_size = 0; |
75 req->abort_code = 0x00000000; |
75 req->abort_code = 0x00000000; |
76 } |
76 } |
77 |
77 |
78 /*****************************************************************************/ |
78 /*****************************************************************************/ |
79 |
79 |
80 /** Sdo request destructor. |
80 /** SDO request destructor. |
81 */ |
81 */ |
82 void ec_sdo_request_clear( |
82 void ec_sdo_request_clear( |
83 ec_sdo_request_t *req /**< Sdo request. */ |
83 ec_sdo_request_t *req /**< SDO request. */ |
84 ) |
84 ) |
85 { |
85 { |
86 ec_sdo_request_clear_data(req); |
86 ec_sdo_request_clear_data(req); |
87 } |
87 } |
88 |
88 |
89 /*****************************************************************************/ |
89 /*****************************************************************************/ |
90 |
90 |
91 /** Copy another Sdo request. |
91 /** Copy another SDO request. |
92 * |
92 * |
93 * \attention Only the index subindex and data are copied. |
93 * \attention Only the index subindex and data are copied. |
94 */ |
94 */ |
95 int ec_sdo_request_copy( |
95 int ec_sdo_request_copy( |
96 ec_sdo_request_t *req, |
96 ec_sdo_request_t *req, |
102 return ec_sdo_request_copy_data(req, other->data, other->data_size); |
102 return ec_sdo_request_copy_data(req, other->data, other->data_size); |
103 } |
103 } |
104 |
104 |
105 /*****************************************************************************/ |
105 /*****************************************************************************/ |
106 |
106 |
107 /** Sdo request destructor. |
107 /** SDO request destructor. |
108 */ |
108 */ |
109 void ec_sdo_request_clear_data( |
109 void ec_sdo_request_clear_data( |
110 ec_sdo_request_t *req /**< Sdo request. */ |
110 ec_sdo_request_t *req /**< SDO request. */ |
111 ) |
111 ) |
112 { |
112 { |
113 if (req->data) { |
113 if (req->data) { |
114 kfree(req->data); |
114 kfree(req->data); |
115 req->data = NULL; |
115 req->data = NULL; |
119 req->data_size = 0; |
119 req->data_size = 0; |
120 } |
120 } |
121 |
121 |
122 /*****************************************************************************/ |
122 /*****************************************************************************/ |
123 |
123 |
124 /** Set the Sdo address. |
124 /** Set the SDO address. |
125 */ |
125 */ |
126 void ec_sdo_request_address( |
126 void ec_sdo_request_address( |
127 ec_sdo_request_t *req, /**< Sdo request. */ |
127 ec_sdo_request_t *req, /**< SDO request. */ |
128 uint16_t index, /**< Sdo index. */ |
128 uint16_t index, /**< SDO index. */ |
129 uint8_t subindex /**< Sdo subindex. */ |
129 uint8_t subindex /**< SDO subindex. */ |
130 ) |
130 ) |
131 { |
131 { |
132 req->index = index; |
132 req->index = index; |
133 req->subindex = subindex; |
133 req->subindex = subindex; |
134 } |
134 } |
138 /** Pre-allocates the data memory. |
138 /** Pre-allocates the data memory. |
139 * |
139 * |
140 * If the \a mem_size is already bigger than \a size, nothing is done. |
140 * If the \a mem_size is already bigger than \a size, nothing is done. |
141 */ |
141 */ |
142 int ec_sdo_request_alloc( |
142 int ec_sdo_request_alloc( |
143 ec_sdo_request_t *req, /**< Sdo request. */ |
143 ec_sdo_request_t *req, /**< SDO request. */ |
144 size_t size /**< Data size to allocate. */ |
144 size_t size /**< Data size to allocate. */ |
145 ) |
145 ) |
146 { |
146 { |
147 if (size <= req->mem_size) |
147 if (size <= req->mem_size) |
148 return 0; |
148 return 0; |
149 |
149 |
150 ec_sdo_request_clear_data(req); |
150 ec_sdo_request_clear_data(req); |
151 |
151 |
152 if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) { |
152 if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) { |
153 EC_ERR("Failed to allocate %u bytes of Sdo memory.\n", size); |
153 EC_ERR("Failed to allocate %u bytes of SDO memory.\n", size); |
154 return -1; |
154 return -1; |
155 } |
155 } |
156 |
156 |
157 req->mem_size = size; |
157 req->mem_size = size; |
158 req->data_size = 0; |
158 req->data_size = 0; |
159 return 0; |
159 return 0; |
160 } |
160 } |
161 |
161 |
162 /*****************************************************************************/ |
162 /*****************************************************************************/ |
163 |
163 |
164 /** Copies Sdo data from an external source. |
164 /** Copies SDO data from an external source. |
165 * |
165 * |
166 * If the \a mem_size is to small, new memory is allocated. |
166 * If the \a mem_size is to small, new memory is allocated. |
167 */ |
167 */ |
168 int ec_sdo_request_copy_data( |
168 int ec_sdo_request_copy_data( |
169 ec_sdo_request_t *req, /**< Sdo request. */ |
169 ec_sdo_request_t *req, /**< SDO request. */ |
170 const uint8_t *source, /**< Source data. */ |
170 const uint8_t *source, /**< Source data. */ |
171 size_t size /**< Number of bytes in \a source. */ |
171 size_t size /**< Number of bytes in \a source. */ |
172 ) |
172 ) |
173 { |
173 { |
174 if (ec_sdo_request_alloc(req, size)) |
174 if (ec_sdo_request_alloc(req, size)) |
183 |
183 |
184 /** Checks, if the timeout was exceeded. |
184 /** Checks, if the timeout was exceeded. |
185 * |
185 * |
186 * \return non-zero if the timeout was exceeded, else zero. |
186 * \return non-zero if the timeout was exceeded, else zero. |
187 */ |
187 */ |
188 int ec_sdo_request_timed_out(const ec_sdo_request_t *req /**< Sdo request. */) |
188 int ec_sdo_request_timed_out(const ec_sdo_request_t *req /**< SDO request. */) |
189 { |
189 { |
190 return req->issue_timeout |
190 return req->issue_timeout |
191 && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000; |
191 && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000; |
192 } |
192 } |
193 |
193 |