Applied 0009-Avoid-changing-running-slaves-DC-offset.patch

This commit is contained in:
Florian Pose 2022-06-23 10:53:56 +02:00
parent 225af9f787
commit 90f3f7e841
1 changed files with 68 additions and 1 deletions

View File

@ -69,6 +69,8 @@ void ec_fsm_master_state_dc_measure_delays(ec_fsm_master_t *);
void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
void ec_fsm_master_state_dc_read_offset(ec_fsm_master_t *);
void ec_fsm_master_state_dc_write_offset(ec_fsm_master_t *);
void ec_fsm_master_state_dc_reset_filter(ec_fsm_master_t *);
void ec_fsm_master_state_assign_sii(ec_fsm_master_t *);
void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
@ -1250,8 +1252,9 @@ void ec_fsm_master_enter_write_system_times(
// read DC system time (0x0910, 64 bit)
// gap (64 bit)
// and time offset (0x0920, 64 bit)
// and receive delay (0x0928, 32 bit)
ec_datagram_fprd(fsm->datagram, fsm->slave->station_address,
0x0910, 24);
0x0910, 28);
ec_datagram_zero(fsm->datagram);
fsm->datagram->device_index = fsm->slave->device_index;
fsm->retries = EC_FSM_RETRIES;
@ -1353,6 +1356,7 @@ void ec_fsm_master_state_dc_read_offset(
ec_slave_t *slave = fsm->slave;
ec_master_t *master = fsm->master;
u64 system_time, old_offset, new_offset;
u32 old_delay;
if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
return;
@ -1384,6 +1388,7 @@ void ec_fsm_master_state_dc_read_offset(
system_time = EC_READ_U64(datagram->data); // 0x0910
old_offset = EC_READ_U64(datagram->data + 16); // 0x0920
old_delay = EC_READ_U32(datagram->data + 24); // 0x0928
if (slave->base_dc_range == EC_DC_32) {
new_offset = ec_fsm_master_dc_offset32(fsm,
@ -1393,6 +1398,23 @@ void ec_fsm_master_state_dc_read_offset(
system_time, old_offset, datagram->app_time_sent);
}
if (new_offset != old_offset
&& slave->current_state >= EC_SLAVE_STATE_SAFEOP) {
// Slave is already active; changing the system time offset could
// cause problems. Leave the offset alone in this case and just
// let the normal cyclic sync process gradually adjust it to the
// correct time.
EC_SLAVE_DBG(slave, 1, "Slave is running; ignoring DC offset change.\n");
new_offset = old_offset;
}
if (new_offset == old_offset && slave->transmission_delay == old_delay) {
// offsets have not changed; skip write to avoid possible trouble
fsm->slave++;
ec_fsm_master_enter_write_system_times(fsm);
return;
}
// set DC system time offset and transmission delay
ec_datagram_fpwr(datagram, slave->station_address, 0x0920, 12);
EC_WRITE_U64(datagram->data, new_offset);
@ -1433,6 +1455,51 @@ void ec_fsm_master_state_dc_write_offset(
return;
}
// reset DC filter after changing offsets
if (slave->current_state >= EC_SLAVE_STATE_SAFEOP) {
EC_SLAVE_DBG(slave, 1, "Slave is running; not resetting DC filter.\n");
fsm->slave++;
ec_fsm_master_enter_write_system_times(fsm);
} else {
ec_datagram_fpwr(datagram, slave->station_address, 0x0930, 2);
EC_WRITE_U16(datagram->data, 0x1000);
fsm->datagram->device_index = slave->device_index;
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_master_state_dc_reset_filter;
}
}
/*****************************************************************************/
/** Master state: DC RESET FILTER.
*/
void ec_fsm_master_state_dc_reset_filter(
ec_fsm_master_t *fsm /**< Master state machine. */
)
{
ec_datagram_t *datagram = fsm->datagram;
ec_slave_t *slave = fsm->slave;
if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
return;
if (datagram->state != EC_DATAGRAM_RECEIVED) {
EC_SLAVE_ERR(slave,
"Failed to receive DC reset filter datagram: ");
ec_datagram_print_state(datagram);
fsm->slave++;
ec_fsm_master_enter_write_system_times(fsm);
return;
}
if (datagram->working_counter != 1) {
EC_SLAVE_ERR(slave, "Failed to reset DC filter: ");
ec_datagram_print_wc_error(datagram);
fsm->slave++;
ec_fsm_master_enter_write_system_times(fsm);
return;
}
fsm->slave++;
ec_fsm_master_enter_write_system_times(fsm);
}