Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Expose escape hatch for manual PDI configuration, misc other changes. #243

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

david-boles
Copy link
Contributor

Hey James; following up on #228. These are the changes I needed to make use of ethercrab with my devices and in the context of the rest of my system. I'm not sure this is all realistically upstreamable, but I'd love to merge however much of it you'd like to take!

ESI files ended up missing a bunch of information that I needed (e.g. decomposing bytes into bit flags, my-system-specific representations and metadata for the ESI variables) so I didn't end up going down that path after all; represented here is a just a ~minimum-viable escape hatch to allow manual SM and FMMU configuration... plus a few other miscellaneous changes that I wanted.

@david-boles david-boles changed the title Expose escape hatch for manual PDI configuration, misc other changes. [WIP] Expose escape hatch for manual PDI configuration, misc other changes. Oct 17, 2024
@@ -262,10 +262,14 @@ impl From<PdoType> for CategoryType {
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum FmmuUsage {
/// TODO
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll obviously document these properly if you agree with exposing these types publicly.

type Error;

/// TODO
async fn configure<'a, S>(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I would have had this just be an FnMut callback instead of its own trait but that's not possible at the moment, as far as I can figure out:
rust-lang/rust#97362 (comment)

/// Configure PDI using the PDO assignments in CoE registers.
#[derive(Clone, Copy)]
pub struct ConfigureSubdevicePdiBasedOnCoe;
impl ConfigureSubdevicePdi for ConfigureSubdevicePdiBasedOnCoe {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These implementations should be unchanged; I'm just exposing them as separate callbacks. This would have been useful when I was first debugging and wanted to try EEPROM-based setup even though my device supports CoE.

@@ -102,12 +459,13 @@ where
/// Second state configuration (PRE-OP -> SAFE-OP).
///
/// PDOs must be configured in the PRE-OP state.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Review the doc comments on modified functions

/// TODO
pub fn as_raw_ref_mut(&mut self) -> SubDeviceRef<'a, &mut SubDevice> {
SubDeviceRef { maindevice: self.maindevice, configured_address: self.configured_address, state: self.state.deref_mut() }
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is maybe a very me-specific problem but I wanted to pass the SubDeviceRefs to a trait object function, so I needed a concrete type.

@@ -776,6 +786,11 @@ impl<'a, S> SubDeviceRef<'a, S> {
self.configured_address
}

/// Get the index of this subdevice in the overall EtherCAT network when it was first initialized.
pub fn topology_address_at_init(&self) -> u16 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than rely on ethercrab continuing to configure addresses in the future based on a fixed base plus the position in the topology, I figured I'd add that information to the API explicitly.

@@ -854,6 +869,11 @@ where
self.process_pdi_response(&data)
}

/// TODO
pub fn pdi_range(&self) -> Range<u32> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my case I'm actually doing some manual interaction with the PDI, so it was helpful to know the entire range for the group.

@jamwaffles
Copy link
Collaborator

Hey David, thanks or posting this PR. I'm afraid I don't have time to review it in depth at the moment as I started fulltime work not too long ago and am busy with that.

I'd really appreciate a new demo in examples/ that shows the usage of these changes so I can better understand how they fit in if you don't mind.

Comment on lines +181 to +197
let sm_config = subdevice
.write_sm_config(sm_idx, &sync_managers[usize::from(sm_idx)], len_bytes)
.await
.expect("configuring sync manager");
let desired_sm_type = match direction {
PdoDirection::MasterRead => SyncManagerType::ProcessDataRead,
PdoDirection::MasterWrite => SyncManagerType::ProcessDataWrite,
};
subdevice
.write_fmmu_config(len_bits, fmmu_idx, global_offset, desired_sm_type, &sm_config)
.await
.expect("configuring fmmu");

Ok(PdiSegment {
bit_len: usize::from(len_bits),
bytes: start_offset.up_to(*global_offset),
})
Copy link
Contributor Author

@david-boles david-boles Oct 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the important lines that this PR facilitates; the ability for a user to configure the SMs and FMMUs of their subdevices themselves.

While avoiding substantially changing the existing EtherCrab PDI setup flow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants