|
1 /****************************************************************************** |
|
2 * |
|
3 * $Id$ |
|
4 * |
|
5 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH |
|
6 * |
|
7 * This file is part of the IgH EtherCAT Master. |
|
8 * |
|
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or |
|
10 * modify it under the terms of the GNU General Public License version 2, as |
|
11 * published by the Free Software Foundation. |
|
12 * |
|
13 * The IgH EtherCAT Master is distributed in the hope that it will be useful, |
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
|
16 * Public License for more details. |
|
17 * |
|
18 * You should have received a copy of the GNU General Public License along |
|
19 * with the IgH EtherCAT Master; if not, write to the Free Software |
|
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
21 * |
|
22 * --- |
|
23 * |
|
24 * The license mentioned above concerns the source code only. Using the |
|
25 * EtherCAT technology and brand is only permitted in compliance with the |
|
26 * industrial property and similar rights of Beckhoff Automation GmbH. |
|
27 * |
|
28 *****************************************************************************/ |
|
29 |
|
30 /** \file |
|
31 * Sercos-over-EtherCAT request functions. |
|
32 */ |
|
33 |
|
34 /*****************************************************************************/ |
|
35 |
|
36 #include <linux/module.h> |
|
37 #include <linux/jiffies.h> |
|
38 |
|
39 #include "soe_request.h" |
|
40 |
|
41 /*****************************************************************************/ |
|
42 |
|
43 /** Default timeout in ms to wait for SoE responses. |
|
44 */ |
|
45 #define EC_SOE_REQUEST_RESPONSE_TIMEOUT 1000 |
|
46 |
|
47 /*****************************************************************************/ |
|
48 |
|
49 void ec_soe_request_clear_data(ec_soe_request_t *); |
|
50 |
|
51 /*****************************************************************************/ |
|
52 |
|
53 /** SoE request constructor. |
|
54 */ |
|
55 void ec_soe_request_init( |
|
56 ec_soe_request_t *req /**< SoE request. */ |
|
57 ) |
|
58 { |
|
59 req->data = NULL; |
|
60 req->mem_size = 0; |
|
61 req->data_size = 0; |
|
62 req->dir = EC_DIR_INVALID; |
|
63 req->state = EC_INT_REQUEST_INIT; |
|
64 //req->jiffies_start = 0U; |
|
65 req->jiffies_sent = 0U; |
|
66 req->error_code = 0x0000; |
|
67 } |
|
68 |
|
69 /*****************************************************************************/ |
|
70 |
|
71 /** SoE request destructor. |
|
72 */ |
|
73 void ec_soe_request_clear( |
|
74 ec_soe_request_t *req /**< SoE request. */ |
|
75 ) |
|
76 { |
|
77 ec_soe_request_clear_data(req); |
|
78 } |
|
79 |
|
80 /*****************************************************************************/ |
|
81 |
|
82 /** Set IDN. |
|
83 */ |
|
84 void ec_soe_request_set_idn( |
|
85 ec_soe_request_t *req, /**< SoE request. */ |
|
86 uint16_t idn /** IDN. */ |
|
87 ) |
|
88 { |
|
89 req->idn = idn; |
|
90 } |
|
91 |
|
92 #if 0 |
|
93 /*****************************************************************************/ |
|
94 |
|
95 /** Copy another SoE request. |
|
96 * |
|
97 * \attention Only the index subindex and data are copied. |
|
98 */ |
|
99 int ec_soe_request_copy( |
|
100 ec_soe_request_t *req, /**< SoE request. */ |
|
101 const ec_soe_request_t *other /**< Other SoE request to copy from. */ |
|
102 ) |
|
103 { |
|
104 req->complete_access = other->complete_access; |
|
105 req->index = other->index; |
|
106 req->subindex = other->subindex; |
|
107 return ec_soe_request_copy_data(req, other->data, other->data_size); |
|
108 } |
|
109 #endif |
|
110 |
|
111 /*****************************************************************************/ |
|
112 |
|
113 /** Free allocated memory. |
|
114 */ |
|
115 void ec_soe_request_clear_data( |
|
116 ec_soe_request_t *req /**< SoE request. */ |
|
117 ) |
|
118 { |
|
119 if (req->data) { |
|
120 kfree(req->data); |
|
121 req->data = NULL; |
|
122 } |
|
123 |
|
124 req->mem_size = 0; |
|
125 req->data_size = 0; |
|
126 } |
|
127 |
|
128 /*****************************************************************************/ |
|
129 |
|
130 /** Pre-allocates the data memory. |
|
131 * |
|
132 * If the \a mem_size is already bigger than \a size, nothing is done. |
|
133 * |
|
134 * \return 0 on success, otherwise -ENOMEM. |
|
135 */ |
|
136 int ec_soe_request_alloc( |
|
137 ec_soe_request_t *req, /**< SoE request. */ |
|
138 size_t size /**< Data size to allocate. */ |
|
139 ) |
|
140 { |
|
141 if (size <= req->mem_size) |
|
142 return 0; |
|
143 |
|
144 ec_soe_request_clear_data(req); |
|
145 |
|
146 if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) { |
|
147 EC_ERR("Failed to allocate %zu bytes of SoE memory.\n", size); |
|
148 return -ENOMEM; |
|
149 } |
|
150 |
|
151 req->mem_size = size; |
|
152 req->data_size = 0; |
|
153 return 0; |
|
154 } |
|
155 |
|
156 /*****************************************************************************/ |
|
157 |
|
158 /** Copies SoE data from an external source. |
|
159 * |
|
160 * If the \a mem_size is to small, new memory is allocated. |
|
161 * |
|
162 * \retval 0 Success. |
|
163 * \retval <0 Error code. |
|
164 */ |
|
165 int ec_soe_request_copy_data( |
|
166 ec_soe_request_t *req, /**< SoE request. */ |
|
167 const uint8_t *source, /**< Source data. */ |
|
168 size_t size /**< Number of bytes in \a source. */ |
|
169 ) |
|
170 { |
|
171 int ret = ec_soe_request_alloc(req, size); |
|
172 if (ret < 0) |
|
173 return ret; |
|
174 |
|
175 memcpy(req->data, source, size); |
|
176 req->data_size = size; |
|
177 return 0; |
|
178 } |
|
179 |
|
180 /*****************************************************************************/ |
|
181 |
|
182 void ec_soe_request_read(ec_soe_request_t *req) |
|
183 { |
|
184 req->dir = EC_DIR_INPUT; |
|
185 req->state = EC_INT_REQUEST_QUEUED; |
|
186 req->error_code = 0x0000; |
|
187 } |
|
188 |
|
189 /*****************************************************************************/ |
|
190 |
|
191 void ec_soe_request_write(ec_soe_request_t *req) |
|
192 { |
|
193 req->dir = EC_DIR_OUTPUT; |
|
194 req->state = EC_INT_REQUEST_QUEUED; |
|
195 req->error_code = 0x0000; |
|
196 } |
|
197 |
|
198 /*****************************************************************************/ |