master/fsm_soe.c
changeset 1873 219be3742274
parent 1866 02323e72efc9
child 1877 7b77000f9764
equal deleted inserted replaced
1872:23d4e121faaf 1873:219be3742274
    75 /*****************************************************************************/
    75 /*****************************************************************************/
    76 
    76 
    77 /** Constructor.
    77 /** Constructor.
    78  */
    78  */
    79 void ec_fsm_soe_init(
    79 void ec_fsm_soe_init(
    80 		ec_fsm_soe_t *fsm, /**< finite state machine */
    80         ec_fsm_soe_t *fsm, /**< finite state machine */
    81 		ec_datagram_t *datagram /**< datagram */
    81         ec_datagram_t *datagram /**< datagram */
    82 		)
    82         )
    83 {
    83 {
    84     fsm->state = NULL;
    84     fsm->state = NULL;
    85     fsm->datagram = datagram;
    85     fsm->datagram = datagram;
    86 }
    86 }
    87 
    87 
    88 /*****************************************************************************/
    88 /*****************************************************************************/
    89 
    89 
    90 /** Destructor.
    90 /** Destructor.
    91  */
    91  */
    92 void ec_fsm_soe_clear(
    92 void ec_fsm_soe_clear(
    93 		ec_fsm_soe_t *fsm /**< finite state machine */
    93         ec_fsm_soe_t *fsm /**< finite state machine */
    94 		)
    94         )
    95 {
    95 {
    96 }
    96 }
    97 
    97 
    98 /*****************************************************************************/
    98 /*****************************************************************************/
    99 
    99 
   107 {
   107 {
   108     fsm->slave = slave;
   108     fsm->slave = slave;
   109     fsm->request = request;
   109     fsm->request = request;
   110     if (request->dir == EC_DIR_OUTPUT) {
   110     if (request->dir == EC_DIR_OUTPUT) {
   111         fsm->state = ec_fsm_soe_write_start;
   111         fsm->state = ec_fsm_soe_write_start;
   112 	} else {
   112     } else {
   113         fsm->state = ec_fsm_soe_read_start;
   113         fsm->state = ec_fsm_soe_read_start;
   114 	}
   114     }
   115 }
   115 }
   116 
   116 
   117 /*****************************************************************************/
   117 /*****************************************************************************/
   118 
   118 
   119 /**
   119 /**
   163         fsm->state = ec_fsm_soe_error;
   163         fsm->state = ec_fsm_soe_error;
   164         return;
   164         return;
   165     }
   165     }
   166 
   166 
   167     data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
   167     data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
   168 			EC_SOE_READ_REQUEST_SIZE);
   168             EC_SOE_READ_REQUEST_SIZE);
   169     if (IS_ERR(data)) {
   169     if (IS_ERR(data)) {
   170         fsm->state = ec_fsm_soe_error;
   170         fsm->state = ec_fsm_soe_error;
   171         return;
   171         return;
   172     }
   172     }
   173 
   173 
   252     }
   252     }
   253 
   253 
   254     if (datagram->working_counter != 1) {
   254     if (datagram->working_counter != 1) {
   255         fsm->state = ec_fsm_soe_error;
   255         fsm->state = ec_fsm_soe_error;
   256         EC_ERR("Reception of SoE mailbox check datagram failed on slave %u: ",
   256         EC_ERR("Reception of SoE mailbox check datagram failed on slave %u: ",
   257 				slave->ring_position);
   257                 slave->ring_position);
   258         ec_datagram_print_wc_error(datagram);
   258         ec_datagram_print_wc_error(datagram);
   259         return;
   259         return;
   260     }
   260     }
   261 
   261 
   262     if (!ec_slave_mbox_check(datagram)) {
   262     if (!ec_slave_mbox_check(datagram)) {
   332     }
   332     }
   333 
   333 
   334     if (rec_size < EC_SOE_READ_RESPONSE_SIZE) {
   334     if (rec_size < EC_SOE_READ_RESPONSE_SIZE) {
   335         fsm->state = ec_fsm_soe_error;
   335         fsm->state = ec_fsm_soe_error;
   336         EC_ERR("Received currupted SoE read response (%zu bytes)!\n",
   336         EC_ERR("Received currupted SoE read response (%zu bytes)!\n",
   337 				rec_size);
   337                 rec_size);
   338         ec_print_data(data, rec_size);
   338         ec_print_data(data, rec_size);
   339         return;
   339         return;
   340     }
   340     }
   341 
   341 
   342     header = EC_READ_U8(data);
   342     header = EC_READ_U8(data);
   343 	opcode = header & 0x7;
   343     opcode = header & 0x7;
   344     incomplete = (header >> 3) & 1;
   344     incomplete = (header >> 3) & 1;
   345 	error_flag = (header >> 4) & 1;
   345     error_flag = (header >> 4) & 1;
   346 
   346 
   347     if (opcode != EC_SOE_OPCODE_READ_RESPONSE) {
   347     if (opcode != EC_SOE_OPCODE_READ_RESPONSE) {
   348         EC_ERR("Received no read response (opcode %x).\n", opcode);
   348         EC_ERR("Received no read response (opcode %x).\n", opcode);
   349         ec_print_data(data, rec_size);
   349         ec_print_data(data, rec_size);
   350         fsm->state = ec_fsm_soe_error;
   350         fsm->state = ec_fsm_soe_error;
   351         return;
   351         return;
   352     }
   352     }
   353 
   353 
   354 	if (error_flag) {
   354     if (error_flag) {
   355 		req->error_code = EC_READ_U16(data + rec_size - 2);
   355         req->error_code = EC_READ_U16(data + rec_size - 2);
   356 		EC_ERR("Received error response: 0x%04x.\n",
   356         EC_ERR("Received error response: 0x%04x.\n",
   357 				req->error_code);
   357                 req->error_code);
   358         fsm->state = ec_fsm_soe_error;
   358         fsm->state = ec_fsm_soe_error;
   359         return;
   359         return;
   360 	} else {
   360     } else {
   361 		req->error_code = 0x0000;
   361         req->error_code = 0x0000;
   362 	}
   362     }
   363 
   363 
   364 	value_included = (EC_READ_U8(data + 1) >> 6) & 1;
   364     value_included = (EC_READ_U8(data + 1) >> 6) & 1;
   365 	if (!value_included) {
   365     if (!value_included) {
   366 		EC_ERR("No value included!\n");
   366         EC_ERR("No value included!\n");
   367 		fsm->state = ec_fsm_soe_error;
   367         fsm->state = ec_fsm_soe_error;
   368 		return;
   368         return;
   369 	}
   369     }
   370 
   370 
   371 	data_size = rec_size - EC_SOE_READ_RESPONSE_SIZE;
   371     data_size = rec_size - EC_SOE_READ_RESPONSE_SIZE;
   372 	if (ec_soe_request_append_data(req,
   372     if (ec_soe_request_append_data(req,
   373                 data + EC_SOE_READ_RESPONSE_SIZE, data_size)) {
   373                 data + EC_SOE_READ_RESPONSE_SIZE, data_size)) {
   374 		fsm->state = ec_fsm_soe_error;
   374         fsm->state = ec_fsm_soe_error;
   375 		return;
   375         return;
   376 	}
   376     }
   377 
   377 
   378     if (incomplete) {
   378     if (incomplete) {
   379         if (master->debug_level) {
   379         if (master->debug_level) {
   380             EC_DBG("SoE data incomplete. Waiting for fragment"
   380             EC_DBG("SoE data incomplete. Waiting for fragment"
   381                     " at offset %zu.\n", req->data_size);
   381                     " at offset %zu.\n", req->data_size);
   428     if (remaining_size % fragment_size) {
   428     if (remaining_size % fragment_size) {
   429         fragments_left++;
   429         fragments_left++;
   430     }
   430     }
   431 
   431 
   432     data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
   432     data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
   433 			EC_SOE_WRITE_REQUEST_SIZE + fragment_size);
   433             EC_SOE_WRITE_REQUEST_SIZE + fragment_size);
   434     if (IS_ERR(data)) {
   434     if (IS_ERR(data)) {
   435         fsm->state = ec_fsm_soe_error;
   435         fsm->state = ec_fsm_soe_error;
   436         return;
   436         return;
   437     }
   437     }
   438 
   438 
   439     EC_WRITE_U8(data, EC_SOE_OPCODE_WRITE_REQUEST | incomplete << 3);
   439     EC_WRITE_U8(data, EC_SOE_OPCODE_WRITE_REQUEST | incomplete << 3);
   440     EC_WRITE_U8(data + 1, 1 << 6); // only value included
   440     EC_WRITE_U8(data + 1, 1 << 6); // only value included
   441     EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
   441     EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
   442 	memcpy(data + 4, req->data + fsm->offset, fragment_size);
   442     memcpy(data + 4, req->data + fsm->offset, fragment_size);
   443     fsm->offset += fragment_size;
   443     fsm->offset += fragment_size;
   444 
   444 
   445     if (master->debug_level) {
   445     if (master->debug_level) {
   446         EC_DBG("SCC write request:\n");
   446         EC_DBG("SCC write request:\n");
   447         ec_print_data(data, EC_SOE_WRITE_REQUEST_SIZE + fragment_size);
   447         ec_print_data(data, EC_SOE_WRITE_REQUEST_SIZE + fragment_size);
   544     }
   544     }
   545 
   545 
   546     if (datagram->working_counter != 1) {
   546     if (datagram->working_counter != 1) {
   547         fsm->state = ec_fsm_soe_error;
   547         fsm->state = ec_fsm_soe_error;
   548         EC_ERR("Reception of SoE write request datagram failed on slave %u: ",
   548         EC_ERR("Reception of SoE write request datagram failed on slave %u: ",
   549 				slave->ring_position);
   549                 slave->ring_position);
   550         ec_datagram_print_wc_error(datagram);
   550         ec_datagram_print_wc_error(datagram);
   551         return;
   551         return;
   552     }
   552     }
   553 
   553 
   554     if (fsm->offset < req->data_size) {
   554     if (fsm->offset < req->data_size) {
   586     ec_datagram_t *datagram = fsm->datagram;
   586     ec_datagram_t *datagram = fsm->datagram;
   587     ec_slave_t *slave = fsm->slave;
   587     ec_slave_t *slave = fsm->slave;
   588     ec_master_t *master = slave->master;
   588     ec_master_t *master = slave->master;
   589     ec_soe_request_t *req = fsm->request;
   589     ec_soe_request_t *req = fsm->request;
   590     uint8_t *data, mbox_prot, opcode, error_flag;
   590     uint8_t *data, mbox_prot, opcode, error_flag;
   591 	uint16_t idn;
   591     uint16_t idn;
   592     size_t rec_size;
   592     size_t rec_size;
   593 
   593 
   594     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   594     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   595         return; // FIXME: request again?
   595         return; // FIXME: request again?
   596 
   596 
   628     }
   628     }
   629 
   629 
   630     if (rec_size < EC_SOE_WRITE_RESPONSE_SIZE) {
   630     if (rec_size < EC_SOE_WRITE_RESPONSE_SIZE) {
   631         fsm->state = ec_fsm_soe_error;
   631         fsm->state = ec_fsm_soe_error;
   632         EC_ERR("Received currupted SoE write response (%zu bytes)!\n",
   632         EC_ERR("Received currupted SoE write response (%zu bytes)!\n",
   633 				rec_size);
   633                 rec_size);
   634         ec_print_data(data, rec_size);
   634         ec_print_data(data, rec_size);
   635         return;
   635         return;
   636     }
   636     }
   637 
   637 
   638 	opcode = EC_READ_U8(data) & 0x7;
   638     opcode = EC_READ_U8(data) & 0x7;
   639     if (opcode != EC_SOE_OPCODE_WRITE_RESPONSE) {
   639     if (opcode != EC_SOE_OPCODE_WRITE_RESPONSE) {
   640         EC_ERR("Received no write response (opcode %x).\n", opcode);
   640         EC_ERR("Received no write response (opcode %x).\n", opcode);
   641         ec_print_data(data, rec_size);
   641         ec_print_data(data, rec_size);
   642         fsm->state = ec_fsm_soe_error;
   642         fsm->state = ec_fsm_soe_error;
   643         return;
   643         return;
   644     }
   644     }
   645 
   645 
   646 	idn = EC_READ_U16(data + 2);
   646     idn = EC_READ_U16(data + 2);
   647 	if (idn != req->idn) {
   647     if (idn != req->idn) {
   648 		EC_ERR("Received response for wrong IDN 0x%04x.\n", idn);
   648         EC_ERR("Received response for wrong IDN 0x%04x.\n", idn);
   649         ec_print_data(data, rec_size);
   649         ec_print_data(data, rec_size);
   650         fsm->state = ec_fsm_soe_error;
   650         fsm->state = ec_fsm_soe_error;
   651 		return;
   651         return;
   652 	}
   652     }
   653 
   653 
   654 	error_flag = (EC_READ_U8(data) >> 4) & 1;
   654     error_flag = (EC_READ_U8(data) >> 4) & 1;
   655 	if (error_flag) {
   655     if (error_flag) {
   656 		if (rec_size < EC_SOE_WRITE_RESPONSE_SIZE + 2) {
   656         if (rec_size < EC_SOE_WRITE_RESPONSE_SIZE + 2) {
   657 			EC_ERR("Received corrupted error response - error flag set,"
   657             EC_ERR("Received corrupted error response - error flag set,"
   658 					" but received size is %zu.\n", rec_size);
   658                     " but received size is %zu.\n", rec_size);
   659 		} else {
   659         } else {
   660 			req->error_code = EC_READ_U16(data + EC_SOE_WRITE_RESPONSE_SIZE);
   660             req->error_code = EC_READ_U16(data + EC_SOE_WRITE_RESPONSE_SIZE);
   661 			EC_ERR("Received error response: 0x%04x.\n",
   661             EC_ERR("Received error response: 0x%04x.\n",
   662 					req->error_code);
   662                     req->error_code);
   663 		}
   663         }
   664 		ec_print_data(data, rec_size);
   664         ec_print_data(data, rec_size);
   665 		fsm->state = ec_fsm_soe_error;
   665         fsm->state = ec_fsm_soe_error;
   666         return;
   666         return;
   667 	} else {
   667     } else {
   668 		req->error_code = 0x0000;
   668         req->error_code = 0x0000;
   669 	}
   669     }
   670 
   670 
   671     fsm->state = ec_fsm_soe_end; // success
   671     fsm->state = ec_fsm_soe_end; // success
   672 }
   672 }
   673 
   673 
   674 /*****************************************************************************/
   674 /*****************************************************************************/