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

Initial progress dump for Mcp25xxx binding #306

Merged
merged 46 commits into from
May 9, 2019
Merged

Initial progress dump for Mcp25xxx binding #306

merged 46 commits into from
May 9, 2019

Conversation

shaggygi
Copy link
Contributor

@shaggygi shaggygi commented Mar 3, 2019

This adds a device binding for the Microchip Mcp25xxx CAN controller.

Notes:

  • This is only an initial dump of project files and current API structure.
  • The intent is to provide a basic binding for CAN to allow team to work with CAN hardware in order to learn and implement CAN interfaces as we did with Mcp23xxx and IGpioController. That effort will not be in this PR.
  • This PR only includes the basics of working with commands and registers. There are areas that can be improved to configure registers for communications. For example, you must assign correct bits for Extended Identifier (EID) in multiple registers (TXBxSIDL, TXBxEID8). Improved helper methods will be added in a future PR as more progress is made on CAN interfaces mentioned above.
  • The API should work with Mcp2510 and Mcp25625 devices.
  • This offers a way for Linux and Windows 10 IoT to interface with CAN devices via SPI.
  • Little testing has been performed against hardware as I'm still reviewing tooling, datasheet, hardware, etc. I'll focus on this next.
  • A future PR will be added for samples and Fritzing. Basic links and references have been added for now.

cc: @krwq @joperezr

@krwq
Copy link
Member

krwq commented Mar 3, 2019

Nice @shaggygi! Will take a look whenever I got time 😄

@krwq krwq changed the title [WIP] Initial progress dump for Mcp25xxx binding Initial progress dump for Mcp25xxx binding Mar 8, 2019
@krwq krwq added the WIP label Mar 8, 2019
@shaggygi
Copy link
Contributor Author

shaggygi commented Mar 9, 2019

@krwq i reached a point for majority of initial register tests and changed GetAddress() method to Address property. If time allows, I'll try to focus on the instructions and more interaction with hardware over the weekend.

@krwq
Copy link
Member

krwq commented Mar 9, 2019

Sounds good @shaggygi - Once you get to the point where you send can frames don't build more on top of that except simple tests since that will have overlap with the stuff which I'm doing right now so we can merge from there - I was able to send couple of frames over the wire and learning details about what can be done and how we should expose it.

@shaggygi
Copy link
Contributor Author

shaggygi commented Mar 10, 2019

@krwq I now have the commands added. I was able to perform a few interactions with the device and appear you can read/write to registers. Sadly, I have not been successful on transmitting/receiving over the wire. This is mostly like because I'm configuring the device wrong. I'll keep tinkering when I get a chance.

Please go ahead and skim over the current code. I would like to go ahead an check in the progress as team should be able to play around with these bits enough to discuss how/if a generic CAN abstraction could be used with this and other implementations.

I want to take a breather from this binding for a few days to study some other things.

Let me know if you find mistakes (I'm sure there are a few) 😄 Thx

@shaggygi
Copy link
Contributor Author

@joperezr no prob. I still believe it covers most of the feedback for now. As mentioned, it is expected to have future enhancement PRs by community as we figure out a good CAN structure for other implentations. I have some ideas to help troubleshoot this with TIOT project once I recover.

</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Device.Gpio" Version="0.1.0-prerelease*" />
Copy link
Member

Choose a reason for hiding this comment

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

use $(SystemDeviceGpioPackageVersion) instead of the specific version (recently changed everywhere)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will update.

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'm going to hold off on this until the end. There are some other changes in the repo that have since been changed and break my local build when doing this.

switch (RxFilterNumber)
{
case 0:
return Address.RxF0Eid0;
Copy link
Member

Choose a reason for hiding this comment

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

optional: I think would smplify a bit if you converted this to array and just simply use indexer and IndexOf (I think Span has it somewhere) for the other method

Copy link
Member

Choose a reason for hiding this comment

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

same comment for similar classes (actually wondering if we should unify them into one class)

Copy link
Contributor Author

@shaggygi shaggygi Apr 27, 2019

Choose a reason for hiding this comment

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

This would be better approach. I started to update and get an error I can't seem to understand though.

This example works (not related to binding):

ReadOnlySpan<byte> value = new byte[] { 0x00, 0x01, 0x02 };
value.IndexOf<byte>(0x00);

Below I get the following and not sure why it is trying to use the overloaded method call:

Error CS1503 Argument 2: cannot convert from 'Iot.Device.Mcp25xxx.Register.Address' to 'System.ReadOnlySpan<Iot.Device.Mcp25xxx.Register.Address>'

ReadOnlySpan<Address> addresses = new Address[] {Address.TxB0Sidl, Address.TxB1Sidl, Address.TxB2Sidl };
addresses.IndexOf<Address>(Address.TxB0Sidl);  // Get red squiggles here.

Have any thoughts on this?

Copy link
Member

Choose a reason for hiding this comment

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

I think you can workaround by creating stackalloc Address[1] { whateverYouSearchFor } since this is what it seems to expect. I would presume searching for single element should work though. cc: @ahsonkhan @GrabYourPitchforks

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 tried this and works, but is not ideal.

Address address = Address.RxB1Dlc;

ReadOnlySpan<byte> addresses = stackalloc byte[2]
{
    (byte)Address.RxB0Dlc,
    (byte)Address.RxB1Dlc
};

int index = addresses.IndexOf((byte)address);

if( index < 0)
{
    throw new ArgumentException($"Invalid address value {address}.", nameof(address));
}

return (byte)index;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@joperezr do you have any thoughts on how to fix this? I still see error in newest VS2019 preview, as well.

Copy link
Member

Choose a reason for hiding this comment

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

The reason why this happens is because the extension method IndexOf requires that the T type should be IEquatable, and an Enum will derive from System.Enum which is not IEquatable. You could theoretically cast it as a byte if you wanted which should work, or alternatively, instead of having Address be an Enum, you could have it be a struct that does extends byte and has some default static values. For that suggestion, you can take a look at what we did with PinValue here: https://github.com/dotnet/iot/blob/master/src/System.Device.Gpio/System/Device/Gpio/PinValue.cs

Choose a reason for hiding this comment

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

As an aside, I am not sure if it makes sense to use IndexOf to search through a compile-time known enum set like this and the switch/case makes more sense to me. Why incur the cost of searching through the enum array every time? What's the benefit?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ahsonkhan Thanks for feedback. This change was based on other feedback for the PR. @krwq If you're good with current code, I believe there are no more outstanding issues with PR.

@krwq
Copy link
Member

krwq commented Apr 17, 2019

Overall looks good to me and I'm fine with merging as is.

Long term all public abbreviated names (mostly thinking about registers and their properties) should be expanded and clear - ideally we should not expose registers at all though

@shaggygi
Copy link
Contributor Author

@krwq thanks for another round of feedback. I plan to address the issues, but as mentioned to @joperezr, I'm out with an injury 🤕 and most likely for another week or so. Leave open until I get a chance to complete. Thx

@krwq
Copy link
Member

krwq commented Apr 24, 2019

No worries @shaggygi, get better!

@shaggygi
Copy link
Contributor Author

ideally we should not expose registers at all though

I think this makes sense for some very simple bindings, but I look at it 2 ways for binding such as this Mcp25xxx.

  1. Some devs will want to interact with the binding directly and get down to the details of setting/getting registers/parameters. Gives them more control on what they want with the capabilities of the component's internals.

  2. Some devs (and probably in most cases) will want to interact with the binding using an interface. Once we determine this (e.g. ICanController or similar), they will use this and perform the general Reads/Writes of CAN messages. The registers/parameters would be set/get at a level they care to see.

@krwq
Copy link
Member

krwq commented Apr 27, 2019

@shaggygi fine with me - if possible you can try to make them protected so that by default you won't see them and if someone needs them they can derive - fine to leave as is for now (please expand names though)

@krwq
Copy link
Member

krwq commented Apr 27, 2019

LGTM so far, let me know once you address all feedback

@shaggygi
Copy link
Contributor Author

Updated the register properties extended names. Still have to review the address array feedback and package version.

@joperezr
Copy link
Member

joperezr commented May 9, 2019

LGTM! thanks for the hard work on this @shaggygi ! 🎆

@joperezr joperezr merged commit c507785 into dotnet:master May 9, 2019
@shaggygi shaggygi deleted the mcp25xx-can-controller branch May 10, 2019 11:01
@github-actions github-actions bot locked and limited conversation to collaborators Dec 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants