Python IOError: [Errno 90] Message too long, Passing long list to SPI function

坚强是说给别人听的谎言 提交于 2021-01-24 09:50:50

问题


I'm programming my A13-OLinuXino-MICRO using the provided pyA13 0.2.2 SPI driver to send data to an LCD. Ideally I would like to send a list containing 320*240*2 (320*240 pixel 16 bits per color) bytes to be written in one continuous write command to be speed efficient. The drivers in spi.c and spi_lib.c had an 8bit tx_len which limited me to 256 bytes so I modified them to 32bit which worked but now I receive an error when I try to pass a list that is more than 4096 values long in my spi.write(data[:]) function. Below is the code I'm using to fill the screen with a solid color that is 16 bits:

def FillScreen(c):
    LCD_SetPos(0, 0, 239, 319)
    ch = c>>8 & 0x00FF
    cl = c & 0x00FF
    d =[]
    for x in range (0,76800):
        d += [ch, cl]
   spi.write(d[:])

This is the error I get when I run the function:

Traceback (most recent call last):
  File "lcd.py", line 205, in <module>
    FillScreen(0x00FF)
  File "lcd.py", line 200, in FillScreen
    spi.write(d[:])
IOError: [Errno 90] Message too long

The piece of code that is giving me this error is contained in spi.c

/* Send data */
    if(spi_write(fd, tx_buffer, tx_len) < 0){
        return PyErr_SetFromErrno(PyExc_IOError);
    }

Is there any way that I can pass a longer message to the spi.write function? I'm very new to python but quite comfortable with C, go easy on my code please... Also, I have tried looping smaller messages to fill the screen but that takes too long. Any help would be appreciated.

Thanks, Michael


回答1:


Look in the notes in the Linux spidev docs - https://www.kernel.org/doc/Documentation/spi/spidev:

- There's a limit on the number of bytes each I/O request can transfer
  to the SPI device.  It defaults to one page, but that can be changed
  using a module parameter.

(You can find out your page size with $ getconf PAGESIZE - I believe it's pretty much always 4096 bytes.)

I haven't tested it, but I think Maxim's answer here should work for you: https://stackoverflow.com/a/16440226/5527382, which is:

The solution is to add following lines to /etc/modprobe.d/local.conf:

options spidev bufsiz=<NEEDED BUFFER SIZE>

The spidev driver defaults to 4096 bytes, then overrides it with the value of that argument if it's provided - https://github.com/beagleboard/linux/blob/4.1/drivers/spi/spidev.c#L92-L94:

static unsigned bufsiz = 4096;
module_param(bufsiz, uint, S_IRUGO);
MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");

Putting that line into /etc/modprobe.d/local.conf should pass that argument to the spidev module when it's loaded - you'll want to reboot after making the change to make sure you've reloaded it.




回答2:


I found a solution that seems to work for me right now since I can't figure out how to add the 'options' method described by Alex Haim. Instead I wrote a bash script that edits the /sys/module/spidev/parameters/bufsiz file

#!/bin/bash
# Spi Bufsiz Script

cd /sys/module/spidev/parameters
chmod 666 bufsiz
echo 65534 > bufsiz

This solution was found here.



来源:https://stackoverflow.com/questions/33791995/python-ioerror-errno-90-message-too-long-passing-long-list-to-spi-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!