This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM3358: AM3358

Part Number: AM3358


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");
	}
}


8037.spi.h
/*
 * 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