SPI trouble with transfer multiple bytes

  • Hello,

    I'm try to use the SPI with the spidev.c in a C++ environment (QT) on efus A9.
    I have to transfer 1 to n Bytes (max. 4096) with one CS Phase, but the the CS signal is always asserted / Deasserted on every Byte.
    (See attached picture)
    I try some different settings in the spi_ioc_transfer structure like cs_change and pad but the behaviour is always the same.
    As a second attempt i want to use the SPI_B_CS1 as a GPIO Pin, but if i initialize the spi with
    ioctl(fd, SPI_IOC_WR_MODE, &mode)
    with mode as (SPI_MODE_0 | SPI_NO_CS) the ioctl returns a failure.
    I ignore that and try to set the CS Pin manually.
    In a first attempt i do that from a putty terminal, but it failed too.
    (GPIO Pin 88 is defined as the SPI_B_CS1 pin in the GPIO Reference card)

    Summary from the putty terminal:

    export gpiochip128@ gpiochip192@ gpiochip64@ unexport
    gpiochip0@ gpiochip160@ gpiochip32@ gpiochip96@
    # echo 88 > /sys/class/gpio/export
    sh: write error: Device or resource busy

    then i try to use the PWM_A Pin (GPIO 42, J22-32 SINTF Board) as the CS Pin.
    For testing i try the putty terminal again.

    Summary from the putty terminal:
    # echo 42 > /sys/class/gpio/export
    # echo out > /sys/class/gpio/gpio42/direction
    # echo 1 > /sys/class/gpio/gpio42/value
    # echo 0 > /sys/class/gpio/gpio42/value

    it looks like good but i can't see any reaction on that pin.
    I try another pin (I2C_B_IRQ, GPIO 44 on J22-48) but it's the same.

    Is there any chance to setup the CS of the spi for my purposes ?
    If not, how can i deactivate it and set it manually ?

    Has anybody an idea why the GPIO Pin settings always failed?

    under /dev/ are 4 SPI devices

    i use /dev/spidev0.2 and it works on SPI_B_CS1
    But what is /dev/spidev0.1 ?
    is there any documentation about the relationship beetween the SPI_A and SPI_B and the spidevX.Y devices ?
    (at the moment it's try and error)

    i hope anybody can help me.
    Sorry for this basic questions but i'am a newbie on Linux and efus Board !

    thanks in advance

  • I think what you want to do is not specified in SPI. SPI does not know the concept of a byte, it is completely based on bits. A transfer starts with the chip select asserted. Then with each clock pulse, one bit is transferred and after the last bit, the chip select is deasserted. This allows for example to transfer 12 bits or 25 bits, so the number of bits is not necessary a multiple of 8. Of course it would be theoretically possible to transfer an arbitrary number of bits in this way, but the devices in real life usually have a limited shift register size and hence a restriction of transferring at most 16 or 32 bits in one go. The software is often even more restricted and can only transfer units of exactly byte or word size.

    If you want to transfer an arbitrary number of bytes, how do you determine the size of the overall transfer? The chip select signal is used to determine the size of one unit (e.g. one byte). So it is completely normal for the chip select signal to be deasserted between bytes.

    I think what you want to do is not covered by the SPI specifications. And therefore there is no way of specifying such a behavior in the spidev device.

    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hello,

    yeahh, i found a GPIO that works.
    I can use the SPI_B_IRQ (GPIO 6) as my CS Signal.
    Because i don't know why the GPIO 42 and GPIO 44 doesn't work.
    In the efusA9 Hardware Documentation (3.1 Goldfinger connector) these pins marked as
    "SW configurable as GPIO" and also in the "efusA9 GPIO reference card"
    I changed to another board (because i suspect a damaged efusA9) but it's the same.
    Where is the bug ? (in the documentation, the kernel etc. ?)

    the next unlovely behaviour are a lot of "empty" gaps in the transfer.
    For testpurposes i transfer a block of 200 bytes with a spi clk setting of 12 MHz.
    On the oscilloscope (see attached picture, blue = CS Signal, red = SPI CLK) i see a gap of 60 µs after every 64 bytes.
    This halfed the transfer performance.
    (thats many cpu cycles for only 64 bytes !!!)
    Is there any way to improve this performance bottleneck in the future ?

    thanks in advance