-
Notifications
You must be signed in to change notification settings - Fork 1.3k
canio: Initial implementation for SAM E5x MCUs #3425
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
Conversation
419d4f6
to
7fec662
Compare
[Rebased to clear out some merge conflicts due to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is a first pass. Thanks for your work on this!
I'm about to rebase this, so I've tagged the pre-rebase last revision: https://github.com/jepler/circuitpython/releases/tag/canbus-v1 jepler@5307ed9 |
.. it'll be used in can as well as sdio
This makes it much easier to implement enums, and the printing code is shared. We might want to convert other enums to this in the future.
Tested & working: * Send standard packets * Receive standard packets (1 FIFO, no filter) Interoperation between SAM E54 Xplained running this tree and MicroPython running on STM32F405 Feather with an external transceiver was also tested. Many other aspects of a full implementation are not yet present, such as error detection and recovery.
Lightly tested: * no matches (catch-all) * standard address single address matches (even and odd positions) * standard address mask matches * only tested that extended doesn't match non-extended
This reflects our belief that the API is stable enough to avoid incompatible changes during 6.x.
I've run into some problems with my final testing, please don't merge this just yet |
OK, I think this is ready. It passes my test program, which I made more extensive. Yay for having loopback mode! Test program: https://gist.github.com/3627fbe0659ae8e54dee27d49699ae4d can run without transceiver, self-verifies "all" functionality |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Nice job with this!
@@ -226,6 +230,10 @@ void cleanup_after_vm(supervisor_allocation* heap) { | |||
free_memory(heap); | |||
supervisor_move_memory(); | |||
|
|||
#if CIRCUITPY_CANIO | |||
common_hal_canio_reset(); | |||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Not for this PR.) We should have a reset_common_hal that wraps all of these. Right now they are don't haphazard in reset_port.
My though is that RTRs and normal messages are not functionally the same so using the same class for both is a bit awkward. If there were two types, then you'd have to know which type to pass into On the receiving end especially, you're going to want to know if it's an RTR message so at some point I would expect code like
We need to know if a message is an RTR or not on both ends, and using a type works in both cases. On creation the constructor has a different signature, and on the receiving end you can use
I feel like I'm barking up a dead tree so I'll leave it at that. PS:I lied: I think RTRMessage is more likely to be used in user code than |
@siddacious has been kind enough to point out some other problems in the docs. I'd like to consider a couple other changes while this still hasn't gone out as beta:
|
@jepler Yup, those seem like good changes. I would like @siddacious Are you proposing dropping readinto in favor of splitting Message into two types, Message and RemoteTransmissionRequest? I like that too. readinto isn't that helpful because you've already set filters so you only receive objects you are interested in. |
@siddacious I don't have anything against If others agree that somehting like a "message pool" would be useful, it would be helpful to provide helpers because they're not trivial (I tried) |
This is very similar to how we do BLE advertisements and we do not have a The objects are typically small so they do not get harder to allocate as the heap fragments. (Reuse is way more important for large objects.) |
If at some point we support CAN FD, the payload of a single message can be up to 64 bytes, rather than just 8. |
@jepler are |
All 4 combinations of silent= and loopback= work on SAM E5x and (as far as I can tell so far) on the STM32. If some combinations are NOT supported, the constructor should throw. |
I guess I don't know what makes sense here; From a user perspective I think setting a mode that has the behavior you want is more important than what bits get set. I don't know if the MCP is the outlier here or the SAM; do other MCUs support all 4 options of the "transmit y/n" and loopback y/n" matrix? |
We can always add readinto if we really need it. I suspect this approach will still be OK because 64 bytes is still only 4 blocks (16b each) of memory. |
STM and SAM both support all 4 modes. Feel free to throw an exception in your constructor if a non-supported mode is requested. Constructors will necessarily differ a little bit in their semantics as different HW has different capabilities. |
esp32s2 has distinct register bits so it looks like all 4 modes would be supported, but at another level the API only supports 3 of the 4 combinations.
but
|
Tested & working:
Interoperation between SAM E54 Xplained running this tree and MicroPython running on STM32F405 Feather with an external transceiver was also tested. (SAM-to-SAM is not actually tested yet)
Error detection and recovery are supported.
Transmitter program:
Receiver program: