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

Add CAN support for nucleo-l476rg #13534

Merged
merged 3 commits into from
Mar 23, 2020

Conversation

Ciusss89
Copy link
Contributor

@Ciusss89 Ciusss89 commented Mar 2, 2020

fix #13258

CAN driver has been added to the STM32 target since commit ae95137. As reported by @vincent-d it should be work with other STM32' CPUs

I'm trying to extend the support of priph_can to Nucleo-l476rg:

  1. STM32L476RG has only one CAN controller. It's mapped on

    • Arduino header CN5: CAN1_RD ( PB_8), CAN1_TX (PB_9)
    • Morpho left header CN10: CN5: CAN1_RD ( PA_11), CAN1_TX (PA_12)

    I chose to map the pins on the arduino header (CN5). The alternate function should be AF9 (take a look here to for its GPIO pin MUX)

  2. I'm using mcp2551 transceiver module, unfortunately, riot-os doesn't have its driver but I did a look to cf34161 42c5c40 and I should be able to add the missing driver for mcp2551.

  3. Goals:

    • I have a couple of Nucleo-l476rg and mcp2551 I would like to try to communicate with each other.
    • I new of RIOT-OS and I never worked with CAN before so I've two questions:
    1. I need the first comment about stm32's periph_can. (It seems to be ok, can list shows the registered can periph, )
    2. Supposing that my transceiver was one of two supported by Riot-os I don't understand how to configure it to make it working on my setup. I take I look here tests/can_trx but I don't understand how to "init code" must be integrated into my case.

thanks

This output is generated by these commits with example conn_can

> reboot
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
main(): This is RIOT! (Version: 2020.04-devel-842-g10af63-stm32l4_can_dev_MASTER)
0: launching receive_thread
1: launching receive_thread
RIOT-OS, MCU=stm32l4 Board=nucleo-l476rg
> ps
	pid | state    Q | pri 
	  1 | pending  Q |  15
	  2 | running  Q |   7
	  3 | bl rx    _ |   5
	  4 | bl rx    _ |   4
	  5 | bl rx    _ |   6
	  6 | bl rx    _ |   6
> help
Command              Description
---------------------------------------
test_can             Test CAN functions
reboot               Reboot the node
ps                   Prints information about running threads.
can                  CAN commands
> can list
CAN #0: can_stm32_0
>
> test_can power_up ifnum 0
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
DIS int (0) (0x20005a90)
> candev_stm32 0x20005a90: power down
turn off (0x20005a90)

> can                    
usage: can <command> [arguments]
commands:
	list
	send ifnum id [B1 .. B8]
	dump ifnum nb ms [id1[:mask1][,id2[:mask2], .. id10:[mask10]]
> can send 0 0x0
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
DIS int (0) (0x20005a90)
_send: candev=0x20005a90, frame=0x20003498
sce irq: error passive
sce irq: bus-off
sce irq: bus-off
...
...
....
sce irq: bus-off
sce irq: bus-off
sce irq: bus-off
tx irq
> sce irq: bus-off
candev_stm32 0x20005a90: power down
turn off (0x20005a90)

> 

@Ciusss89 Ciusss89 changed the title [WIP] [RCF] add CAN support for nucleo-l476rg [WIP] [RFC] add CAN support for nucleo-l476rg Mar 2, 2020
@PeterKietzmann PeterKietzmann added the Area: drivers Area: Device drivers label Mar 3, 2020
@PeterKietzmann
Copy link
Member

@JannesVolkens might be interested.

@JannesVolkens
Copy link
Contributor

Supposing that my transceiver was one of two supported by Riot-os I don't understand how to configure it to make it working on my setup. I take I look here tests/can_trx but I don't understand how to "init code" must be integrated into my case.

I’ve checked the reference manual for the mcp2551 transceiver and to me it seems like you do not actually need a driver to work with this transceiver. Pin 8 (RS) of the transceiver determines which mode the transceiver is operating in:

MCP

But I may be mistaken.

When running the test under tests/conn_can and typing in “test_can” the application should show you all the different commands you can use for this test.

@wosym
Copy link
Member

wosym commented Mar 3, 2020

I'm using mcp2551 transceiver module, unfortunately, riot-os doesn't have its driver but I did a look to cf34161 42c5c40 and I should be able to add the missing driver for mcp2551.

Are you sure you need a driver for that? As far as I understand it, the mcp2551 turns a digital can tx/rx into a can signal (canH/canL). It functions as an interface between the CAN-controller and the physical bus.
I've been using it for the past months on RIOT, and it worked without a hitch.

Unless you meant the mcp2515 ofcourse, which is an SPI can controller that is compatible with the mcp2551.

I have a PR ready for the mcp2515 drivermodule, but I'm still waiting for #13360 to be merged before I can open the mcp2515 PR.

@Ciusss89
Copy link
Contributor Author

Ciusss89 commented Mar 3, 2020

Supposing that my transceiver was one of two supported by Riot-os I don't understand how to configure it to make it working on my setup. I take I look here tests/can_trx but I don't understand how to "init code" must be integrated into my case.

I’ve checked the reference manual for the mcp2551 transceiver and to me it seems like you do not actually need a driver to work with this transceiver. Pin 8 (RS) of the transceiver determines which mode the transceiver is operating in:

MCP

But I may be mistaken.

When running the test under tests/conn_can and typing in “test_can” the application should show you all the different commands you can use for this test.

I'm using this transceiver.
According to table 1.1:
Screenshot from 2020-03-03 14-26-12
It operates in High-speed mode, there's a 4.7K resistor between RS pin and ground. (Irs = 0.7mA, and Vrs < 0.3Vdd )
I agree with you, In this case, the transceiver seems to be to work correctly as is.

My setup:

    NUCLEO-64      MCP2551      MCP2551      NUCLEO-64
PB_8 (CAN1_RD) <-->  CRX          CRX <--> PB_8 (CAN1_RD)
PB_9 (CAN1_TX) <-->  CTX          CTX <--> PB_9 (CAN1_TX)
                     CANH <----> CANH
                     CANL <----> CANL

I tested the CMDs provided by test_can example, but when I try to send a message it returns to me sce irq: bus-off and fails (check the snippet of PR ) other commands seem working

Any idea to help me to debug it? 🤓

@Ciusss89
Copy link
Contributor Author

Ciusss89 commented Mar 3, 2020

I'm using mcp2551 transceiver module, unfortunately, riot-os doesn't have its driver but I did a look to cf34161 42c5c40 and I should be able to add the missing driver for mcp2551.

Are you sure you need a driver for that? As far as I understand it, the mcp2551 turns a digital can tx/rx into a can signal (canH/canL). It functions as an interface between the CAN-controller and the physical bus.
I've been using it for the past months on RIOT, and it worked without a hitch.

Unless you meant the mcp2515 ofcourse, which is an SPI can controller that is compatible with the mcp2551.

I have a PR ready for the mcp2515 drivermodule, but I'm still waiting for #13360 to be merged before I can open the mcp2515 PR.

It's an mcp2551 (a transceiver only). Had you used an STM's mcu?

@Ciusss89
Copy link
Contributor Author

Ciusss89 commented Mar 3, 2020

I enabled the debug on STM32's can driver, I report here some test

test_can list : works.

> test_can list
CAN #0: can_stm32_0

test_can power_up 0 : It goes down after few seconds

 >reboot
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
main(): This is RIOT! (Version: 2020.04-devel-842-g10af63-stm32l4_can_dev_MASTER)
0: launching receive_thread
1: launching receive_thread
RIOT-OS, MCU=stm32l4 Board=nucleo-l476rg
> test_can power_up 0
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
> candev_stm32 0x20005a90: power down
turn off (0x20005a90)

test_can get_* works

> test_can get_filter 0
No filter set
> test_can get_bitrate 0
Bitrate read: bitrate=500000, sample_point=875
brp=5phase-seg1=3, phase-seg2=1, sjw=2
> 

test_can set_bitrate works

> test_can set_bitrate 0 1000000
Setting bitrate=1000000, sample point=0
turn on (0x20005a90)
DIS int (0) (0x20005a90)
turn off (0x20005a90)
Bittimings successfully set

test_can get_counter

> test_can get_counter 0
TEC=0, REC=0

Send doesn't work, all command about send fails with the same error.

test_can send_isotp 1 01 02 03 04 05 0a 0b 0c
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
DIS int (0) (0x20005a90)
_send: candev=0x20005a90, frame=0x20003498
sce irq: error passive
sce irq: bus-off
sce irq: bus-off
...
...
...
sce irq: bus-off
sce irq: bus-off
tx irq
sce irq: bus-off
Error when sending
> candev_stm32 0x20005a90: power down
turn off (0x20005a90)

@wosym
Copy link
Member

wosym commented Mar 4, 2020

It's an mcp2551 (a transceiver only). Had you used an STM's mcu?

No, I used an AVR. That's why I had to use the extra mcp2515. Because unlike the STM32 you are using, the AVR doesn't have an internal CAN periph.
Using the mcp2551 should not require an extra driver.

@JannesVolkens
Copy link
Contributor

Send doesn't work, all command about send fails with the same error.

Is your bus terminated by 120 ohm resistors at both ends of the bus between CAN high and CAN low? See https://en.wikipedia.org/wiki/CAN_bus#/media/File:CAN_ISO11898-2_Network.png

@Ciusss89
Copy link
Contributor Author

Ciusss89 commented Mar 4, 2020

Send doesn't work, all command about send fails with the same error.

Is your bus terminated by 120 ohm resistors at both ends of the bus between CAN high and CAN low? See https://en.wikipedia.org/wiki/CAN_bus#/media/File:CAN_ISO11898-2_Network.png

Maybe this is the problem, I don't terminate the bus. I'll do new attempt and I will update you

@wosym
Copy link
Member

wosym commented Mar 4, 2020

I can confirm that not terminating the bus will in most cases cause problems with the MCP2551. It really is not an optional thing.

@Ciusss89
Copy link
Contributor Author

Ciusss89 commented Mar 5, 2020

@JannesVolkens @wosym thanks for the suggestions. it works now!

On the first board.

> test_can send 0 0 1 2 34 44 55 66
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
DIS int (0) (0x20005a90)
_send: candev=0x20005a90, frame=0x20003498
sce irq: error warning
sce irq: error passive
tx irq
_tx_conf: device=0x20005a90, mb=0
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
> candev_stm32 0x20005a90: power down
turn off (0x20005a90)

On the second board.

main(): This is RIOT! (Version: 2020.04-devel-842-g10af63-stm32l4_can_dev_MASTER)
0: launching receive_thread
1: launching receive_thread
RIOT-OS, MCU=stm32l4 Board=nucleo-l476rg
> can dump ifnum 0 nb 0 ms 100 0
_set_filter: dev=0x20005a90, filter=0x0
candev_stm32 0x20005a90: power down
turn off (0x20005a90)
int wkup: 0x20005a90
candev_stm32 0x20005a90: power up
int wkup: 0x20005a90
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
DIS int (0) (0x20005a90)
sce irq: wakeup
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
rx irq
_rx_isr: device=0x20005a90
candev_stm32 0x20005a90: power up
turn on (0x20005a90)
can_stm32_0(0)        0  [6]  01 02 34 44 55 66
candev_stm32 0x20005a90: power down
turn off (0x20005a90)

I did two mistakes:

  • I had forgotten the null term resistor on the CAN bus
  • MCP2551 doesn't work with 3.3V

I fixed the commits to make Travis happy

@Ciusss89 Ciusss89 changed the title [WIP] [RFC] add CAN support for nucleo-l476rg Add CAN support for nucleo-l476rg Mar 5, 2020
@Ciusss89
Copy link
Contributor Author

ping: @PeterKietzmann @aabadie

I need a review,
Travis is happy while Murdock is Waiting...

@fjmolinas fjmolinas added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Mar 22, 2020
Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

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

Looks good, please squash right away with the suggested change to keep line size. I'll trigger murdock afterwise

cpu/stm32_common/include/candev_stm32.h Outdated Show resolved Hide resolved
@fjmolinas fjmolinas added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 22, 2020
Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

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

Documentation doesn't build properly, please apply these changes.

boards/nucleo-l476rg/doc.txt Outdated Show resolved Hide resolved
boards/nucleo-l476rg/doc.txt Show resolved Hide resolved
boards/nucleo-l476rg/doc.txt Show resolved Hide resolved
@Ciusss89 Ciusss89 requested a review from smlng as a code owner March 22, 2020 15:53
@Ciusss89
Copy link
Contributor Author

Documentation doesn't build properly, please apply these changes.

it's should be ok 🍺

Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

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

Documentation now builds correctly, changes make sense and test output has been posted in the PR. ACK

@fjmolinas fjmolinas merged commit 5ef0cb9 into RIOT-OS:master Mar 23, 2020
@fjmolinas
Copy link
Contributor

Thanks for the contribution @Ciusss89

@Ciusss89 Ciusss89 deleted the stm32l4_can_dev_MASTER branch March 23, 2020 18:43
@leandrolanzieri leandrolanzieri added this to the Release 2020.04 milestone Mar 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

STM32L4: CAN support
6 participants