Increase Shell buffer size for 64 bytes payload length of CAN FD frame.
This also implies to increase main thread stack size and especially for
native architectures.
Add two new sub-commands to test_can command:
* fdsend: to send a CAN FD frame
* fdsendrtr: to send a CAN FD RTR frame (payload length = 0).
Signed-off-by: Gilles DOFFE <gilles.doffe@rtone.fr>
As CAN FD is already supported by SocketCAN on Linux, just enable the
fdcan pseudomodule and allow CAN FD frames.
Signed-off-by: Gilles DOFFE <gilles.doffe@rtone.fr>
Until now, STM32 MCUs classic CAN support is coded in can.c file.
However CAN FD in STM32G4 family is designed in a very different way:
* CAN FD channels are independant
* CAN FD channel configuration is done in a dedicated RAM block called
message RAM, with one message RAM per channel
* Each message RAM is divided this way:
- 11-bit filter (28 elements / 28 words)
- 29-bit filter (8 elements / 16 words)
- Rx FIFO 0 (3 elements / 54 words)
- Rx FIFO 1 (3 elements / 54 words)
- Tx event FIFO (3 elements / 6 words)
- Tx buffers (3 elements / 54 words)
Due to these design differences with other STM32 MCUs, the choice is
made to split the driver in two files:
* classiccan.c for STM32 MCUs that support classical CAN. This file
has just been renamed (previously can.c) to avoid build conflicts
but does not introduce changes
* fdcan.c for STM32 MCUs that support CAN FD
Message RAM definitions is not provided in CMSIS headers of the STM32G4
family, they are defined in fdcandev_stm32.h. Those definitions could be
extracted to a new file for each STM32 families as some differences
exist with other STM32 families that support CAN FD (for instance
STM32H7). This could be done in a futher commit, according to new
families requirements.
CAN hardware parameters stay similar and are kept in can_params.h.
There are 36 filters per channel:
* 28 first filters are standard ID (11 bit) filters
* 8 last filters are extended ID (29 bit) filters
On each Tx frame sent, the STM32G4 can store Tx events in a dedicated
FIFO. This feature is not yet implemented and Tx event FIFO is disabled
by default.
Automatic retransmission on arbitration loss is enabled by default by
the STM32G4.
About Rx, if no filter is configured, all frames are accepted by
default.
Signed-off-by: Gilles DOFFE <gilles.doffe@rtone.fr>
During the data phase of a FDCAN transmission only one node is
transmitting, all others are receivers. The length of the bus line has
no impact.
When transmitting via pin FDCAN_TX the protocol controller receives the
transmitted data from its local CAN transceiver via pin FDCAN_RX. The
received data is delayed by the CAN transceiver loop delay.
If this delay is greater than TSEG1 (time segment before sample point),
a bit error is detected. Without transceiver delay compensation, the bit
rate in the data phase of a FDCAN frame is limited by the transceiver's
loop delay.
Since this parameter is related to the transceiver used, there cannot be
a default value, and it must be explicitly defined with the
configuration variable CONFIG_FDCAN_DEVICE_TRANSCEIVER_LOOP_DELAY.
Signed-off-by: Gilles DOFFE <gilles.doffe@rtone.fr>
Add CAN FD specifities to CAN system library in RIOT:
* 64 bytes payload
* Bit rate switching
* Error State Indicator
Signed-off-by: Gilles DOFFE <gilles.doffe@rtone.fr>
Whole CAN code in RIOT is using 'struct can_frame' to represent a CAN
frame.
However incoming CAN FD support will bring 'struct canfd_frame' to
represent CAN FD frames.
Even if the 'struct canfd_frame' has additional flags and a bigger
payload, it is aligned on 'struct can_frame' and thus they can be
referenced by the same pointers in the code.
As it is impossible to predict which one will be used in RIOT, just
define a new type 'can_frame_t' which will map to the right struct
according to the MCU CAN supported format.
Signed-off-by: Gilles DOFFE <gilles.doffe@rtone.fr>
RIOT implementation of CAN bus relies on SocketCAN model.
Since commit c398e56 (can: add optional DLC element to Classical CAN
frame structure), '__u8 can_dlc' attribute of struct can_frame is
considered as deprecated in SocketCAN and kept for legacy support.
Attribute '__u8 len' should be used instead.
union {
/* CAN frame payload length in byte (0 .. CAN_MAX_DLEN)
* was previously named can_dlc so we need to carry that
* name for legacy support
*/
__u8 len;
__u8 can_dlc; /* deprecated */
};
Moreover, CAN FD frame structure does not support legacy attribute
'can_dlc', making 'len' mandatory for incoming CAN FD support in RIOT.
struct canfd_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 len; /* frame payload length in byte */
__u8 flags; /* additional flags for CAN FD */
__u8 __res0; /* reserved / padding */
__u8 __res1; /* reserved / padding */
__u8 data[CANFD_MAX_DLEN]
__attribute__((aligned(8)));
};
Signed-off-by: Gilles DOFFE <gilles.doffe@rtone.fr>
Previously the corner case when RFC 8974 extended TKL fields are used
the result of coap_get_totel_hdr_len() was not tested, resulting in a
bug slipping through the test. This increase the test coverage.
Since https://github.com/RIOT-OS/RIOT/pull/20935 gpio_write()
uses a `bool` instead of an `int`. This does the same treatment for
`gpio_read()`.
This does indeed add an instruction to `gpio_read()` implementations.
However, users caring about an instruction more are better served with
`gpio_ll_read()` anyway. And `gpio_read() == 1` is often seen in
newcomer's code, which would now work as expected.
This adds the board specification of the Adafruit Metro M4 Express [1].
The significance of this board is that it is compatible with both
classical SPI Arduino Shields using the ISP header for SPI
(such as `shield_w5100`) and more recent shields using D11/D12/D13 as
SPI (such as `shield_llcc68`).
[1]: https://learn.adafruit.com/adafruit-metro-m4-express-featuring-atsamd51/overview
If the timer at the head of a ztimer clock's timer list is re-scheduled
(ztimer_set() called on an already set timer) and the timer is no longer
at the head after being re-scheduled, clock-ops->set() is never called
from inside ztimer_set(), and the underlying timer is left with an ISR
scheduled to expire at the timer's old time. The intended behavior is
that the clock's lower level timer should always be set to expire at the
time of the clocks head timer.
This patch changes ztimer_set() to call _ztimer_update(), which sets the
lower level timer according to the current list of timers, rather than
setting the timer directly inside of ztimer_set().