master/fsm_sii.c
changeset 753 7ba5f9cd8f7e
parent 713 ae41cadd25b6
child 754 0b47b49c5976
equal deleted inserted replaced
752:3d5cd81674bd 753:7ba5f9cd8f7e
    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 }
   125 
   125 
   126 int ec_fsm_sii_exec(ec_fsm_sii_t *fsm /**< finite state machine */)
   126 int ec_fsm_sii_exec(ec_fsm_sii_t *fsm /**< finite state machine */)
   127 {
   127 {
   128     fsm->state(fsm);
   128     fsm->state(fsm);
   129 
   129 
   130     return fsm->state != ec_fsm_sii_end && fsm->state != ec_fsm_sii_error;
   130     return fsm->state != ec_fsm_sii_state_end && fsm->state != ec_fsm_sii_state_error;
   131 }
   131 }
   132 
   132 
   133 /*****************************************************************************/
   133 /*****************************************************************************/
   134 
   134 
   135 /**
   135 /**
   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 /*****************************************************************************/