Skip to content

drivers: sensor: tmag5170 — “fixed 32-bit SPI frame” is not SPI_WORD_SET(32); on STM32U5/N657 SPI_WORD_SET(32) causes byte packing/byte order issues, SPI_WORD_SET(8) works #103615

@bernhardrtr

Description

@bernhardrtr

Summary

TMAG5170 datasheet specifies a fixed 32-bit SPI frame (32 SCK pulses while CS is held low). The TMAG5170 driver is implemented as a single 4-byte (uint8_t[4]) transceive, which already satisfies the 32-bit frame requirement on the wire.

On STM32 targets, configuring SPI_WORD_SET(32) results in correct bus activity but incorrect semantics (likely byte order/packing), while SPI_WORD_SET(8) works reliably.

Related attempt: #97327


Repro / Observation

  • SPI_WORD_SET(8) → driver works, correct values
  • SPI_WORD_SET(32) → transfers happen and data arrives, but appears byte-swapped/packed differently, so the driver interprets it incorrectly

Why SPI_WORD_SET(8) is correct/portable

The driver uses byte-framed buffers:

uint8_t buffer_tx[4] = { BIT(7) | reg, 0x00U, 0x00U, (cmd & 0x0F) << 4 };
uint8_t buffer_rx[4] = { 0 };
spi_transceive_dt(&config->bus, &tx, &rx);

It decodes response bytes by fixed indexes:

*output = (buffer_rx[1] << 8) | buffer_rx[2];

CRC nibble placement assumes the 4th byte is the last byte on the wire:

#define TMAG5170_SET_CRC(buf, crc) ((uint8_t *)(buf))[3] |= (crc & 0x0F)
#define TMAG5170_ZERO_CRC(buf) ((uint8_t *)(buf))[3] &= 0xF0

With SPI_WORD_SET(32), the effective byte order of that 4-byte frame becomes controller-driver dependent (packing/endianness/chunking), which can vary across SoCs. Using SPI_WORD_SET(8) keeps the wire byte sequence aligned with the driver’s uint8_t[4] layout by construction.

Note: the datasheet’s “32-bit frame” requirement is satisfied by 4×8-bit transfers as long as CS stays asserted for 32 SCK pulses.


Proposal

  • Clarify in driver docs/Kconfig help that “32-bit frame” refers to 32 clocks under CS, not 32-bit SPI word size
  • Default/recommend SPI_WORD_SET(8) for TMAG5170 to avoid controller-dependent packing surprises
  • If 32-bit word size must be supported, driver would need explicit pack/unpack with defined endianness, but portability may still be limited

Regression

  • This is a regression.

Steps to reproduce

No response

Relevant log output

Impact

Major – Severely degrades functionality; workaround is difficult or unavailable.

Environment

  • Zephyr commit: 8238dd8
  • Boards: nucleo_u5a5zj_q, nucleo_n657x0_q
  • Bus: SPI1 @ 5 MHz
  • Sensor: TI TMAG5170 (4-wire SPI)

Additional Context

No response

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions