Forums » Software Development »
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
baseboard-sys9000.c (4.41 KB) baseboard-sys9000.c |
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