Manual control of dedicated SPI CS?

Hi Guys,
I’m wondering if it is possible to manually control the hardware SPI Chip Select pin instead of them being controlled by the hardware?

I wish to use the SPI peripheral in Master mode and manually control the Chip Select level.

More specifically I’m interested in controlling SPI2_CS0# which is pin G16 (Tegra SPI1_CS0) - I see in the pin mux that this pin has no GPIO3 configuration possible and only SFIO2 being SPI1_CS0.

My end goal is to be able to do something like this pseudo code:

SPI2_CS_Pin = 0;

ioctl(file_spi, SPI_IOC_MESSAGE(1), &xfer_spi);
… do some processing and waiting required by the slave device…
ioctl(file_spi, SPI_IOC_MESSAGE(1), &xfer_spi);

SPI2_CS_Pin = 1;

Thanks for any advice you can offer.

Regards
Lasse

Why need manual control?
The chip select will be assert/deassert automatic when access the SPI device.

Hi @ShaneCCC

The device I’m talking to is made so that I need to keep CS asserted (low) between the transfers.

The “problem” is that I first have to send say 20 bytes and then depending on the response on MISO while sending these I have to send another 20 bytes which are depending on the result of the first - trouble is that I must keep CS asserted during this entire ordeal and only release it once I have all the bytes.

I saw that the SPI peripheral in the Tegra reference manual supports controlling the CS line by software using the bits:

CS_SW_HW and CS_SW_VAL

I’m just wondering if there’s support for it somehow?

Regards
Lasse

After consult with developer Jetson doesn’t support to control CS externally. We can use sw cs mode but only driver has control over it.

Hi @ShaneCCC

Thanks for checking!

Can you tell me (or point me to) how one can use sw cs mode using the before mentioned driver?

Regards
Lasse

You can check the source of …/kernel/nvidia/drivers/spi/spi-tegra114.c

Could it be cs_change that we need? The doc says:

(ii) When the transfer is the last one in the message, the chip may
* stay selected until the next transfer.  On multi-device SPI busses
* with nothing blocking messages going to other devices, this is just
* a performance hint; starting a message to another device deselects
* this one.  But in other cases, this can be used to ensure correctness.
* Some devices need protocol transactions to be built from a series of
* spi_message submissions, where the content of one message is determined
* by the results of previous messages and where the whole transaction
* ends when the chipselect goes inactive.

I see the driver seems to support it:

    		if (is_single_xfer && !(t->cs_change)) {
    			tspi->use_hw_based_cs = true;
    			command1 &= ~(SPI_CS_SW_HW | SPI_CS_SW_VAL);
    		} else {
    			tspi->use_hw_based_cs = false;
    			command1 |= SPI_CS_SW_HW;
    			if (spi->mode & SPI_CS_HIGH)
    				command1 |= SPI_CS_SW_VAL;
    			else
    				command1 &= ~SPI_CS_SW_VAL;
    		}

but I can’t find where is the DTS or spidev it should be configured, do you have any pointers? thanks!

1 Like

@ShaneCCC

Can you give any guidance?

Yt
Lasse

All of the dt setting can find here.

…/kernel/kernel-4.9/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt
…/kernel/kernel-4.9/Documentation/devicetree/bindings/spi/nvidia,tegra124-spi.txt

G16 can be made to work as a GPIO H.03 (#379). Try configuring it as a GPIO and manually setting it just as you have described. I would hope that the Tegra SPI driver will work, even though it is not in direct control of the SPI CS signal.

1 Like