pzakielarz
Posts: 3
Joined: Sat Oct 15, 2016 10:51 am

SPI_NO_CS flag in SPI_MODE seems to have no effect.

Tue Oct 17, 2017 6:10 pm

I'm not seeing any difference on how the chipselects operate when SPI_NO_CS is set/cleared. My intention is to configure the system to use GPIO chipselects. I need to leave the chipselect de-asserted for some transfers.

I'm running Raspbian (March 2017 Jessie) on a Pi 2 Model B V. 1.1.

Code: Select all

# This is my config.txt:
dtparam=audio=on
disable_splash=1
gpu_mem=128
disable_audio_dither=1
lcd_rotate=2
dtoverlay=spi0-cs,cs0_pin=4,cs1_pin=0
dtoverlay=spi1-2cs,cs0_pin=12,cs1_pin=16
I've included some simplified code for what I'm trying to do here:

Code: Select all

// send byte WITH CHANGING CHIPSELECT
mode = SPI_MODE_0;
ioctl(fds[0], SPI_IOC_WR_MODE, &mode) < 0)
	
memset(&spi, 0, sizeof(spi));
	
spi.tx_buf = (unsigned long) &outmessage;
spi.rx_buf = (unsigned long) &inmessage;
spi.len = 1;
spi.delay_usecs = 0;
spi.speed_hz = speed;
spi.bits_per_word = bpw;
spi.cs_change = 0;
	
ioctl(fds[0], SPI_IOC_MESSAGE(1), &spi);

// send byte WITHOUT CHANGING CHIPSELECT
mode = SPI_MODE_0 | SPI_NO_CS;
ioctl(fds[0], SPI_IOC_WR_MODE, &mode) < 0)
	
memset(&spi, 0, sizeof(spi));
	
spi.tx_buf = (unsigned long) &outmessage;
spi.rx_buf = (unsigned long) &inmessage;
spi.len = 1;
spi.delay_usecs = 0;
spi.speed_hz = speed;
spi.bits_per_word = bpw;
spi.cs_change = 0;
	
ioctl(fds[0], SPI_IOC_MESSAGE(1), &spi);
I read through drivers/spi/spi-bcm2835.c, and I think the SPI_NO_CS flag might only work if the native hardware chipselect is used. I think I can come up with a workaround with some creative use of the cs_change and SPI_CS_HIGH flags, but I want to make sure I'm not missing something with how SPI_NO_CS is supposed to work before I go down that path.

pzakielarz
Posts: 3
Joined: Sat Oct 15, 2016 10:51 am

Re: SPI_NO_CS flag in SPI_MODE seems to have no effect.

Wed Oct 18, 2017 3:47 pm

After studying the source closer, I'm confident that the driver ignores SPI_NO_CS when using gpio chipselect. Anyone have any thoughts as to why this is or isn't a bug?

piras77
Posts: 147
Joined: Mon Jun 13, 2016 11:39 am

Re: SPI_NO_CS flag in SPI_MODE seems to have no effect.

Fri Oct 20, 2017 7:35 pm

Well, this might not really help, still, there is always the possibility to access the peripheral directly from userland. Real-time behavior is feasible thru DMA access. If you need other CE/CS signals than the one controlled by the SPI peripheral you still can daisy chain DMA control blocks to access other GPIO pins. However, lacking access to interrupts and ISR may be an issue. And, of course, this may involve significant efforts (to get familiar and to implement).

pzakielarz
Posts: 3
Joined: Sat Oct 15, 2016 10:51 am

Re: SPI_NO_CS flag in SPI_MODE seems to have no effect.

Sun Oct 29, 2017 10:12 am

piras77 wrote:
Fri Oct 20, 2017 7:35 pm
Well, this might not really help, still, there is always the possibility to access the peripheral directly from userland. Real-time behavior is feasible thru DMA access. If you need other CE/CS signals than the one controlled by the SPI peripheral you still can daisy chain DMA control blocks to access other GPIO pins. However, lacking access to interrupts and ISR may be an issue. And, of course, this may involve significant efforts (to get familiar and to implement).
I'm not ashamed to say I have no idea what you're talking about, but would love to learn. Any idea where I can find a reference that describes this in a little more detail so I can determine if it suits my needs?

piras77
Posts: 147
Joined: Mon Jun 13, 2016 11:39 am

Re: SPI_NO_CS flag in SPI_MODE seems to have no effect.

Mon Oct 30, 2017 3:47 pm

There are two (major) ways to run SPI from userland on a Pi. By directly accessing the peripheral. Or by using the kernel support (in Raspbian).

Since you encountered problems with the kernel driver, and there wasn't any answer, my suggestion was to try it the direct way. Honestly, I can't find a proper documentation on the kernel drivers (and not only for SPI). I neither know whether these drivers are developed by the RPF or by Broadcom (so where would we direct a question regarding these?). Most responses here in this forum come from users, not kernel developers AFAIK.

Anyway, there is the possibility to access the peripherals directly from userland. There is a document that describes the peripherals (or at least some of them): https://www.raspberrypi.org/app/uploads ... herals.pdf. There you start (even though the document contains some flaws).

If you need examples on how this works, take a look at pigpio: http://abyz.me.uk/rpi/pigpio: So you develop in C or C++. The periphals are addressed by registers (32-bit words). These registers are mapped into user space thru /dev/mem. You bring a peripheral to live by peeking and poking the proper registers.

If you like to take a look at the document and at the pigpio implementation, you'll learn how these peripherals work. You'll probably don't understand everything. Unlike questions concerning the kernel drivers, your odds are much better that people here will be willing/able to help (I myself went thru SPI, I2C, GPIO and Clock Manager peripherals).

Have fun! :-)

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 9929
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: SPI_NO_CS flag in SPI_MODE seems to have no effect.

Mon Oct 30, 2017 4:28 pm

I'm not an SPI expert, but if using GPIO chipselects then it appears the core SPI code handles all the GPIO operations, not the individual SPI block driver. Hence it is correct that spi-bcm2835.c does no checking of SPI_NO_CS when using gpio chipselects.
It does appear that spi.c doesn't check SPI_NO_CS, so perhaps it is worth a quick hack in there to make it

Code: Select all

	if (gpio_is_valid(spi->cs_gpio)) {
		if (!(spi->mode & SPI_NO_CS))
			gpio_set_value(spi->cs_gpio, !enable);
	} else if (spi->master->set_cs) {
		spi->master->set_cs(spi, !enable);
	}
piras77 wrote:Since you encountered problems with the kernel driver, and there wasn't any answer, my suggestion was to try it the direct way. Honestly, I can't find a proper documentation on the kernel drivers (and not only for SPI).
Most of the kernel documentation is in the kernel tree - https://github.com/raspberrypi/linux/tr ... tation/spi is a good place to start for SPI (other kernel versions are available as branches).
piras77 wrote:I neither know whether these drivers are developed by the RPF or by Broadcom (so where would we direct a question regarding these?). Most responses here in this forum come from users, not kernel developers AFAIK.
First port of call if you really think you have found a bug - https://github.com/raspberrypi/linux/issues. That's the repo that the Pi specific Linux kernel comes from.
Secondly the copyright message at the top of the source file tells you

Code: Select all

/*
 * Driver for Broadcom BCM2835 SPI Controllers
 *
 * Copyright (C) 2012 Chris Boot
 * Copyright (C) 2013 Stephen Warren
 * Copyright (C) 2015 Martin Sperl
 *
 * This driver is inspired by:
 * spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
 * spi-atmel.c, Copyright (C) 2006 Atmel Corporation
 *
No company attribution should tell you not supplied by Broadcom or RPF.
And thirdly with ANY Linux kernel driver, there will be a maintainer and mailing list listed for it in MAINTAINERS. There is a useful little script in the kernel tree called get_maintainers.pl (in the scripts folder) that will do just that:

Code: Select all

me@my-PC:~/linux$ ./scripts/get_maintainer.pl drivers/spi/spi-bcm2835.c 
Mark Brown <broonie@kernel.org> (maintainer:SPI SUBSYSTEM)
Eric Anholt <eric@anholt.net> (maintainer:BROADCOM BCM2835 ARM ARCHITECTURE)
Stefan Wahren <stefan.wahren@i2se.com> (maintainer:BROADCOM BCM2835 ARM ARCHITECTURE)
Florian Fainelli <f.fainelli@gmail.com> (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...)
Ray Jui <rjui@broadcom.com> (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...)
Scott Branden <sbranden@broadcom.com> (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...)
bcm-kernel-feedback-list@broadcom.com (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...)
linux-spi@vger.kernel.org (open list:SPI SUBSYSTEM)
linux-rpi-kernel@lists.infradead.org (moderated list:BROADCOM BCM2835 ARM ARCHITECTURE)
linux-arm-kernel@lists.infradead.org (moderated list:BROADCOM BCM2835 ARM ARCHITECTURE)
linux-kernel@vger.kernel.org (open list)
Look at the most specific lists first, so linux-rpi-kernel@lists.infradead.org would be your next port of call if you think it is spi-bcm2835.c related, and linux-spi@vger.kernel.org if you thought it was spi.c (the core framework). A search of the list archives first would be sensible.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

Return to “Interfacing (DSI, CSI, I2C, etc.)”