Tool/software: Linux
Hello All,
I'm using beagle bone black for my project, need to evaluate the SPI for some device interface which will send the data in MBPS.
I have tested the SPI by using ioctal calls, code base attached.
/*******************************************************************************
* FileName : spi.h
* Description :
*******************************************************************************/
#include <spi.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
void pabort(const char *s)
{
perror(s);
abort();
}
/**
* brief: open spi device and return the file descriptor
* @Param: the spi number
*/
int spi_fd_open(char *device)
{
int fd;
fd = open(device, O_RDWR);
if (fd < 0) {
perror("spi/fd_open");
}
return fd;
}
/**
* brief: close spi device
* @Param: fd: the file descriptor of spi
*/
int spi_fd_close(int fd)
{
return close(fd);
}
/**
* bried: initialize the spi
* @Param: spi number, spi_prms structure
*/
int spi_init(int fd, struct spi_prms *spi)
{
int ret = 0;
printf("Rxd: Struct: Mode:%d Speed:%d Bits:%d \n", spi->mode, spi->speed, spi->bits);
/* spi mode */
ret = ioctl(fd, SPI_IOC_WR_MODE, &spi->mode);
if (ret == -1)
{
pabort("can't set spi mode");
return ret;
}
ret = ioctl(fd, SPI_IOC_RD_MODE, &spi->mode);
if (ret == -1)
{
pabort("can't get spi mode");
return ret;
}
/* bits per word */
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spi->bits);
if (ret == -1)
{
pabort("can't set bits per word");
return ret;
}
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &spi->bits);
if (ret == -1)
{
pabort("can't get bits per word");
return ret;
}
/* max speed hz */
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi->speed);
if (ret == -1)
{
pabort("can't set max speed hz");
return ret;
}
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &spi->speed);
if (ret == -1)
{
pabort("can't get max speed hz");
return ret;
}
return ret;
}
// send a data block to SPI
// will only change CS if the SPI_CS bits are set
void spi_send(struct spi_prms *spi, const void *buffer, int length)
{
struct spi_ioc_transfer transfer_buffer[1] = {
{
.tx_buf = (unsigned long)(buffer),
.rx_buf = 0, // nothing to receive
.len = length,
.delay_usecs = spi->delay,
.speed_hz = spi->speed,
.bits_per_word = spi->bits,
.cs_change = 0
}
};
if (-1 == ioctl(spi->fd, SPI_IOC_MESSAGE(1), transfer_buffer)) {
warn("SPI: send failure");
}
}
// send a data block to SPI and return last bytes returned by slave
// will only change CS if the SPI_CS bits are set
void spi_read(struct spi_prms *spi, const void *buffer, void *received, int length)
{
struct spi_ioc_transfer transfer_buffer[1] = {
{
.tx_buf = (unsigned long)(buffer),
.rx_buf = (unsigned long)(received),
.len = length,
.delay_usecs = spi->delay,
.speed_hz = spi->speed,
.bits_per_word = spi->bits,
.cs_change = 0
}
};
if (-1 == ioctl(spi->fd, SPI_IOC_MESSAGE(1), transfer_buffer)) {
warn("SPI: read failure");
}
}
/*
* SPI testing utility (using spidev driver)
*
* Copyright (c) 2007 MontaVista Software, Inc.
* Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* Cross-compile with cross-gcc -I/path/to/cross-kernel/include
*/
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <spi.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
/* Configuration parameters of SPI1 */
static char *device = "/dev/spidev1.0";
struct spi_prms spi1;
int main(void)
{
int ret = 0;
int i=10, z;
uint8_t tx[10] = {0x11, 0x22, 0x33, 0x44, 0xFF, 0xFF, 0x77, 0x88, 0x99, 0xaa};
// uint8_t tx[] = {'D', 'E', 'A', 'D', 'B', 'E', 'F', 'F'};
uint8_t rx[10] = {0};
spi1.mode = 3;
spi1.bits = 8;
spi1.speed = 10000000;
spi1.fd = spi_fd_open(device);
if (spi1.fd < 0)
{
printf("can't open spi1 device \n");
pabort("can't open device");
}else
{
ret = spi_init(spi1.fd, &spi1);
if (ret != -1)
{
printf("SPI init done succesfully \n");
printf("spi mode: %d\n", spi1.mode);
printf("bits per word: %d\n", spi1.bits);
printf("max speed: %d Hz (%d KHz)\n", spi1.speed, spi1.speed/1000);
}else
{
printf("SPI init failed \n");
return ret;
}
}
do
{
//spi_transfer(fd, &spi1, tx, rx, 10);
spi_send(&spi1, &tx, 10);
spi_read(&spi1, &tx, &rx, 10);
i--;
printf("SPI i:%d \n", i);
for(z=0; z<10; z++)
printf(" %x", rx[z]);
printf(" \n");
}while(i>0);
spi_fd_close(spi1.fd);
return ret;
}
Can anyone help me how to configure the SPI with interrupt(for MISO & MOSI) & use in application. I have do for MISO line.
Looking forward your reply.
Thanks,
Shekar