can mcp2515: spi can controller driver#6276
can mcp2515: spi can controller driver#6276vincent-d wants to merge 2 commits intoRIOT-OS:masterfrom
Conversation
|
If someone from Berlin has time to review and test but needs hardware: feel free to contact me. |
5f0c589 to
b6f79e2
Compare
|
Rebased and adapted with the new autoinit process from #5793, and the new SPI interface! |
|
Since no review has happened so far, why don't you squash commits before anyone starts to review? |
|
mcp2515 part is squashed |
c02f87c to
fe54ff0
Compare
d5a8273 to
ce1892a
Compare
1a9d198 to
6b7dc4a
Compare
This driver implements the candev interface
|
@LudwigKnuepfer if you have the hardware and mind testing yourself, why don't you ask @mfrey for assistance? |
|
@LudwigKnuepfer @A-Paul ping? |
|
@aabadie , @lebrush and @haukepetersen. Is there a chance to review this PR? |
| /** masks list */ | ||
| uint32_t masks[MCP2515_RX_MAILBOXES]; | ||
| /** filters list */ | ||
| canid_t filter_ids[MCP2515_RX_MAILBOXES][MCP2515_FILTERS_MB1]; |
There was a problem hiding this comment.
There are two filter_ids too much, which will never be used. The construction MCP2515_FILTERS_MB0 * mailbox_index + filter_pos is used to interface with the mcp2515, I think the same construction could be used to access memory and two positions could be saved.
|
|
||
| static inline int _max_filters(int mailbox) | ||
| { | ||
| return mailbox == 0 ? MCP2515_FILTERS_MB0 : MCP2515_FILTERS_MB1; |
There was a problem hiding this comment.
parenthesis. I've been quite a bit off-line, maybe this is accepted now :-)
|
|
||
| void candev_mcp2515_init(candev_mcp2515_t *dev, const candev_mcp2515_conf_t *conf) | ||
| { | ||
| memset(dev, 0, sizeof(*dev)); |
There was a problem hiding this comment.
dev not checked against NULL
i guess it's assumed that it will never be NULL. I remember in some pieces of RIOT's code the doxygen claims something like @pre (dev != NULL)` to make the user aware (and then point to a usage bug and not a code issue)
| memcpy(&dev->candev.bittiming, &timing, sizeof(timing)); | ||
| /* configure filters to be closed */ | ||
| for (int mailbox = 0; mailbox < MCP2515_RX_MAILBOXES; mailbox++) { | ||
| dev->masks[mailbox] = 0; |
There was a problem hiding this comment.
I think these loops are not necessary. You already set all dev struct to 0 on the first line of the method.
| } | ||
| } | ||
| res = mcp2515_set_mode(dev, MODE_NORMAL); | ||
| return res; |
There was a problem hiding this comment.
maybe you can remove res and simply return mcp2515_set_mode(...)
| int res = mcp2515_spi_read(dev, MCP2515_CANSTAT, &mode, 1); | ||
| if (res == 0) { | ||
| //TODO: error handling of extra information in mode result | ||
| result = (enum mcp2515_mode) mode & MCP2515_CANSTAT_OPMOD_MASK; |
|
|
||
| mcp2515_spi_bitmod(dev, MCP2515_CANCTRL, MCP2515_CANCTRL_REQOP_MASK, (uint8_t) mode); | ||
| int cnt = 0; | ||
| while (cur_mode != mode && cnt++ < 2) { |
| #define CAN_IRQ_PORTREN P1REN | ||
| #define CAN_IRQ_PORTIES P1IES | ||
| #define CAN_IRQ_PORTIE P1IE | ||
| #define CAN_IRQ_PORTIFG P1IFG |
There was a problem hiding this comment.
Are these defines board/cpu specific?
| FEATURES_REQUIRED += periph_gpio | ||
| endif | ||
|
|
||
| ifneq (,$(filter ltc4150,$(USEMODULE))) |
|
|
||
| DEBUG("Inside mcp2515 set opt=%d\n", opt); | ||
| switch (opt) { | ||
| case CANOPT_BITTIMING: /**< bit timing parameter */ |
|
@vincent-d, I apologize for the delay. Hopefully you're still interested to get this driver into RIOT. I made an approach to come as close as possible to run the test with a real device (although I havn't one yet). Both, with a checked out pure branch and rebased onto master. But build failed. I also have no clue what to do when the shell will be running. And "tests/driver_mcp2515/README.md" is a litlle bit terse. |
A-Paul
left a comment
There was a problem hiding this comment.
Compiling the test application faiies.
In the initial comment you mention creating a "can_conf_mcp2515.h". Where should this be placed?
There seems to be not location in the code where this file is referenced.
It defines a variable of type candev_mcp2515_conf_t, same as in the "main.c" where the unrsolved sysbol are. Why is this defined twice?
|
|
||
| static const candev_mcp2515_conf_t conf = { | ||
| .spi = SPI_1, | ||
| .cs_pin = CAN2_SS_PIN, |
There was a problem hiding this comment.
Causes a compile error as undeclared. Should it be replaced because names have changed or defined by the user?
| static const candev_mcp2515_conf_t conf = { | ||
| .spi = SPI_1, | ||
| .cs_pin = CAN2_SS_PIN, | ||
| .rst_pin = CAN2_RST_PIN, |
| .spi = SPI_1, | ||
| .cs_pin = CAN2_SS_PIN, | ||
| .rst_pin = CAN2_RST_PIN, | ||
| .int_pin = CAN2_INT_PIN, |
|
|
||
|
|
||
| static const shell_command_t shell_commands[] = { | ||
| { "send", "send some data", _send }, |
There was a problem hiding this comment.
_send causes a compile error as undeclared.
|
|
||
| static const shell_command_t shell_commands[] = { | ||
| { "send", "send some data", _send }, | ||
| { "receive", "receive some data", _receive }, |
There was a problem hiding this comment.
_receive causes a compile error as undeclared.
|
I'm gonna need some time to get back into this, it's been quite a long time ;) Thanks for taking a look at it anyway. We actually don't use it in our product anymore, but I still think this driver is useful as this device is widely used. If I remember correctly we wanted to rework or remove this test app, as it actually should be tested through the stack. I can't promise I'll work on this soon as it's not anymore on top of my priority list. |
|
@vincent-d I have the hardware and tried to test it but couldn't make it work. I connected it to a CAN bus where I'm certain that CAN messages are send on it from another (non-RIOT) device, but the receive IRQ and its handler on the MCP2515 never fired. Could be SPI related though, but the SPI is working - I tested with another device driver which worked fine. |
|
@smlng what board are you using and which code changes have you made? |
|
I'm using a Bluepill, I just made a quick test no in-depth debugging, my changes are here https://github.com/smlng/RIOT/tree/testing/mcp2515 |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
|
Closing this PR in favor of #13624. |
This driver is compliant with the candev interface and this PR is based on #5793 .
It has been tested on our own hardware.
The mcp2515 needs an external clock which can be provided wither by a crystal or by the host MCU.
A can_conf_mcp2515.h file is needed and must contains at least the following: