Project

General

Profile

Accessing SPI1 bus

Added by Mary Frantz almost 11 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 almost 11 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 almost 11 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 almost 11 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 almost 11 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 almost 11 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 almost 11 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 almost 11 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)
    Go to top
    Add picture from clipboard (Maximum size: 1 GB)