Skip to content

Commit df636d3

Browse files
committed
drivers: can: mchp_mss: add control via KConfig of CAN_CONFIG.SWAP_ENDIAN bit
Default implementation of CAN driver for the Polarfire SoC inverts the byte ordering to write registers/from read registers due to platform endianness, possibly resulting in an unexpected behavior when considering the normal API usage of CAN. This adds KConfig support for forcing a configuration bit to be set, which will take care of reversing the byte order in hardware. Signed-off-by: Donato Brusamento <[email protected]>
1 parent a12ace0 commit df636d3

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

drivers/can/Kconfig.mchp_mss

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,18 @@ config CAN_MCHP_MSS
77
help
88
This option enables the CAN driver for Microchip's PolarFire SoC
99
platform.
10+
11+
if CAN_MCHP_MSS
12+
13+
config CAN_MCHP_MSS_SWAP_ENDIANNESS
14+
bool "Force little endian on transmit and receive buffers"
15+
help
16+
This option sets the SWAP_ENDIAN bit of CAN_CONFIG register.
17+
By setting this bit, the values of [TX|RX]_MSGx_DATA_[LOW|HIGH]
18+
will operate in little endian mode. For example, either field set
19+
to 0x01020304 will result in 0x01 -> 0x02 -> 0x03 -> 0x04 being written on the bus.
20+
21+
Conversely, when operating in the (default) big endian mode, the inverse
22+
sequence will be transmitted on the bus, i.e. in network order.
23+
24+
endif # CAN_MCHP_MSS

drivers/can/can_mchp_mss.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ static int mss_can_reset(const struct device *dev)
259259
{
260260
const struct mss_can_config *cfg = dev->config;
261261
uintptr_t reg_base = cfg->reg_base;
262+
uint32_t can_config;
262263

263264
#if MSS_CAN_RESET_ENABLED
264265
if (cfg->reset_spec.dev != NULL) {
@@ -269,6 +270,14 @@ static int mss_can_reset(const struct device *dev)
269270
mss_can_stop_and_disable_interrupts(reg_base);
270271
BUILD_ASSERT(MSS_CAN_TX_MSG_COUNT == MSS_CAN_RX_MSG_COUNT);
271272

273+
can_config = sys_read32(reg_base + MSS_CAN_CONFIG);
274+
#if CONFIG_CAN_MCHP_MSS_SWAP_ENDIANNESS
275+
can_config |= MSS_CAN_CFG_SWAP_ENDIAN;
276+
#else
277+
can_config &= ~MSS_CAN_CFG_SWAP_ENDIAN;
278+
#endif
279+
sys_write32(can_config, reg_base + MSS_CAN_CONFIG);
280+
272281
for (uintptr_t i = 0; i < MSS_CAN_TX_MSG_COUNT; ++i) {
273282
/* Clear transmit buffer */
274283
uintptr_t tx_msg_base = reg_base + MSS_CAN_TX_MSG(i);

0 commit comments

Comments
 (0)