-
Notifications
You must be signed in to change notification settings - Fork 335
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
SPI regression on BeagleBone (AM3358) #104
Comments
I have added debug output to Adafruit_Blinka, Adafruit_CircuitPython_BusDevice, and py_spidev:
The strace output shows that
|
How does Adafruit_CircuitPython_BME280 expect chip select (CS) to be handled? class Adafruit_BME280_SPI(Adafruit_BME280):
"""Driver for BME280 connected over SPI"""
def __init__(self, spi, cs, baudrate=100000):
import adafruit_bus_device.spi_device as spi_device
self._spi = spi_device.SPIDevice(spi, cs, baudrate=baudrate)
super().__init__()
The SPI implementation in Adafruit_Blinka does NOT handle CS def write(self, buf, start=0, end=None):
if not buf:
return
if end is None:
end = len(buf)
try:
self._spi.open(self._port, 0)
try:
self._spi.no_cs = True # this doesn't work but try anyways
except AttributeError:
pass
self._spi.max_speed_hz = self.baudrate
self._spi.mode = self.mode
self._spi.bits_per_word = self.bits
self._spi.writebytes([x for x in buf[start:end]])
self._spi.close()
except FileNotFoundError as not_found:
print("Could not open SPI device - check if SPI is enabled in kernel!")
raise |
This line in adafruit_blinka/microcontroller/generic_linux/spi.py: self._spi.no_cs = True # this doesn't work but try anyways causes the error:
debug output:
What is happening in It invokes this code in spidev_module.c: {"no_cs", (getter)SpiDev_get_no_cs, (setter)SpiDev_set_no_cs,
"disable chip select\n"}, which calls: SpiDev_set_no_cs(SpiDevObject *self, PyObject *val, void *closure) which calls: static int __spidev_set_mode( int fd, __u8 mode) this is where the
This |
How does the Linux kernel handle SPI_NO_CS? Here are the references to It is defined in: #define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */ The Raspberry Pi (BCM2835 processor) seems to support #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
| SPI_NO_CS | SPI_3WIRE) |
SPI driver for BeagleBone does not support for SPI on the AM3358 is called McSPI and is implemented in: The allowed mode bits are: master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; The allowed mode bits for the SPI controller ( int spi_setup(struct spi_device *spi)
{
/*snip*/
bad_bits = spi->mode & ~spi->controller->mode_bits;
ugly_bits = bad_bits &
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD);
if (ugly_bits) {
dev_warn(&spi->dev,
"setup: ignoring unsupported mode bits %x\n",
ugly_bits);
spi->mode &= ~ugly_bits;
bad_bits &= ~ugly_bits;
}
if (bad_bits) {
dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
bad_bits);
return -EINVAL;
} In the case of the BeagleBone, the I recompiled the kernel on the BeagleBone with some print statements which confirms that setting
|
hihi yeah so there are situations where you want to use the SPI bus w/o a CS pin (dotstars for example) so what we do is we have one 'dummy' CS pin that we always toggle but never connect to. Then we use any plain gpio pin for CS. this lets us have any CS pin, and any config of SPI, at the loss of a GPIO |
@ladyada thanks, yes, I can see why it is useful to decouple CS from the hardware SPI peripheral. As a test, I just commented out all instances of
This is because spidev no longer tries to set the I think a work around maybe to add logic to skip setting no CS if AM3358 based board. I'll try that out and followup. |
please do a try-except |
fyi dont commit directly to this repo, have PRs only that i'll review. thanks :) |
OK, no problem. I will create PR when I have a working code. For try:
self._spi.no_cs = True # this doesn't work but try anyways
except AttributeError:
pass with a call to to a new method def set_no_cs(self):
print("generic_linux/spi.py: set_no_cs(): enter")
if detector.chip.AM33XX:
print("generic_linux/spi.py: set_no_cs(): detected AM33XX, SKIP setting no_cs")
else:
try:
print("generic_linux/spi.py: set_no_cs(): self._spi.no_cs = True")
self._spi.no_cs = True # this doesn't work but try anyways
except AttributeError:
pass I just tested this out and the BME280 works OK on the BeagleBone. However, I think that calling |
why not add an except for OSError? |
|
ok got it |
do not set SPI_NO_CS bit when chip is AM3358 #104
Tested OK with BME280 on PocketBeagle. Make sure pins are configured for SPI0 plus P1.6 as GPIO for CS:
import board
import busio
import adafruit_bme280
import digitalio
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
bme_cs = digitalio.DigitalInOut(board.P1_6)
bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi, bme_cs)
print("\nTemperature: %0.1f C" % bme280.temperature)
system version info:
|
@s-light is adding support for PocketBeagle (#100) but could not get SPI to work. The issue is not specific to the PocketBeagle. SPI support is also broken on BeagleBone Black. Both boards have the TI AM3358 processor.
PR #46 added SPI support for the BeagleBone Black (which has a TI AM3358 processor). At that time, I was able to successfully test the BME280 in SPI mode.
However, it now encounters error
OSError: [Errno 22] Invalid argument
inmicrocontroller/generic_linux/spi.py
:From Adafruit_Python_BME280, I am testing with
bme280_simpletest.py
:which results in:
The text was updated successfully, but these errors were encountered: