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_mcux_lpspi: inconsistent chip select behaviour #16544

Open
henrikbrixandersen opened this issue Jun 2, 2019 · 12 comments
Open
Assignees
Labels
area: GPIO area: SPI SPI bus bug The issue is a bug, or the PR is fixing a bug platform: NXP Drivers NXP Semiconductors, drivers platform: NXP NXP priority: low Low impact/importance bug

Comments

@henrikbrixandersen
Copy link
Member

Describe the bug
The MCUX LPSPI SPI driver handles SPI chip selects inconsistently when comparing GPIO CS and "native" controller CS handling over multipart transfers.

With GPIO CS enabled (where the LPSPI controller does not control the CS line), the CS line is kept asserted through the entire transfer. This is opposed to what happens when the CS line is controlled by the LPSPI controller itself; then the CS line is deasserted between the different parts of the transfer.

To Reproduce

#include <zephyr.h>
#include <misc/printk.h>
#include <spi.h>

#define SPI_LABEL     "SPI_1"
#define GPIO_CS_LABEL "GPIO_0"
#define GPIO_CS_PIN   16

void main(void)
{
	struct spi_config spi_cfg;
	struct device *spi_dev;
	struct spi_cs_control spi_cs;
	u8_t cmd[2] = { 0xaa, 0x55 }; /* 2 bytes command */
	u8_t response[2];             /* 2 bytes response */

	const struct spi_buf tx_bufs[] = {
		{
			.buf = cmd,
			.len = sizeof(cmd),
		},
	};
	const struct spi_buf_set tx = {
		.buffers = tx_bufs,
		.count = ARRAY_SIZE(tx_bufs),
	};
	const struct spi_buf rx_bufs[] = {
		{
			.buf = NULL,
			.len = sizeof(cmd), /* 2 dummy bytes */
		},
		{
			.buf = response,
			.len = sizeof(response),
		},
	};
	const struct spi_buf_set rx = {
		.buffers = rx_bufs,
		.count = ARRAY_SIZE(rx_bufs),
	};

	spi_dev = device_get_binding(SPI_LABEL);
	if (!spi_dev) {
		printk("SPI device not found\n");
		return;
	}

	spi_cfg.operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB |
		SPI_WORD_SET(8);
	spi_cfg.frequency = 1000000;
	spi_cfg.slave = 2;

#if 0
	spi_cs.gpio_dev = device_get_binding(GPIO_CS_LABEL);
	if (!spi_cs.gpio_dev) {
		printk("SPI GPIO CS device not found\n");
		return;
	}
	spi_cs.gpio_pin = GPIO_CS_PIN;
	spi_cs.delay = 1; /* us */
	spi_cfg.cs = &spi_cs;
#else
	spi_cfg.cs = NULL;
#endif

	spi_transceive(spi_dev, &spi_cfg, &tx, &rx);
}

Expected behavior
The CS line remains asserted through all the parts of the multipart transfer.

Impact
Deasserting the CS line in the middle of a transfer causes problem e.g. when communicating with SPI EEPROMs.

Screenshots or console output
When using GPIO CS:
GPIO CS

When using LPSPI CS:
SPI CS

Environment (please complete the following information):

  • OS: GNU/Linux
  • Toolchain Zephyr SDK
  • Commit SHA or Version used: c88c919

Additional context
This was spotted when trying to use a SPI EEPROM with the TWR-KE18F board, but it is not limited to that board nor to the KE1xF SoC series, as far as I can tell.

@henrikbrixandersen henrikbrixandersen added bug The issue is a bug, or the PR is fixing a bug area: SPI SPI bus platform: NXP NXP labels Jun 2, 2019
@nashif nashif added the priority: medium Medium impact/importance bug label Jun 4, 2019
@ioannisg
Copy link
Member

@MaureenHelm is this issue being looked at?

@MaureenHelm
Copy link
Member

@MaureenHelm is this issue being looked at?

Not yet, but going to try to look at it tomorrow.

@MaureenHelm
Copy link
Member

This is caused by the underlying MCUX SDK LPSPI driver missing a feature to hold the chip select active after a transfer. The underlying MCUX SDK DSPI driver used on frdm_k64f has a kDSPI_MasterActiveAfterTransfer flag that we need in the LPSPI driver used on KE1xF and i.MX RT10xx. I will file an internal NXP ticket to add this feature.

Decreasing the priority of this bug from medium to low since we can work around it with GPIO CS.

@MaureenHelm MaureenHelm added priority: low Low impact/importance bug and removed priority: medium Medium impact/importance bug labels Aug 28, 2019
@henrikbrixandersen
Copy link
Member Author

This is still an issue with the most recent MCUX SDK (I was just bitten by this issue on bringing up a newly developed board today). Should we change all affected in-tree boards to use cs-gpios until this is resolved?

@agansari
Copy link
Collaborator

@henrikbrixandersen i've encountered similar issues with SPI on LPC55xxx, see my 2 pulls:

@pdgendt
Copy link
Collaborator

pdgendt commented May 17, 2023

Re-opening after discord discussion, as this issue is still relevant.

@pdgendt pdgendt reopened this May 17, 2023
@pdgendt pdgendt assigned decsny and unassigned MaureenHelm May 17, 2023
@decsny decsny removed the Stale label May 17, 2023
@aedancullen
Copy link
Contributor

aedancullen commented May 18, 2023

If CONFIG_SPI_MCUX_FLEXCOMM_DMA=y, this issue also appears with the spi_mcux_flexcomm driver.

(If CONFIG_SPI_MCUX_FLEXCOMM_DMA is not enabled, then spi_mcux_flexcomm has correct CS behavior regardless of whether GPIO or hardware CS is used.)

@github-actions github-actions bot added the Stale label Jul 18, 2023
@pdgendt pdgendt removed the Stale label Jul 18, 2023
@github-actions github-actions bot added the Stale label Sep 17, 2023
@DerekSnell DerekSnell removed the Stale label Sep 18, 2023
@zephyrproject-rtos zephyrproject-rtos deleted a comment from github-actions bot Sep 18, 2023
@zephyrproject-rtos zephyrproject-rtos deleted a comment from github-actions bot Sep 18, 2023
@zephyrproject-rtos zephyrproject-rtos deleted a comment from github-actions bot Sep 18, 2023
@zephyrproject-rtos zephyrproject-rtos deleted a comment from github-actions bot Sep 18, 2023
@zephyrproject-rtos zephyrproject-rtos deleted a comment from github-actions bot Sep 18, 2023
Copy link

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

@github-actions github-actions bot added the Stale label Nov 18, 2023
@dleach02 dleach02 removed the Stale label Nov 21, 2023
Copy link

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

Copy link

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

@github-actions github-actions bot added the Stale label Mar 24, 2024
@decsny decsny removed the Stale label Mar 25, 2024
@decsny
Copy link
Member

decsny commented Apr 11, 2024

I produced this code to try to reproduce the issue on mimxrt1024_evk on commit b573f44 based on what was originally posted by @henrikbrixandersen :

#include <zephyr/kernel.h>
#include <stdio.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/util.h>

struct spi_config spi_cfg = SPI_CONFIG_DT(DT_NODELABEL(dummy_spi_dev),
		(SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8)), 1);

const struct device *spi_ctlr = DEVICE_DT_GET(DT_NODELABEL(lpspi1));

#define XFER_SIZE 2

uint8_t cmd[XFER_SIZE] = {0xaa, 0x55};
uint8_t resp[XFER_SIZE];

const struct spi_buf tx_bufs[] = {
	{
		.buf = cmd,
		.len = sizeof(cmd),
	},
};

const struct spi_buf_set tx = {
	.buffers = tx_bufs,
	.count = ARRAY_SIZE(tx_bufs),
};

const struct spi_buf rx_bufs[] = {
	{
		.buf = NULL,
		.len = sizeof(cmd),
	},
	{
		.buf = resp,
		.len = sizeof(resp),
	},
};

const struct spi_buf_set rx = {
	.buffers = rx_bufs,
	.count = ARRAY_SIZE(rx_bufs),
};

int main(void)
{
	if (!spi_ctlr) {
		printf("SPI device not found");
		return 1;
	};

	if (!spi_cfg.cs.gpio.port) {
		printf("Using native CS\n");
	} else {
		printf("Using GPIO CS\n");
	}

	spi_transceive(spi_ctlr, &spi_cfg, &tx, &rx);

	printf("Transmission finished.\n");

	return 0;
}

With DT overlay

#include <zephyr/dt-bindings/gpio/gpio.h>
#include <zephyr/dt-bindings/spi/spi.h>

&pinmux_lpspi1 {
		group0 {
			pinmux =
				<&iomuxc_gpio_ad_b0_11_gpio1_io11>,
				<&iomuxc_gpio_ad_b0_10_lpspi1_sck>,
				<&iomuxc_gpio_ad_b0_11_lpspi1_pcs0>,
				<&iomuxc_gpio_ad_b0_12_lpspi1_sdo>,
				<&iomuxc_gpio_ad_b0_13_lpspi1_sdi>;
			drive-strength = "r0-6";
			slew-rate = "slow";
			nxp,speed = "100-mhz";
		};
};

&lpspi1 {
	cs-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
	dummy_spi_dev: dummy_spi_dev@0 {
		compatible = "spi-device";
		reg = <0>;
		duplex = <SPI_FULL_DUPLEX>;
		spi-max-frequency = <100000>;
 	};
};

And I observed the behavior to be the same whether or not the cs-gpios property was commented out of the DT or not. The behavior of both versions being that the CS is deasserted between the parts of the transfer.

Please someone who had this issue please confirm if I missed something in this code or if the behavior did indeed change in the last 5 years, or maybe the issue is specific to only some platforms

@henrikbrixandersen
Copy link
Member Author

Please someone who had this issue please confirm if I missed something in this code or if the behavior did indeed change in the last 5 years, or maybe the issue is specific to only some platforms

I can try to reproduce this when I return from Seattle. My original finding was on the twr_ke18f board.

@decsny decsny added platform: NXP Drivers NXP Semiconductors, drivers area: GPIO labels Apr 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: GPIO area: SPI SPI bus bug The issue is a bug, or the PR is fixing a bug platform: NXP Drivers NXP Semiconductors, drivers platform: NXP NXP priority: low Low impact/importance bug
Projects
None yet
Development

No branches or pull requests