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 |
46 void ec_sdo_request_clear_data(ec_sdo_request_t *); |
46 void ec_sdo_request_clear_data(ec_sdo_request_t *); |
47 |
47 |
48 /*****************************************************************************/ |
48 /*****************************************************************************/ |
49 |
49 |
50 /** Sdo request constructor. |
50 /** SDO request constructor. |
51 */ |
51 */ |
52 void ec_sdo_request_init( |
52 void ec_sdo_request_init( |
53 ec_sdo_request_t *req /**< Sdo request. */ |
53 ec_sdo_request_t *req /**< SDO request. */ |
54 ) |
54 ) |
55 { |
55 { |
56 req->data = NULL; |
56 req->data = NULL; |
57 req->mem_size = 0; |
57 req->mem_size = 0; |
58 req->data_size = 0; |
58 req->data_size = 0; |
63 req->abort_code = 0x00000000; |
63 req->abort_code = 0x00000000; |
64 } |
64 } |
65 |
65 |
66 /*****************************************************************************/ |
66 /*****************************************************************************/ |
67 |
67 |
68 /** Sdo request destructor. |
68 /** SDO request destructor. |
69 */ |
69 */ |
70 void ec_sdo_request_clear( |
70 void ec_sdo_request_clear( |
71 ec_sdo_request_t *req /**< Sdo request. */ |
71 ec_sdo_request_t *req /**< SDO request. */ |
72 ) |
72 ) |
73 { |
73 { |
74 ec_sdo_request_clear_data(req); |
74 ec_sdo_request_clear_data(req); |
75 } |
75 } |
76 |
76 |
77 /*****************************************************************************/ |
77 /*****************************************************************************/ |
78 |
78 |
79 /** Copy another Sdo request. |
79 /** Copy another SDO request. |
80 * |
80 * |
81 * \attention Only the index subindex and data are copied. |
81 * \attention Only the index subindex and data are copied. |
82 */ |
82 */ |
83 int ec_sdo_request_copy( |
83 int ec_sdo_request_copy( |
84 ec_sdo_request_t *req, |
84 ec_sdo_request_t *req, |
90 return ec_sdo_request_copy_data(req, other->data, other->data_size); |
90 return ec_sdo_request_copy_data(req, other->data, other->data_size); |
91 } |
91 } |
92 |
92 |
93 /*****************************************************************************/ |
93 /*****************************************************************************/ |
94 |
94 |
95 /** Sdo request destructor. |
95 /** SDO request destructor. |
96 */ |
96 */ |
97 void ec_sdo_request_clear_data( |
97 void ec_sdo_request_clear_data( |
98 ec_sdo_request_t *req /**< Sdo request. */ |
98 ec_sdo_request_t *req /**< SDO request. */ |
99 ) |
99 ) |
100 { |
100 { |
101 if (req->data) { |
101 if (req->data) { |
102 kfree(req->data); |
102 kfree(req->data); |
103 req->data = NULL; |
103 req->data = NULL; |
107 req->data_size = 0; |
107 req->data_size = 0; |
108 } |
108 } |
109 |
109 |
110 /*****************************************************************************/ |
110 /*****************************************************************************/ |
111 |
111 |
112 /** Set the Sdo address. |
112 /** Set the SDO address. |
113 */ |
113 */ |
114 void ec_sdo_request_address( |
114 void ec_sdo_request_address( |
115 ec_sdo_request_t *req, /**< Sdo request. */ |
115 ec_sdo_request_t *req, /**< SDO request. */ |
116 uint16_t index, /**< Sdo index. */ |
116 uint16_t index, /**< SDO index. */ |
117 uint8_t subindex /**< Sdo subindex. */ |
117 uint8_t subindex /**< SDO subindex. */ |
118 ) |
118 ) |
119 { |
119 { |
120 req->index = index; |
120 req->index = index; |
121 req->subindex = subindex; |
121 req->subindex = subindex; |
122 } |
122 } |
128 * If the \a mem_size is already bigger than \a size, nothing is done. |
128 * If the \a mem_size is already bigger than \a size, nothing is done. |
129 * |
129 * |
130 * \return 0 on success, otherwise -ENOMEM. |
130 * \return 0 on success, otherwise -ENOMEM. |
131 */ |
131 */ |
132 int ec_sdo_request_alloc( |
132 int ec_sdo_request_alloc( |
133 ec_sdo_request_t *req, /**< Sdo request. */ |
133 ec_sdo_request_t *req, /**< SDO request. */ |
134 size_t size /**< Data size to allocate. */ |
134 size_t size /**< Data size to allocate. */ |
135 ) |
135 ) |
136 { |
136 { |
137 if (size <= req->mem_size) |
137 if (size <= req->mem_size) |
138 return 0; |
138 return 0; |
139 |
139 |
140 ec_sdo_request_clear_data(req); |
140 ec_sdo_request_clear_data(req); |
141 |
141 |
142 if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) { |
142 if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) { |
143 EC_ERR("Failed to allocate %u bytes of Sdo memory.\n", size); |
143 EC_ERR("Failed to allocate %u bytes of SDO memory.\n", size); |
144 return -ENOMEM; |
144 return -ENOMEM; |
145 } |
145 } |
146 |
146 |
147 req->mem_size = size; |
147 req->mem_size = size; |
148 req->data_size = 0; |
148 req->data_size = 0; |
149 return 0; |
149 return 0; |
150 } |
150 } |
151 |
151 |
152 /*****************************************************************************/ |
152 /*****************************************************************************/ |
153 |
153 |
154 /** Copies Sdo data from an external source. |
154 /** Copies SDO data from an external source. |
155 * |
155 * |
156 * If the \a mem_size is to small, new memory is allocated. |
156 * If the \a mem_size is to small, new memory is allocated. |
157 * |
157 * |
158 * \retval 0 Success. |
158 * \retval 0 Success. |
159 * \retval <0 Error code. |
159 * \retval <0 Error code. |
160 */ |
160 */ |
161 int ec_sdo_request_copy_data( |
161 int ec_sdo_request_copy_data( |
162 ec_sdo_request_t *req, /**< Sdo request. */ |
162 ec_sdo_request_t *req, /**< SDO request. */ |
163 const uint8_t *source, /**< Source data. */ |
163 const uint8_t *source, /**< Source data. */ |
164 size_t size /**< Number of bytes in \a source. */ |
164 size_t size /**< Number of bytes in \a source. */ |
165 ) |
165 ) |
166 { |
166 { |
167 int ret = ec_sdo_request_alloc(req, size); |
167 int ret = ec_sdo_request_alloc(req, size); |
177 |
177 |
178 /** Checks, if the timeout was exceeded. |
178 /** Checks, if the timeout was exceeded. |
179 * |
179 * |
180 * \return non-zero if the timeout was exceeded, else zero. |
180 * \return non-zero if the timeout was exceeded, else zero. |
181 */ |
181 */ |
182 int ec_sdo_request_timed_out(const ec_sdo_request_t *req /**< Sdo request. */) |
182 int ec_sdo_request_timed_out(const ec_sdo_request_t *req /**< SDO request. */) |
183 { |
183 { |
184 return req->issue_timeout |
184 return req->issue_timeout |
185 && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000; |
185 && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000; |
186 } |
186 } |
187 |
187 |