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

drivers: spi: spi_rpi_pico_pio: Byte order is incorrect #72954

Open
ThreeEights opened this issue May 17, 2024 · 3 comments
Open

drivers: spi: spi_rpi_pico_pio: Byte order is incorrect #72954

ThreeEights opened this issue May 17, 2024 · 3 comments
Assignees
Labels
area: SPI SPI bus bug The issue is a bug, or the PR is fixing a bug platform: Raspberry Pi Pico Raspberry Pi Pico (RPi Pico) priority: low Low impact/importance bug

Comments

@ThreeEights
Copy link
Contributor

Describe the bug
The PIO-based SPI driver for the Raspberry Pi Pico (and the RP2040 in general) sends data out the SPI bus in the wrong byte order when SPI_WORD_SET() is 16 or 32 bits, and reverses the byte order of the input data. Data is passed to the SPI driver (tx buffer) in the byte order intended for transmission. However, the little-endian PIO SPI driver treats the data as 16- or 32-bit integers, loading the data into the transmit FIFO in the reverse of the correct order and not correcting the reversed data in the receive FIFO.

  • Target platform: Raspberry Pi Pico, Pico W (Probably affects other RP2040 platforms as well.)
  • Work-around: Modify calling code to re-order data (generally impractical, in my opinion).
  • Not a regression, bug in original code.

To Reproduce
Steps to reproduce the behavior:

  1. The only readily available device that supports SPI_WORD_SET(32) in Zephyr is the TI TMAG5170 sensor.
  2. Wire the TMAG5170 to the Raspberry Pi Pico (see "Additional context" for configuration).
  3. Build samples/sensor/magn_polling, adding the boards/rpi_pico.overlay provided below, with the command west build -p auto -b rpi_pico
  4. While monitoring the SPI bus, run the generated sample.

Observed behavior
The command to read the TEST_CONFIG register should be 0x8F000008, but is sent on the bus as 0x08 0x00 0x00 0x8F. The input line receives 0xE0 0x00 0x00 0x8B, but the status message delivered to the application is 0x8B0000E0. The TMAG5170 driver repeats the attempt to read the TEST_CONFIG register, never leaving the driver's init function.

Expected behavior
The data should be transmitted in the order provided, regardless of the CPU byte order: 0x8F 0x00 0x00 0x08, and the received data should be placed in the rx buffer in the order expected: 0xE0 0x00 0x00 0x8B.

Impact
The PIO SPI driver cannot operate correctly in either SPI_WORD_SET(16) or SPI_WORD_SET(32) configurations.

Logs and console output
Data as exchanged on the SPI bus (first two 32-bit exchanges):

Time [s],Packet ID,MOSI,MISO
0.0000392500,0,0x08,0xE0
0.0000472500,0,0x00,0x00
0.0000552500,0,0x00,0x00
0.0000632500,0,0x8F,0x8B
0.0000892500,0,0x08,0xE0
0.0000972500,0,0x00,0x00
0.0001052500,0,0x00,0x00
0.0001132500,0,0x8F,0x8B

Environment (please complete the following information):

  • OS: Linux (Ubuntu 22.04.4 LTS)
  • Toolchain: Zephyr SDK
  • Commit SHA: 5409c7c

Additional context
boards/rpi_pico.overlay used to build sample:

/ {
	aliases {
		magn0 = &tmag5170;
	};
};

&pinctrl {
	pio0_spi0_default: pio0_spi0_default {
		/* gpio 9 is used for chip select, not assigned to the PIO */
		group1 {
			pinmux = <PIO0_P10>, <PIO0_P11>;
		};
		group2 {
			pinmux = <PIO0_P8>;
			input-enable;
		};
	};

};

&pio0 {
 	status = "okay";

	pio0_spi0: pio0_spi0 {
		pinctrl-0 = <&pio0_spi0_default>;
		pinctrl-names = "default";

		compatible = "raspberrypi,pico-spi-pio";
		status = "okay";
		#address-cells = <1>;
		#size-cells = <0>;
		clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>;
		miso-gpios = <&gpio0 8 0>;
		cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
		clk-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
		mosi-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
		tmag5170: tmag5170@0 {
			compatible = "ti,tmag5170";
			reg = <0>;
			operating-mode = <3>;
			spi-max-frequency = <1000000>; /* conservatively set to 1MHz */
		};
	};
};

TMAG5170 connections to RPI Pico:

  • CS to GPIO 9
  • CLK to GPIO 10
  • MOSI to GPIO 11
  • MISO to GPIO 8
@ThreeEights ThreeEights added the bug The issue is a bug, or the PR is fixing a bug label May 17, 2024
@ThreeEights
Copy link
Contributor Author

@morsisko - Feel free to comment on this issue.

@MaureenHelm MaureenHelm added the platform: Raspberry Pi Pico Raspberry Pi Pico (RPi Pico) label May 17, 2024
@nashif nashif added the priority: low Low impact/importance bug label May 21, 2024
@morsisko
Copy link
Contributor

morsisko commented May 28, 2024

Hello, sorry for late response. When I was designing the driver I was using mainly ESP32 SPI driver. I also encountered bugs described here: #54746

ESP32 driver send bytes as they are in the buffer (so that byte[0] will be sent first on the SPI, then byte[1] and so on). I don't know if it is correct behavior or not, however definitely there needs to be some kind of agreement about the byte order between different SPI drivers.

@ThreeEights
Copy link
Contributor Author

@morsisko - Thanks. I think I have the Pico PIO SPI driver working that way, too. It seems like a sensible convention: Send the bytes in the order in the buffer, whether sending 8, 16, or 32 bytes in a transaction. Once I have a pull request ready we should be able to close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: SPI SPI bus bug The issue is a bug, or the PR is fixing a bug platform: Raspberry Pi Pico Raspberry Pi Pico (RPi Pico) priority: low Low impact/importance bug
Projects
None yet
Development

No branches or pull requests

6 participants