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

CAN Support #100

Merged
merged 22 commits into from
Oct 20, 2020
Merged

CAN Support #100

merged 22 commits into from
Oct 20, 2020

Conversation

zklapow
Copy link
Contributor

@zklapow zklapow commented May 9, 2020

This PR is fairly incomplete still, though it is functional.

I created a (temp) create called embedded-hal-can to try implementing the traits currently in rust-embedded/embedded-hal#77 though that PR is so old now, I am not sure its going to get much traction (and I am not totally sure I love the structure of those traits anyhow) so I may remove that piece.

I have been testing this on an STM32f302C8T6, I am working on simplifying my "blinky with can" into an example of how to use this.

todos:

  • Generify this to support other stm32f3xx devices

future improvements:

  • Some sort of baud rate param heuristics (maybe just embed a table for standard rates?)
  • Improved filter handling (the current implementation "wastes" filter registers)

Wanted to post this now though as I have been sitting on it for a while and I figured it would be good to at least get thoughts/feedback.

Copy link
Member

@Sh3Rm4n Sh3Rm4n left a comment

Choose a reason for hiding this comment

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

Thank you for this PR!

I left some comments, but these are mostly nit-picks. I know this PR is still WIP, so ignore comments which are not applicable.

Disclaimer: I did not have much experience with Can nor did I look into the CAN hal proposal.

src/can.rs Outdated
}

impl CanFrame {
pub fn new_with_len(id: CanId, data: &[u8], length: usize) -> CanFrame {
Copy link
Member

Choose a reason for hiding this comment

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

Just curious. Why must the data slice be converted into an array? Slice has a len() method. Maybe you could give me some insight :)

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 should likely limit the visibility of this method and it could be simplified a bit... The reason this exists is mainly to do with lifetimes and there are sort of two reasons for it:

  1. is for reading, we allocate an array always of length 8 bytes (the max CAN frame size), because we cant do dynamic allocation and then use a subslice of it, but now that I think more about it, we can likely just consume that array in this case and avoid the reference.
  2. Is because of how we need to implement embedded_hal_can::Frame. Having every frame have a 8 byte backing array was just the simplest way to handle this without getting into using generic_array or something, but ultimately I may do that, because it would make the code clearer.

@zklapow
Copy link
Contributor Author

zklapow commented May 17, 2020

Added a simple "blinky" example, heres a GIF of it in action:

Image

@zklapow zklapow changed the title [WIP] CAN Support CAN Support May 30, 2020
@zklapow
Copy link
Contributor Author

zklapow commented May 30, 2020

@Sh3Rm4n this should be ready for another look when you have some time, it should be mergeable in its current state.

A couple notes:

  • I updated to use ArrayVec to give the CanFrame a slightly simpler API (no need to remember that there is an extra length field there!). I tried to use generic_array but I don't think that will be possible without having transmit be generic of the frame size. Given that a frame is at most 8 bytes, having to allocate the full backing array seemed OK. (I also considered introducing some sort of allocator dedicated to canframes but.... that seemed extreme)
  • Everything should be behind the can feature flag now, so it is disabled by default.

@zklapow
Copy link
Contributor Author

zklapow commented Jul 12, 2020

@Sh3Rm4n any thoughts on another review or merging this?

@teskje
Copy link
Collaborator

teskje commented Jul 15, 2020

I'm working on getting all the open PRs reviewed, starting with the oldest one. If @Sh3Rm4n is busy I'll take a look once I got to this one.

Just to confirm though: Do you consider this ready for merging? I'm asking because there are still two open TODOs.

@zklapow
Copy link
Contributor Author

zklapow commented Jul 17, 2020

I moved those around a bit to be more clear, I do think they would be interesting to tackle in the future but are sort of hard and don't really affect the functionality here much. This should be useable and mergeable as-is.

@Sh3Rm4n Sh3Rm4n mentioned this pull request Jul 19, 2020
Copy link
Member

@Sh3Rm4n Sh3Rm4n left a comment

Choose a reason for hiding this comment

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

Sorry for keeping you waiting. I've left some comments, but I did not dive into the implementation logic, yet.

let filter = CanFilter::from_mask(0b100, ID as u32);
rx0.set_filter(filter);

// Watchdog makes sure this gets restarted periodically if nothing happens
Copy link
Member

Choose a reason for hiding this comment

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

Nice, this is also now an example for the watchdog 👍


static FILTER_INDEX: AtomicU8 = AtomicU8::new(0);

pub struct Can {
Copy link
Member

Choose a reason for hiding this comment

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

I would like to see more comments / documentation, especially on the public interfaces, like this struct :)

@zklapow zklapow force-pushed the canbus-with-crate branch from 11ea850 to 6d18d68 Compare August 6, 2020 23:44
@zklapow
Copy link
Contributor Author

zklapow commented Aug 6, 2020

I have updated this to address the open comments. I added a bunch of notes about the usages of unsafe but a lot of those notes are semi silly but calling bits() is just always unsafe but also the only way to access those registers.

@David-OConnor
Copy link
Contributor

Merge!

@zklapow
Copy link
Contributor Author

zklapow commented Sep 28, 2020

@David-OConnor would love to tho I dont have access 👍

@Sh3Rm4n or @ra-kete I have merged master to address some conflicts as well as updated the changelog, and the build is passing. Any chance one of you could merge this for me when you have a moment? I think all of the comments should be addressed.

@teskje
Copy link
Collaborator

teskje commented Sep 28, 2020

@Sh3Rm4n has reviewed this, so if he gives his thumbs-up for merging I'm fine too.

Copy link
Member

@Sh3Rm4n Sh3Rm4n left a comment

Choose a reason for hiding this comment

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

Hey, sorry for the late response.

Minor nits and this is not addressed, yet.

But overall LGTM. :)

src/can.rs Outdated
return (transmitter, fifo0, fifo1);
}

pub fn release(self) -> stm32::CAN {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
pub fn release(self) -> stm32::CAN {
pub fn free(self) -> stm32::CAN {

And it should release gpioa::PA11<AF9> and gpioa::PA12<AF9> as well.

@zklapow
Copy link
Contributor Author

zklapow commented Oct 19, 2020

updated, the docs are still a bit sparse but unfortunately I don't have a ton of time to work on this ATM.

@Sh3Rm4n
Copy link
Member

Sh3Rm4n commented Oct 20, 2020

Nice. Thanks for the contribution. Finally i've time to merge this 🎉

Thanks for your patience. Further things can still be improved later on, if necessary.

@Sh3Rm4n Sh3Rm4n merged commit 33c84a6 into stm32-rs:master Oct 20, 2020
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.

4 participants