SPIDEV 1.0 doesn't work, but SPIDEV 1.1 does

DannyB
DannyB New Member Posts: 3

Hey folks,
I've followed the directions to enable SPI on the UP 6000, and both spi devices show up.

However, the chip select pin on spidev1.0 never toggles when doing transfers. It does otherwise transfer data. The one on spidev1.1 properly toggles CS.

(The ASL files also set the speed wrong, if you compare the DSDT function to the ASL, the DSDT says 10mhz max, the ASL is setting it to 1mhz max).

Answers

  • mafish
    mafish New Member Posts: 8

    I can confim the behaviour is not correct. On my platform on spidev1.0 I only get a very short (<25us) pulse on the CS pin. The spidev1.0 works better.
    I've run some more tests using different settings of the message (I am using native C code, and spidev implementation - no MRAA or any other 3rd party lib).
    This is a snippet of message config I've used:

    spi_message[0].bits_per_word = spi_bits_per_word;
    spi_message[0].cs_change = 1;
    spi_message[0].delay_usecs = 0;
    spi_message[0].len = 4;
    spi_message[0].rx_buf = (uint64_t)rxBuffer;
    spi_message[0].tx_buf = (uint64_t)txBuffer;
    int rv = ioctl(spi_1_fd, SPI_IOC_MESSAGE(1), &spi_message);
    

    My main interest was in the .cs_change option. From my understanding, when set to 1, it should make my CS go low before first byte, and go back up after the last byte of the message. When set to 0, it should go low before first byte, and stay low after message is complete.
    On the oscillograms below - yellow line is SCK and blue line is CS.

    First scenario - spidev1.0 with cs_change = 0:

    Short impulse on CS before message (not what we want) and signal goes low after the message (as expected).

    Second scenario - spidev1.0 with cs_change = 1:

    Only short impulse on the CS - now other change of state on the CS.

    Third scenario - spidev1.1 with cs_change = 0:

    This is what i would expect cs_change = 1 would look like - but note that in this case cs_change = 0 which means that CS line should stay low after transmission.

    Fourth scenarion - spidev1.1 with cs_change = 1:

    This is what i would expect cs_change = 0 look like.

    From my observations it seems that there are some bugs in spi kernel code that cause malfunction in CS handing of the spidev1.0 (the cs_change indicates that the spi mechanism seems to work but somethings is pulling the pin up just after setting it low).
    For spidev1.1 it seems that cs_change behaviour is inverted.

  • fvllml
    fvllml New Member Posts: 12

    Which mode are you using? I think I had the same issue and tried like this

    int file_desctiptor = open("/dev/spidev1.0", O_RDWR);
    ioctl(file_desctiptor, SPI_IOC_WR_MODE, (SPI_MODE_1 | SPI_CS_HIGH));
    
  • mafish
    mafish New Member Posts: 8

    Hi, my config was the following:

    //spi hardware config
        unsigned char spi_mode = SPI_MODE_0;
        unsigned char spi_bits_per_word = 16;
        unsigned int spi_speed = 8333333;
        uint8_t lsb = 0x01;
    
        int spi_1_fd = -1;
    
        spi_1_fd = open("/dev/spidev2.0", O_RDWR);
        rv = ioctl(spi_1_fd, SPI_IOC_WR_MODE, &spi_mode);
        rv = ioctl(spi_1_fd, SPI_IOC_RD_MODE, &spi_mode);
        rv = ioctl(spi_1_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits_per_word);
        rv = ioctl(spi_1_fd, SPI_IOC_RD_BITS_PER_WORD, &spi_bits_per_word);
        rv = ioctl(spi_1_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
        rv = ioctl(spi_1_fd, SPI_IOC_RD_MAX_SPEED_HZ, &spi_speed);
        rv = ioctl(spi_1_fd, SPI_IOC_RD_LSB_FIRST, &lsb);
    

    I've not tested modes other than SPI_MODE_0 in my application, but I would assume it should work, as there is no info about it not working with some specific settings.