Project

General

Profile

Accessing SPI1 bus

Added by Mary Frantz over 6 years ago

How do you read/write to a device on the SPI1 bus (CS1) on the ARM side? Is there an example? Can I do low level register read/writes or is there a driver?

I am using MDK_2012-08-10

I have recompiled the kernel with a custom baseboard configuration (see attached).

The SPI1 bus has a variety of devices attached to it, so I will need to modify the clock polarity, data transfer size, clock rate, etc. We will use gpio for the chip selects.

Thanks,
Mary


Replies (7)

RE: Accessing SPI1 bus - Added by Gregory Gluszek over 6 years ago

Hi Mary,

Reading and writing over a SPI bus on Linux is pretty simple. You need to open a file descriptor for the SPI /dev/ entry and use ioctl SPI_IOC_MESSAGE commands to send spi_ioc_transfer structs to the device.

Here's a forum post with what looks like a good example: http://www.linuxquestions.org/questions/programming-9/spi-program-using-c-857237/

Thanks,
\Greg

RE: Accessing SPI1 bus - Added by Mary Frantz over 6 years ago

I don't see a SPI /dev/ entry.

Tried this (as in the example at https://www.kernel.org/doc/Documentation/spi/spidev_test.c)

    int fdSpi;
    fdSpi = open( "/dev/spidev1.1", O_RDWR);

fdSpi = -1 after this call.

The /dev/ directory doesn't contain anything starting with 'spi'.
Mary

RE: Accessing SPI1 bus - Added by Gregory Gluszek over 6 years ago

Hi Mary,

My guess would be that since in your baseboard file you set the modalias to "M25PE80" as part of the spi_board_info you will get a /dev/M25PE801.1 entry, or something to that affect, instead of /dev/spidev1.1.

Thanks,
\Greg

RE: Accessing SPI1 bus - Added by Mary Frantz over 6 years ago

Nope. I don't see that either.

I am going with the low level register access for now. I have SPI driver code that ran on a C6748 and am porting that. You can gain access to the registers using mmap().

#define SPI1_REG_BASE         (0x01F0E000)

typedef struct
{
  volatile uint32_t SPIGCR0;        // 0x0000
  volatile uint32_t SPIGCR1;        // 0x0004
  volatile uint32_t SPIINT;         // 0x0008
  volatile uint32_t SPILVL;         // 0x000C
  volatile uint32_t SPIFLG;         // 0x0010
  volatile uint32_t SPIPC0;         // 0x0014
  volatile uint32_t SPIPC1;         // 0x0018
  volatile uint32_t SPIPC2;         // 0x001C
  volatile uint32_t SPIPC3;         // 0x0020
  volatile uint32_t SPIPC4;         // 0x0024
  volatile uint32_t SPIPC5;         // 0x0028
  volatile uint32_t RSVD0[3];       // 0x002C
  volatile uint32_t SPIDAT0;        // 0x0038
  volatile uint32_t SPIDAT1;        // 0x003C
  volatile uint32_t SPIBUF;         // 0x0040
  volatile uint32_t SPIEMU;         // 0x0044
  volatile uint32_t SPIDELAY;       // 0x0048
  volatile uint32_t SPIDEF;         // 0x004C
  volatile uint32_t SPIFMT0;        // 0x0050
  volatile uint32_t SPIFMT1;        // 0x0054
  volatile uint32_t SPIFMT2;        // 0x0058
  volatile uint32_t SPIFMT3;        // 0x005C
  volatile uint32_t INTVEC0;        // 0x0060
  volatile uint32_t INTVEC1;        // 0x0064
} spi_regs_t;

    spi_regs_t *spi;
    int fd;

    // Access SPI1 Regs
    fd = open("/dev/mem", O_RDWR | O_SYNC);        // READ/WRITE, NON-CHACHED
    spi = (spi_regs_t *)mmap(NULL, sizeof(spi_regs_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, SPI1_REG_BASE );  // get virtual address for SPI1

I have successfully read/written these registers. I will test more fully once hardware is ready.

Mary

RE: Accessing SPI1 bus - Added by Michael Williamson over 6 years ago

Hi,

To get the spidev device, you need to add an entry for it in your platform baseboard file.

See the recent industrial I/O board platform file in the 3.2 kernel and look for spidev which is enabled with the CONFIG_INDIO_EXPANSION_ANALOGIO macro. This adds user space spidev devices to SPI0_CS3 and SPI0_CS4.

You also need to ensure that the SPIDEV support (the driver) is compiled in to the kernel as well (CONFIG_SPI_SPIDEV).

I don't recommend going down the memmap path and trying to write a user space driver the way you are suggesting.

-Mike

RE: Accessing SPI1 bus - Added by Mary Frantz over 6 years ago

I have successfully added the SPIDEV support to the kernel and can communicate over the bus now.

I occasionally see messages on the console of the following form:

<7> spidev spi1.2: msb first
<7> spidev spi1.2: setup mode 2, 8 bits/w, 10000000 Hz max --> 0


What do these mean?

I have a high priority task running that waits on a periodic timer. The period of the timer is 5 msec.

while(1)
{
    sigwait(&gSig_record, &sig);
    ... Do some processing ...
}

Sometimes when I see the spidev message, I also see that this task is held off from running for up to 3 or 4 msec, which is a problem for a periodic task running every 5 msec.

Can I eliminate this message?

Thanks,
Mary

RE: Accessing SPI1 bus - Added by Jonathan Cormier over 6 years ago

Mary,

You can search the kernel source for the messages by using grep. For example I might search for the string "msb first" and look at what files are found containing that text. You could then comment out those print statements.

cd <linux-src>
grep -r "msb first" .
grep -r "setup mode" .

Jonathan

    (1-7/7)
    Add picture from clipboard (Maximum size: 500 MB)