00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039
00040
00041 #include "globals.h"
00042 #include "mailbox.h"
00043 #include "master.h"
00044 #include "fsm_sii.h"
00045
00046
00047
00048 void ec_fsm_sii_start_reading(ec_fsm_sii_t *);
00049 void ec_fsm_sii_read_check(ec_fsm_sii_t *);
00050 void ec_fsm_sii_read_fetch(ec_fsm_sii_t *);
00051 void ec_fsm_sii_start_writing(ec_fsm_sii_t *);
00052 void ec_fsm_sii_write_check(ec_fsm_sii_t *);
00053 void ec_fsm_sii_write_check2(ec_fsm_sii_t *);
00054 void ec_fsm_sii_end(ec_fsm_sii_t *);
00055 void ec_fsm_sii_error(ec_fsm_sii_t *);
00056
00057
00058
00063 void ec_fsm_sii_init(ec_fsm_sii_t *fsm,
00064 ec_datagram_t *datagram
00065 )
00066 {
00067 fsm->state = NULL;
00068 fsm->datagram = datagram;
00069 }
00070
00071
00072
00077 void ec_fsm_sii_clear(ec_fsm_sii_t *fsm )
00078 {
00079 }
00080
00081
00082
00087 void ec_fsm_sii_read(ec_fsm_sii_t *fsm,
00088 ec_slave_t *slave,
00089 uint16_t offset,
00090 ec_fsm_sii_addressing_t mode
00091 )
00092 {
00093 fsm->state = ec_fsm_sii_start_reading;
00094 fsm->slave = slave;
00095 fsm->offset = offset;
00096 fsm->mode = mode;
00097 }
00098
00099
00100
00105 void ec_fsm_sii_write(ec_fsm_sii_t *fsm,
00106 ec_slave_t *slave,
00107 uint16_t offset,
00108 uint16_t *value,
00109 ec_fsm_sii_addressing_t mode
00110 )
00111 {
00112 fsm->state = ec_fsm_sii_start_writing;
00113 fsm->slave = slave;
00114 fsm->offset = offset;
00115 fsm->mode = mode;
00116 memcpy(fsm->value, value, 2);
00117 }
00118
00119
00120
00126 int ec_fsm_sii_exec(ec_fsm_sii_t *fsm )
00127 {
00128 fsm->state(fsm);
00129
00130 return fsm->state != ec_fsm_sii_end && fsm->state != ec_fsm_sii_error;
00131 }
00132
00133
00134
00140 int ec_fsm_sii_success(ec_fsm_sii_t *fsm )
00141 {
00142 return fsm->state == ec_fsm_sii_end;
00143 }
00144
00145
00146
00147
00148
00154 void ec_fsm_sii_start_reading(ec_fsm_sii_t *fsm )
00155 {
00156 ec_datagram_t *datagram = fsm->datagram;
00157
00158
00159 switch (fsm->mode) {
00160 case EC_FSM_SII_POSITION:
00161 ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x502, 4);
00162 break;
00163 case EC_FSM_SII_NODE:
00164 ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 4);
00165 break;
00166 }
00167
00168 EC_WRITE_U8 (datagram->data, 0x00);
00169 EC_WRITE_U8 (datagram->data + 1, 0x01);
00170 EC_WRITE_U16(datagram->data + 2, fsm->offset);
00171 ec_master_queue_datagram(fsm->slave->master, datagram);
00172 fsm->state = ec_fsm_sii_read_check;
00173 }
00174
00175
00176
00182 void ec_fsm_sii_read_check(ec_fsm_sii_t *fsm )
00183 {
00184 ec_datagram_t *datagram = fsm->datagram;
00185
00186 if (datagram->state != EC_DATAGRAM_RECEIVED
00187 || datagram->working_counter != 1) {
00188 EC_ERR("SII: Reception of read datagram failed.\n");
00189 fsm->state = ec_fsm_sii_error;
00190 return;
00191 }
00192
00193 fsm->cycles_start = datagram->cycles_sent;
00194 fsm->check_once_more = 1;
00195
00196
00197 switch (fsm->mode) {
00198 case EC_FSM_SII_POSITION:
00199 ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
00200 break;
00201 case EC_FSM_SII_NODE:
00202 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
00203 break;
00204 }
00205 ec_master_queue_datagram(fsm->slave->master, datagram);
00206 fsm->state = ec_fsm_sii_read_fetch;
00207 }
00208
00209
00210
00216 void ec_fsm_sii_read_fetch(ec_fsm_sii_t *fsm )
00217 {
00218 ec_datagram_t *datagram = fsm->datagram;
00219
00220 if (datagram->state != EC_DATAGRAM_RECEIVED
00221 || datagram->working_counter != 1) {
00222 EC_ERR("SII: Reception of check/fetch datagram failed.\n");
00223 fsm->state = ec_fsm_sii_error;
00224 return;
00225 }
00226
00227
00228 if (EC_READ_U8(datagram->data + 1) & 0x81) {
00229
00230 if (datagram->cycles_received
00231 - fsm->cycles_start >= (cycles_t) 10 * cpu_khz) {
00232 if (!fsm->check_once_more) {
00233 EC_ERR("SII: Read timeout.\n");
00234 fsm->state = ec_fsm_sii_error;
00235 #if 0
00236 EC_DBG("SII busy: %02X %02X %02X %02X\n",
00237 EC_READ_U8(datagram->data + 0),
00238 EC_READ_U8(datagram->data + 1),
00239 EC_READ_U8(datagram->data + 2),
00240 EC_READ_U8(datagram->data + 3));
00241 #endif
00242 return;
00243 }
00244 fsm->check_once_more = 0;
00245 }
00246
00247
00248 switch (fsm->mode) {
00249 case EC_FSM_SII_POSITION:
00250 ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
00251 break;
00252 case EC_FSM_SII_NODE:
00253 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
00254 break;
00255 }
00256 ec_master_queue_datagram(fsm->slave->master, datagram);
00257 return;
00258 }
00259
00260 #if 0
00261 EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n",
00262 EC_READ_U8(datagram->data + 0), EC_READ_U8(datagram->data + 1),
00263 EC_READ_U8(datagram->data + 2), EC_READ_U8(datagram->data + 3),
00264 EC_READ_U8(datagram->data + 6), EC_READ_U8(datagram->data + 7),
00265 EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9));
00266 #endif
00267
00268
00269 memcpy(fsm->value, datagram->data + 6, 4);
00270 fsm->state = ec_fsm_sii_end;
00271 }
00272
00273
00274
00280 void ec_fsm_sii_start_writing(ec_fsm_sii_t *fsm )
00281 {
00282 ec_datagram_t *datagram = fsm->datagram;
00283
00284
00285 ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 8);
00286 EC_WRITE_U8 (datagram->data, 0x01);
00287 EC_WRITE_U8 (datagram->data + 1, 0x02);
00288 EC_WRITE_U32(datagram->data + 2, fsm->offset);
00289 memcpy(datagram->data + 6, fsm->value, 2);
00290 ec_master_queue_datagram(fsm->slave->master, datagram);
00291 fsm->state = ec_fsm_sii_write_check;
00292 }
00293
00294
00295
00300 void ec_fsm_sii_write_check(ec_fsm_sii_t *fsm )
00301 {
00302 ec_datagram_t *datagram = fsm->datagram;
00303
00304 if (datagram->state != EC_DATAGRAM_RECEIVED
00305 || datagram->working_counter != 1) {
00306 EC_ERR("SII: Reception of write datagram failed.\n");
00307 fsm->state = ec_fsm_sii_error;
00308 return;
00309 }
00310
00311 fsm->cycles_start = datagram->cycles_sent;
00312 fsm->check_once_more = 1;
00313
00314
00315 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2);
00316 ec_master_queue_datagram(fsm->slave->master, datagram);
00317 fsm->state = ec_fsm_sii_write_check2;
00318 }
00319
00320
00321
00326 void ec_fsm_sii_write_check2(ec_fsm_sii_t *fsm )
00327 {
00328 ec_datagram_t *datagram = fsm->datagram;
00329
00330 if (datagram->state != EC_DATAGRAM_RECEIVED
00331 || datagram->working_counter != 1) {
00332 EC_ERR("SII: Reception of write check datagram failed.\n");
00333 fsm->state = ec_fsm_sii_error;
00334 return;
00335 }
00336
00337 if (EC_READ_U8(datagram->data + 1) & 0x82) {
00338
00339 if (datagram->cycles_received
00340 - fsm->cycles_start >= (cycles_t) 10 * cpu_khz) {
00341 if (!fsm->check_once_more) {
00342 EC_ERR("SII: Write timeout.\n");
00343 fsm->state = ec_fsm_sii_error;
00344 return;
00345 }
00346 fsm->check_once_more = 0;
00347 }
00348
00349
00350 ec_master_queue_datagram(fsm->slave->master, datagram);
00351 return;
00352 }
00353
00354 if (EC_READ_U8(datagram->data + 1) & 0x40) {
00355 EC_ERR("SII: Write operation failed!\n");
00356 fsm->state = ec_fsm_sii_error;
00357 return;
00358 }
00359
00360
00361 fsm->state = ec_fsm_sii_end;
00362 }
00363
00364
00365
00370 void ec_fsm_sii_error(ec_fsm_sii_t *fsm )
00371 {
00372 }
00373
00374
00375
00380 void ec_fsm_sii_end(ec_fsm_sii_t *fsm )
00381 {
00382 }
00383
00384