Post Go back to editing

LTC1858 and spidev

Hello,

I am working with the Eagle board from Diamond System that has Apalis imx6 on it and I would like to communicate with SPI component LTC1858 using /dev/spidev1.0. The TX nb of bits is 8 and the RX nb of bits is 14.

It seems like I can kind of get data back from the component (I checked with an oscilloscope, what I see is what I get, I can't check again until Friday), it's just that the values sent back are not what I am expecting. I'm wondering if maybe the configuration is sent wrong.... Not sure how to deal with the TX 8 bit and RX 14 bit business... I haven't done anything with CS. Is there something wrong with the code I have been using? Is there a library I could use instead?

Best regards,

Jennifer

/*
  * 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/spidev1.0";
 static uint8_t mode=0;
 static uint8_t bits = 8;
 static uint32_t speed = 1000;
 static uint16_t delay  ;
 
 static void printHexToBinary(uint16_t hex)
 {
   switch (hex)
   {
     case 0: printf("0000");
           break;
     case 1: printf("0001");
           break;
     case 2: printf("0010");
           break;
     case 3: printf("0011");
           break;
     case 4: printf("0100");
           break;
     case 5: printf("0101");
           break;
     case 6: printf("0110");
           break;
     case 7: printf("0111");
           break;
     case 8: printf("1000");
           break;
     case 9: printf("1001");
           break;
     case 10: printf("1010");
           break;
     case 11: printf("1011");
           break;
     case 12: printf("1100");
           break;
     case 13: printf("1101");
           break;
     case 14: printf("1110");
           break;
     case 15: printf("1111");
           break;
     default: break;
   }
 }
 
 static void transfer(int fd)
 {
     int ret;
         uint8_t tx[] = {
               (  0xAC )
     };
         uint8_t rx[2] = {0, };
     struct spi_ioc_transfer tr = {
         .tx_buf = (unsigned long)tx,
         .rx_buf = (unsigned long)rx,
              .len = ARRAY_SIZE(rx),
         .delay_usecs = delay,
         .speed_hz = speed,
         .bits_per_word = 8,
     };
     ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
     if (ret < 1)
         pabort("can't send spi message");
     for (ret = 0; ret < ARRAY_SIZE(rx); ret++) {
     //    if (!(ret % 6))
     //        puts("");
         printf("%.2X ", rx[ret]);
     }
     printf("\r\n");
         uint16_t total = (rx[0] << 8) + rx[1];
     printf("%d\r\n", total);
 
         printHexToBinary(rx[0]>>4);
     printHexToBinary(rx[0] & 0x0f);
     printHexToBinary((rx[1]>>4) & 0x0f);
     printHexToBinary(rx[1] & 0x0f);
         printf("\r\nvoltage: %f", (double)total*10/(4*16383));
     puts("");  
 }
 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;
     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);
     transfer(fd);
     close(fd);
     return ret;
 }