-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add CAN support for STM32L4KC #16516
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
base: master
Are you sure you want to change the base?
Conversation
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.
Hello @LightDestory and thank you for your first PR welcome to The NuttX Club :-)
We have automated CI verification for each PR, including build and code formatting, all checks must pass to unblock merge.
I can see formatting needs some update. Please take a look at:
- https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md
- https://nuttx.apache.org/docs/latest/contributing/index.html
Please update git commit message:
- topic
boards/nucleo-l432kc: add can support and configuration.
- please add some short description to the commit so people reading the
git log
will know what/why happened here :-)
All three sections of the PR are mandatory (Summary, Impact, Testing). Please update :-)
- Impact - adds CAN support to nucleo-l432kc board and dedicated configuration where CAN is enabled so it is available out of the box for testing.
- Testing - this is very important to show the patch that you provide works and was tested, you can provide build log essentials + testing logs (text preferred).
Added support of CAN so the CAN example can be compiles out-of-the-box without any modification. Added "nucleo-l432kc:can" config.
5887e50
to
f4ad320
Compare
Thanks for your review. I tried to meet all the requirements. |
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.
Thanks @LightDestory :-)
Still some minor formatting issue (see Check CI logs it complains about blank line). You can test on local machine two ways:
./tools/checkpatch.sh -g HEAD~...HEAD
./tools/checkpatch.sh -f path/to/your/file.c
It would be nice if you also provided runtime logs showing that CAN works :-) For me it fails to poen /dev/can0
but I only have one board with no CAN network attached - is this the problem?
nsh> uname -a
NuttX 10.4.0 f4ad320a86 Jun 12 2025 00:45:58 arm nucleo-l432kc
nsh> help
help usage: help [-v] [<cmd>]
. cd exit mkrd sleep unset
[ cp expr mount source uptime
? cmp false mv test usleep
alias dirname help printf time watch
unalias date hexdump pwd true xd
basename dmesg kill rm truncate
break echo ls rmdir uname
cat exec mkdir set umount
Builtin Apps:
alarm can dd nsh ostest rand sh
nsh> can
nmsgs: 0
min ID: 1 max ID: 2047
ERROR: open /dev/can0 failed: 110
Terminating!
nsh> ls /dev
/dev:
can0
console
null
random
rtc0
ttyS0
zero
I also noticed some build warnings in chip/stm32l4_can.c
we may want to fix one day (can be separate PR) :-)
% gmake -j24
Create version.h
LN: platform/board to /XXX/nuttx/pr/nuttx-apps.git/platform/dummy
Register: rand
Register: alarm
Register: dd
Register: nsh
Register: ostest
Register: sh
Register: can
CC: obstack/lib_obstack_grow.c chip/stm32l4_gpio.c:46:11: note: '#pragma message: CONFIG_STM32L4_USE_LEGACY_PINMAP will be deprecated migrate board.h see tools/stm32_pinmap_tool.py'
46 | # pragma message "CONFIG_STM32L4_USE_LEGACY_PINMAP will be deprecated migrate board.h see tools/stm32_pinmap_tool.py"
| ^~~~~~~
CC: obstack/lib_obstack_room.c In file included from chip/stm32l4_rcc.c:47:
chip/stm32l4x3xx_rcc.c: In function 'stm32l4_stdclockconfig':
chip/stm32l4x3xx_rcc.c:699:2: warning: #warning todo: regulator voltage according to clock freq [-Wcpp]
699 | #warning todo: regulator voltage according to clock freq
| ^~~~~~~
In file included from chip/stm32l4_can.c:35:
chip/stm32l4_can.c: In function 'stm32l4can_ioctl':
chip/stm32l4_can.c:880:19: warning: format '%d' expects argument of type 'int', but argument 5 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
880 | caninfo("TS1: %d TS2: %d BRP: %d\n",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
881 | bt->bt_tseg1, bt->bt_tseg2, brp);
| ~~~
| |
| uint32_t {aka long unsigned int}
chip/stm32l4_can.c:880:42: note: format string is defined here
880 | caninfo("TS1: %d TS2: %d BRP: %d\n",
| ~^
| |
| int
| %ld
chip/stm32l4_can.c: In function 'stm32l4can_remoterequest':
chip/stm32l4_can.c:1139:2: warning: #warning "Remote request not implemented" [-Wcpp]
1139 | #warning "Remote request not implemented"
| ^~~~~~~
chip/stm32l4_can.c: In function 'stm32l4can_txready':
chip/stm32l4_can.c:1335:11: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
1335 | caninfo("CAN%d TSR: %08x\n", priv->port, regval);
| ^~~~~~~~~~~~~~~~~~~ ~~~~~~
| |
| uint32_t {aka long unsigned int}
chip/stm32l4_can.c:1335:26: note: format string is defined here
1335 | caninfo("CAN%d TSR: %08x\n", priv->port, regval);
| ~~~^
| |
| unsigned int
| %08lx
chip/stm32l4_can.c: In function 'stm32l4can_txempty':
chip/stm32l4_can.c:1366:11: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
1366 | caninfo("CAN%d TSR: %08x\n", priv->port, regval);
| ^~~~~~~~~~~~~~~~~~~ ~~~~~~
| |
| uint32_t {aka long unsigned int}
CC: pthread/pthread_attr_getscope.c chip/stm32l4_can.c:1366:26: note: format string is defined here
1366 | caninfo("CAN%d TSR: %08x\n", priv->port, regval);
| ~~~^
| |
| unsigned int
| %08lx
chip/stm32l4_can.c: In function 'stm32l4can_bittiming':
chip/stm32l4_can.c:1685:11: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]
1685 | caninfo("CAN%d PCLK1: %d baud: %d\n",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
chip/stm32l4_can.c:1685:26: note: format string is defined here
1685 | caninfo("CAN%d PCLK1: %d baud: %d\n",
| ~^
| |
| int
| %ld
chip/stm32l4_can.c:1685:11: warning: format '%d' expects argument of type 'int', but argument 5 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
1685 | caninfo("CAN%d PCLK1: %d baud: %d\n",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
1686 | priv->port, STM32L4_PCLK1_FREQUENCY, priv->baud);
| ~~~~~~~~~~
| |
| uint32_t {aka long unsigned int}
CC: common/arm_modifyreg.c chip/stm32l4_can.c:1685:35: note: format string is defined here
1685 | caninfo("CAN%d PCLK1: %d baud: %d\n",
| ~^
| |
| int
| %ld
chip/stm32l4_can.c:1738:11: warning: format '%d' expects argument of type 'int', but argument 3 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
1738 | caninfo("TS1: %d TS2: %d BRP: %d\n", ts1, ts2, brp);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~
| |
| uint32_t {aka long unsigned int}
chip/stm32l4_can.c:1738:18: note: format string is defined here
1738 | caninfo("TS1: %d TS2: %d BRP: %d\n", ts1, ts2, brp);
| ~^
| |
| int
| %ld
chip/stm32l4_can.c:1738:11: warning: format '%d' expects argument of type 'int', but argument 4 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
1738 | caninfo("TS1: %d TS2: %d BRP: %d\n", ts1, ts2, brp);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~
| |
| uint32_t {aka long unsigned int}
chip/stm32l4_can.c:1738:26: note: format string is defined here
1738 | caninfo("TS1: %d TS2: %d BRP: %d\n", ts1, ts2, brp);
| ~^
| |
| int
| %ld
chip/stm32l4_can.c:1738:11: warning: format '%d' expects argument of type 'int', but argument 5 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
1738 | caninfo("TS1: %d TS2: %d BRP: %d\n", ts1, ts2, brp);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~
| |
| uint32_t {aka long unsigned int}
chip/stm32l4_can.c:1738:34: note: format string is defined here
1738 | caninfo("TS1: %d TS2: %d BRP: %d\n", ts1, ts2, brp);
| ~^
| |
| int
| %ld
chip/stm32l4_can.c: In function 'stm32l4can_exitinitmode':
chip/stm32l4_can.c:1857:14: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
1857 | canerr("ERROR: Timed out waiting to exit initialization mode: %08x\n",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1858 | regval);
| ~~~~~~
| |
| uint32_t {aka long unsigned int}
chip/stm32l4_can.c:1857:72: note: format string is defined here
1857 | canerr("ERROR: Timed out waiting to exit initialization mode: %08x\n",
| ~~~^
| |
| unsigned int
| %08lx
LD: nuttx
Memory region Used Size Region Size %age Used
flash: 229212 B 256 KB 87.44%
sram: 9912 B 64 KB 15.12%
CP: nuttx.hex
CP: nuttx.bin
I have converted the PR to draft, I will provide text logs of the CAN as soon as I get my hands on the board itself. Regarding the warnings, I just took as reference the can implementation for the l476rg. |
Thank you :-) In a perfect situation we want to include code that is already verified on a real world hardware. I know this is copy-paste from similar MCU but there may be slight differences that will not allow exact same code to work on different MCU (happened to me recently with stm32) :-)
It would be nice to update the existing code as well when you know it already and there are known issues :-) This fix updates may come already in this PR as part of L432 but then you will have copy-paste for L476 :-) Thanks again @LightDestory :-) |
@@ -226,7 +226,7 @@ int stm32_bringup(void) | |||
|
|||
#ifdef CONFIG_CAN | |||
/* Initialize CAN and register the CAN device. */ | |||
|
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.
let's squash into one patch
@LightDestory same issue that @cederom pointed early. The issue was not caused by you, but the CI detected that stm32l4_can.c in arch/ has some printing error. Replace %d from those variables that are unsigned int with %u or %" PRIu32 ".
|
Summary
Nucleo-L432KC provides a CAN1 interface, but the current NuttX configuration misses both the PINs declaration and the setup definition.
Impact
This PR aims to add CAN support to the nucleo-l432kc board and a dedicated configuration where CAN is enabled, so it is available out of the box for testing.
Testing
Trying to compile with the following configuration: CAN1 enabled, CAN Driver enabled, CAN example enabled.


Before PR:
After PR: