43 #include "master.h" |
43 #include "master.h" |
44 #include "fsm_sii.h" |
44 #include "fsm_sii.h" |
45 |
45 |
46 /*****************************************************************************/ |
46 /*****************************************************************************/ |
47 |
47 |
48 void ec_fsm_sii_start_reading(ec_fsm_sii_t *); |
48 void ec_fsm_sii_state_start_reading(ec_fsm_sii_t *); |
49 void ec_fsm_sii_read_check(ec_fsm_sii_t *); |
49 void ec_fsm_sii_state_read_check(ec_fsm_sii_t *); |
50 void ec_fsm_sii_read_fetch(ec_fsm_sii_t *); |
50 void ec_fsm_sii_state_read_fetch(ec_fsm_sii_t *); |
51 void ec_fsm_sii_start_writing(ec_fsm_sii_t *); |
51 void ec_fsm_sii_state_start_writing(ec_fsm_sii_t *); |
52 void ec_fsm_sii_write_check(ec_fsm_sii_t *); |
52 void ec_fsm_sii_state_write_check(ec_fsm_sii_t *); |
53 void ec_fsm_sii_write_check2(ec_fsm_sii_t *); |
53 void ec_fsm_sii_state_write_check2(ec_fsm_sii_t *); |
54 void ec_fsm_sii_end(ec_fsm_sii_t *); |
54 void ec_fsm_sii_state_end(ec_fsm_sii_t *); |
55 void ec_fsm_sii_error(ec_fsm_sii_t *); |
55 void ec_fsm_sii_state_error(ec_fsm_sii_t *); |
56 |
56 |
57 /*****************************************************************************/ |
57 /*****************************************************************************/ |
58 |
58 |
59 /** |
59 /** |
60 Constructor. |
60 Constructor. |
88 ec_slave_t *slave, /**< slave to read from */ |
88 ec_slave_t *slave, /**< slave to read from */ |
89 uint16_t offset, /**< offset to read from */ |
89 uint16_t offset, /**< offset to read from */ |
90 ec_fsm_sii_addressing_t mode /**< addressing scheme */ |
90 ec_fsm_sii_addressing_t mode /**< addressing scheme */ |
91 ) |
91 ) |
92 { |
92 { |
93 fsm->state = ec_fsm_sii_start_reading; |
93 fsm->state = ec_fsm_sii_state_start_reading; |
94 fsm->slave = slave; |
94 fsm->slave = slave; |
95 fsm->offset = offset; |
95 fsm->offset = offset; |
96 fsm->mode = mode; |
96 fsm->mode = mode; |
97 } |
97 } |
98 |
98 |
107 uint16_t offset, /**< offset to read from */ |
107 uint16_t offset, /**< offset to read from */ |
108 const uint16_t *value, /**< pointer to 2 bytes of data */ |
108 const uint16_t *value, /**< pointer to 2 bytes of data */ |
109 ec_fsm_sii_addressing_t mode /**< addressing scheme */ |
109 ec_fsm_sii_addressing_t mode /**< addressing scheme */ |
110 ) |
110 ) |
111 { |
111 { |
112 fsm->state = ec_fsm_sii_start_writing; |
112 fsm->state = ec_fsm_sii_state_start_writing; |
113 fsm->slave = slave; |
113 fsm->slave = slave; |
114 fsm->offset = offset; |
114 fsm->offset = offset; |
115 fsm->mode = mode; |
115 fsm->mode = mode; |
116 memcpy(fsm->value, value, 2); |
116 memcpy(fsm->value, value, 2); |
117 } |
117 } |
137 \return non-zero if successful. |
137 \return non-zero if successful. |
138 */ |
138 */ |
139 |
139 |
140 int ec_fsm_sii_success(ec_fsm_sii_t *fsm /**< Finite state machine */) |
140 int ec_fsm_sii_success(ec_fsm_sii_t *fsm /**< Finite state machine */) |
141 { |
141 { |
142 return fsm->state == ec_fsm_sii_end; |
142 return fsm->state == ec_fsm_sii_state_end; |
143 } |
143 } |
144 |
144 |
145 /****************************************************************************** |
145 /****************************************************************************** |
146 * SII state machine |
146 * SII state machine |
147 *****************************************************************************/ |
147 *****************************************************************************/ |
149 /** |
149 /** |
150 SII state: START READING. |
150 SII state: START READING. |
151 Starts reading the slave information interface. |
151 Starts reading the slave information interface. |
152 */ |
152 */ |
153 |
153 |
154 void ec_fsm_sii_start_reading(ec_fsm_sii_t *fsm /**< finite state machine */) |
154 void ec_fsm_sii_state_start_reading(ec_fsm_sii_t *fsm /**< finite state machine */) |
155 { |
155 { |
156 ec_datagram_t *datagram = fsm->datagram; |
156 ec_datagram_t *datagram = fsm->datagram; |
157 |
157 |
158 // initiate read operation |
158 // initiate read operation |
159 switch (fsm->mode) { |
159 switch (fsm->mode) { |
167 |
167 |
168 EC_WRITE_U8 (datagram->data, 0x00); // read-only access |
168 EC_WRITE_U8 (datagram->data, 0x00); // read-only access |
169 EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation |
169 EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation |
170 EC_WRITE_U16(datagram->data + 2, fsm->offset); |
170 EC_WRITE_U16(datagram->data + 2, fsm->offset); |
171 fsm->retries = EC_FSM_RETRIES; |
171 fsm->retries = EC_FSM_RETRIES; |
172 fsm->state = ec_fsm_sii_read_check; |
172 fsm->state = ec_fsm_sii_state_read_check; |
173 } |
173 } |
174 |
174 |
175 /*****************************************************************************/ |
175 /*****************************************************************************/ |
176 |
176 |
177 /** |
177 /** |
178 SII state: READ CHECK. |
178 SII state: READ CHECK. |
179 Checks, if the SII-read-datagram has been sent and issues a fetch datagram. |
179 Checks, if the SII-read-datagram has been sent and issues a fetch datagram. |
180 */ |
180 */ |
181 |
181 |
182 void ec_fsm_sii_read_check(ec_fsm_sii_t *fsm /**< finite state machine */) |
182 void ec_fsm_sii_state_read_check(ec_fsm_sii_t *fsm /**< finite state machine */) |
183 { |
183 { |
184 ec_datagram_t *datagram = fsm->datagram; |
184 ec_datagram_t *datagram = fsm->datagram; |
185 |
185 |
186 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
186 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
187 return; |
187 return; |
188 |
188 |
189 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
189 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
190 fsm->state = ec_fsm_sii_error; |
190 fsm->state = ec_fsm_sii_state_error; |
191 EC_ERR("Failed to receive SII read datagram from slave %i" |
191 EC_ERR("Failed to receive SII read datagram from slave %i" |
192 " (datagram state %i).\n", |
192 " (datagram state %i).\n", |
193 fsm->slave->ring_position, datagram->state); |
193 fsm->slave->ring_position, datagram->state); |
194 return; |
194 return; |
195 } |
195 } |
196 |
196 |
197 if (datagram->working_counter != 1) { |
197 if (datagram->working_counter != 1) { |
198 fsm->state = ec_fsm_sii_error; |
198 fsm->state = ec_fsm_sii_state_error; |
199 EC_ERR("Reception of SII read datagram failed on slave %i: ", |
199 EC_ERR("Reception of SII read datagram failed on slave %i: ", |
200 fsm->slave->ring_position); |
200 fsm->slave->ring_position); |
201 ec_datagram_print_wc_error(datagram); |
201 ec_datagram_print_wc_error(datagram); |
202 return; |
202 return; |
203 } |
203 } |
214 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10); |
214 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10); |
215 break; |
215 break; |
216 } |
216 } |
217 |
217 |
218 fsm->retries = EC_FSM_RETRIES; |
218 fsm->retries = EC_FSM_RETRIES; |
219 fsm->state = ec_fsm_sii_read_fetch; |
219 fsm->state = ec_fsm_sii_state_read_fetch; |
220 } |
220 } |
221 |
221 |
222 /*****************************************************************************/ |
222 /*****************************************************************************/ |
223 |
223 |
224 /** |
224 /** |
225 SII state: READ FETCH. |
225 SII state: READ FETCH. |
226 Fetches the result of an SII-read datagram. |
226 Fetches the result of an SII-read datagram. |
227 */ |
227 */ |
228 |
228 |
229 void ec_fsm_sii_read_fetch(ec_fsm_sii_t *fsm /**< finite state machine */) |
229 void ec_fsm_sii_state_read_fetch(ec_fsm_sii_t *fsm /**< finite state machine */) |
230 { |
230 { |
231 ec_datagram_t *datagram = fsm->datagram; |
231 ec_datagram_t *datagram = fsm->datagram; |
232 |
232 |
233 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
233 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
234 return; |
234 return; |
235 |
235 |
236 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
236 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
237 fsm->state = ec_fsm_sii_error; |
237 fsm->state = ec_fsm_sii_state_error; |
238 EC_ERR("Failed to receive SII check/fetch datagram from slave %i" |
238 EC_ERR("Failed to receive SII check/fetch datagram from slave %i" |
239 " (datagram state %i).\n", |
239 " (datagram state %i).\n", |
240 fsm->slave->ring_position, datagram->state); |
240 fsm->slave->ring_position, datagram->state); |
241 return; |
241 return; |
242 } |
242 } |
243 |
243 |
244 if (datagram->working_counter != 1) { |
244 if (datagram->working_counter != 1) { |
245 fsm->state = ec_fsm_sii_error; |
245 fsm->state = ec_fsm_sii_state_error; |
246 EC_ERR("Reception of SII check/fetch datagram failed on slave %i: ", |
246 EC_ERR("Reception of SII check/fetch datagram failed on slave %i: ", |
247 fsm->slave->ring_position); |
247 fsm->slave->ring_position); |
248 ec_datagram_print_wc_error(datagram); |
248 ec_datagram_print_wc_error(datagram); |
249 return; |
249 return; |
250 } |
250 } |
254 // still busy... timeout? |
254 // still busy... timeout? |
255 if (datagram->cycles_received |
255 if (datagram->cycles_received |
256 - fsm->cycles_start >= (cycles_t) 10 * cpu_khz) { |
256 - fsm->cycles_start >= (cycles_t) 10 * cpu_khz) { |
257 if (!fsm->check_once_more) { |
257 if (!fsm->check_once_more) { |
258 EC_ERR("SII: Read timeout.\n"); |
258 EC_ERR("SII: Read timeout.\n"); |
259 fsm->state = ec_fsm_sii_error; |
259 fsm->state = ec_fsm_sii_state_error; |
260 #if 0 |
260 #if 0 |
261 EC_DBG("SII busy: %02X %02X %02X %02X\n", |
261 EC_DBG("SII busy: %02X %02X %02X %02X\n", |
262 EC_READ_U8(datagram->data + 0), |
262 EC_READ_U8(datagram->data + 0), |
263 EC_READ_U8(datagram->data + 1), |
263 EC_READ_U8(datagram->data + 1), |
264 EC_READ_U8(datagram->data + 2), |
264 EC_READ_U8(datagram->data + 2), |
290 EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9)); |
290 EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9)); |
291 #endif |
291 #endif |
292 |
292 |
293 // SII value received. |
293 // SII value received. |
294 memcpy(fsm->value, datagram->data + 6, 4); |
294 memcpy(fsm->value, datagram->data + 6, 4); |
295 fsm->state = ec_fsm_sii_end; |
295 fsm->state = ec_fsm_sii_state_end; |
296 } |
296 } |
297 |
297 |
298 /*****************************************************************************/ |
298 /*****************************************************************************/ |
299 |
299 |
300 /** |
300 /** |
301 SII state: START WRITING. |
301 SII state: START WRITING. |
302 Starts reading the slave information interface. |
302 Starts reading the slave information interface. |
303 */ |
303 */ |
304 |
304 |
305 void ec_fsm_sii_start_writing(ec_fsm_sii_t *fsm /**< finite state machine */) |
305 void ec_fsm_sii_state_start_writing(ec_fsm_sii_t *fsm /**< finite state machine */) |
306 { |
306 { |
307 ec_datagram_t *datagram = fsm->datagram; |
307 ec_datagram_t *datagram = fsm->datagram; |
308 |
308 |
309 // initiate write operation |
309 // initiate write operation |
310 ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 8); |
310 ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 8); |
312 EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation |
312 EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation |
313 EC_WRITE_U32(datagram->data + 2, fsm->offset); |
313 EC_WRITE_U32(datagram->data + 2, fsm->offset); |
314 memcpy(datagram->data + 6, fsm->value, 2); |
314 memcpy(datagram->data + 6, fsm->value, 2); |
315 |
315 |
316 fsm->retries = EC_FSM_RETRIES; |
316 fsm->retries = EC_FSM_RETRIES; |
317 fsm->state = ec_fsm_sii_write_check; |
317 fsm->state = ec_fsm_sii_state_write_check; |
318 } |
318 } |
319 |
319 |
320 /*****************************************************************************/ |
320 /*****************************************************************************/ |
321 |
321 |
322 /** |
322 /** |
323 SII state: WRITE CHECK. |
323 SII state: WRITE CHECK. |
324 */ |
324 */ |
325 |
325 |
326 void ec_fsm_sii_write_check(ec_fsm_sii_t *fsm /**< finite state machine */) |
326 void ec_fsm_sii_state_write_check(ec_fsm_sii_t *fsm /**< finite state machine */) |
327 { |
327 { |
328 ec_datagram_t *datagram = fsm->datagram; |
328 ec_datagram_t *datagram = fsm->datagram; |
329 |
329 |
330 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
330 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
331 return; |
331 return; |
332 |
332 |
333 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
333 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
334 fsm->state = ec_fsm_sii_error; |
334 fsm->state = ec_fsm_sii_state_error; |
335 EC_ERR("Failed to receive SII write datagram for slave %i" |
335 EC_ERR("Failed to receive SII write datagram for slave %i" |
336 " (datagram state %i).\n", |
336 " (datagram state %i).\n", |
337 fsm->slave->ring_position, datagram->state); |
337 fsm->slave->ring_position, datagram->state); |
338 return; |
338 return; |
339 } |
339 } |
340 |
340 |
341 if (datagram->working_counter != 1) { |
341 if (datagram->working_counter != 1) { |
342 fsm->state = ec_fsm_sii_error; |
342 fsm->state = ec_fsm_sii_state_error; |
343 EC_ERR("Reception of SII write datagram failed on slave %i: ", |
343 EC_ERR("Reception of SII write datagram failed on slave %i: ", |
344 fsm->slave->ring_position); |
344 fsm->slave->ring_position); |
345 ec_datagram_print_wc_error(datagram); |
345 ec_datagram_print_wc_error(datagram); |
346 return; |
346 return; |
347 } |
347 } |
350 fsm->check_once_more = 1; |
350 fsm->check_once_more = 1; |
351 |
351 |
352 // issue check/fetch datagram |
352 // issue check/fetch datagram |
353 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2); |
353 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2); |
354 fsm->retries = EC_FSM_RETRIES; |
354 fsm->retries = EC_FSM_RETRIES; |
355 fsm->state = ec_fsm_sii_write_check2; |
355 fsm->state = ec_fsm_sii_state_write_check2; |
356 } |
356 } |
357 |
357 |
358 /*****************************************************************************/ |
358 /*****************************************************************************/ |
359 |
359 |
360 /** |
360 /** |
361 SII state: WRITE CHECK 2. |
361 SII state: WRITE CHECK 2. |
362 */ |
362 */ |
363 |
363 |
364 void ec_fsm_sii_write_check2(ec_fsm_sii_t *fsm /**< finite state machine */) |
364 void ec_fsm_sii_state_write_check2(ec_fsm_sii_t *fsm /**< finite state machine */) |
365 { |
365 { |
366 ec_datagram_t *datagram = fsm->datagram; |
366 ec_datagram_t *datagram = fsm->datagram; |
367 |
367 |
368 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
368 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
369 return; |
369 return; |
370 |
370 |
371 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
371 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
372 fsm->state = ec_fsm_sii_error; |
372 fsm->state = ec_fsm_sii_state_error; |
373 EC_ERR("Failed to receive SII write check datagram from slave %i" |
373 EC_ERR("Failed to receive SII write check datagram from slave %i" |
374 " (datagram state %i).\n", |
374 " (datagram state %i).\n", |
375 fsm->slave->ring_position, datagram->state); |
375 fsm->slave->ring_position, datagram->state); |
376 return; |
376 return; |
377 } |
377 } |
378 |
378 |
379 if (datagram->working_counter != 1) { |
379 if (datagram->working_counter != 1) { |
380 fsm->state = ec_fsm_sii_error; |
380 fsm->state = ec_fsm_sii_state_error; |
381 EC_ERR("Reception of SII write check datagram failed on slave %i: ", |
381 EC_ERR("Reception of SII write check datagram failed on slave %i: ", |
382 fsm->slave->ring_position); |
382 fsm->slave->ring_position); |
383 ec_datagram_print_wc_error(datagram); |
383 ec_datagram_print_wc_error(datagram); |
384 return; |
384 return; |
385 } |
385 } |
388 // still busy... timeout? |
388 // still busy... timeout? |
389 if (datagram->cycles_received |
389 if (datagram->cycles_received |
390 - fsm->cycles_start >= (cycles_t) 10 * cpu_khz) { |
390 - fsm->cycles_start >= (cycles_t) 10 * cpu_khz) { |
391 if (!fsm->check_once_more) { |
391 if (!fsm->check_once_more) { |
392 EC_ERR("SII: Write timeout.\n"); |
392 EC_ERR("SII: Write timeout.\n"); |
393 fsm->state = ec_fsm_sii_error; |
393 fsm->state = ec_fsm_sii_state_error; |
394 return; |
394 return; |
395 } |
395 } |
396 fsm->check_once_more = 0; |
396 fsm->check_once_more = 0; |
397 } |
397 } |
398 |
398 |
401 return; |
401 return; |
402 } |
402 } |
403 |
403 |
404 if (EC_READ_U8(datagram->data + 1) & 0x40) { |
404 if (EC_READ_U8(datagram->data + 1) & 0x40) { |
405 EC_ERR("SII: Write operation failed!\n"); |
405 EC_ERR("SII: Write operation failed!\n"); |
406 fsm->state = ec_fsm_sii_error; |
406 fsm->state = ec_fsm_sii_state_error; |
407 return; |
407 return; |
408 } |
408 } |
409 |
409 |
410 // success |
410 // success |
411 fsm->state = ec_fsm_sii_end; |
411 fsm->state = ec_fsm_sii_state_end; |
412 } |
412 } |
413 |
413 |
414 /*****************************************************************************/ |
414 /*****************************************************************************/ |
415 |
415 |
416 /** |
416 /** |
417 State: ERROR. |
417 State: ERROR. |
418 */ |
418 */ |
419 |
419 |
420 void ec_fsm_sii_error(ec_fsm_sii_t *fsm /**< finite state machine */) |
420 void ec_fsm_sii_state_error(ec_fsm_sii_t *fsm /**< finite state machine */) |
421 { |
421 { |
422 } |
422 } |
423 |
423 |
424 /*****************************************************************************/ |
424 /*****************************************************************************/ |
425 |
425 |
426 /** |
426 /** |
427 State: END. |
427 State: END. |
428 */ |
428 */ |
429 |
429 |
430 void ec_fsm_sii_end(ec_fsm_sii_t *fsm /**< finite state machine */) |
430 void ec_fsm_sii_state_end(ec_fsm_sii_t *fsm /**< finite state machine */) |
431 { |
431 { |
432 } |
432 } |
433 |
433 |
434 /*****************************************************************************/ |
434 /*****************************************************************************/ |