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.

SPI Write with spidev



HI,

i am using spidev user space driver to write data on the DAC module connected to SPI 4 Chip select 1.

while i am writing 24 bit data, it is transferring the same three times as observed in the scope.

please let me know why it is doing it three times.

here i am attaching my code of the user space application.

/*
 * 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>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static void pabort(const char *s)
{
	perror(s);
	abort();
}

static const char *device = "/dev/spidev4.1";
static uint8_t mode;
static uint8_t bits = 24;
static uint32_t speed = 12000000;
static uint16_t delay=20;

/*unsigned long uu_dac_cmd[]={ 	0xFFAA55 ;
, 0xFFAA55,0xFFAA55,0xFFAA55,0xFFAA55,0xFFAA55,
				0xFFAA55, 0xFFAA55,0xFFAA55,0xFFAA55,0xFFAA55,0xFFAA55,
				0xFFAA55, 0xFFAA55,0xFFAA55,0xFFAA55,0xFFAA55,0xFFAA55,
				0xFFAA55, 0xFFAA55,0xFFAA55,0xFFAA55,0xFFAA55,0xFFAA55
			    };*/

//unsigned long uu_dac_cmd[]= {0xC81FFF};

unsigned long uu_dac_cmd[]={ 	0xC80000,0xC805FF,0xC81FFF,0xC82500,0xC82FFF,0xC83500,
				0xC83F00,0xC84500,0xC84FFF,0xC805FF,0xC86FFF,0xC87FFF,
				0xC88FFF,0xC89FFF,0xC88F00,0xC87FFF,0xC86FFF,0xC85FFF,
				0xC84FFF,0xC83FFF,0xC82FFF,0xC81FFF,0xC805FF,0xC80000};




static void transfer(int fd )
{
	int ret;
	//uint32_t tx[3] = {0xC0,0x00,0x00};//uu_dac_cmd[x];
	//uint32_t tx[] =  {0xFFAA55}; 

	//uint8_t rx[1] = {0x00};

	
	struct spi_ioc_transfer tr = {
		.tx_buf = (unsigned long)uu_dac_cmd,
	/*	.rx_buf = (unsigned long)rx, */
		.rx_buf = 0;
		.len = ARRAY_SIZE(uu_dac_cmd),
		.delay_usecs = delay,
		.speed_hz = speed,
		.bits_per_word = bits,
	};

	printf("Before IOCTL \n");
	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	if (ret < 1)
		pabort("can't send spi message");

	
	printf("AFTER IOCTL \n");
	
}

static void print_usage(const char *prog)
{
	printf("Usage: %s [-DsbdlHOLC3]\n", prog);
	puts("  -D --device   device to use (default /dev/spidev1.1)\n"
	     "  -s --speed    max speed (Hz)\n"
	     "  -d --delay    delay (usec)\n"
	     "  -b --bpw      bits per word \n"
	     "  -l --loop     loopback\n"
	     "  -H --cpha     clock phase\n"
	     "  -O --cpol     clock polarity\n"
	     "  -L --lsb      least significant bit first\n"
	     "  -C --cs-high  chip select active high\n"
	     "  -3 --3wire    SI/SO signals shared\n");
	exit(1);
}

static void parse_opts(int argc, char *argv[])
{
	while (1) {
		static const struct option lopts[] = {
			{ "device",  1, 0, 'D' },
			{ "speed",   1, 0, 's' },
			{ "delay",   1, 0, 'd' },
			{ "bpw",     1, 0, 'b' },
			{ "loop",    0, 0, 'l' },
			{ "cpha",    0, 0, 'H' },
			{ "cpol",    0, 0, 'O' },
			{ "lsb",     0, 0, 'L' },
			{ "cs-high", 0, 0, 'C' },
			{ "3wire",   0, 0, '3' },
			{ "no-cs",   0, 0, 'N' },
			{ "ready",   0, 0, 'R' },
			{ NULL, 0, 0, 0 },
		};
		int c;

		c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);

		if (c == -1)
			break;

		switch (c) {
		case 'D':
			device = optarg;
			break;
		case 's':
			speed = atoi(optarg);
			break;
		case 'd':
			delay = atoi(optarg);
			break;
		case 'b':
			bits = atoi(optarg);
			break;
		case 'l':
			mode |= SPI_LOOP;
			break;
		case 'H':
			mode |= SPI_CPHA;
			break;
		case 'O':
			mode |= SPI_CPOL;
			break;
		case 'L':
			mode |= SPI_LSB_FIRST;
			break;
		case 'C':
			mode |= SPI_CS_HIGH;
			break;
		case '3':
			mode |= SPI_3WIRE;
			break;
		case 'N':
			mode |= SPI_NO_CS;
			break;
		case 'R':
			mode |= SPI_READY;
			break;
		default:
			print_usage(argv[0]);
			break;
		}
	}
}

int main(int argc, char *argv[])
{
	int ret = 0;
	int fd;

	int cnt=0;
	mode=1;

	//char wr_buf[]={0xff,0x00,0x1f,0x0f};
	unsigned long wr_buf[]={0xC81FFF};

	parse_opts(argc, argv);

	fd = open(device, O_RDWR);
	if (fd < 0)
		pabort("can't open device");

	/*
	 * spi mode
	 */
	 ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
	if (ret == -1)
		pabort("can't set spi mode");
       
/*
	ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
	if (ret == -1)
		pabort("can't get spi mode");
  */      
	/*
	 * bits per word
	 */
	ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't set bits per word");
       
	/*ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't get bits per word");
        */
	/*
	 * max speed hz
	 */
	/*ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
	if (ret == -1)
 		pabort("can't set max speed hz");*/
        
	ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't get max speed hz");
         
	printf("spi mode: %d\n", mode);
	printf("bits per word: %d\n", bits);
	printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
	cnt =0;

while(1)
{	
	printf("loop\n\r");
	for(cnt=0;cnt<23;cnt++)
	{

		printf("\n transferring  %d \n:",cnt);
              	transfer( fd);
		
		usleep(50);  			

	}

}
	//transfer(fd);

	close(fd);

	return ret;
}

Regards,

Vimal

  • Vimal,

    There is sample application (spidev_test.c) available online that shows how to use the spidev driver.

    You can also see the below e2e threads:

    http://e2e.ti.com/support/arm/sitara_arm/f/791/t/288783.aspx

    http://e2e.ti.com/support/embedded/linux/f/354/t/74188.aspx

    http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/t/201820.aspx

    Regards,
    Pavel

  • I think the field len in struct spi_ioc_transfer is in bytes. Try changing this line from

      .len = ARRAY_SIZE(uu_dac_cmd),

    to

      .len = sizeof(uu_dac_cmd),