LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer
User Name
Password
Linux - Embedded & Single-board computer This forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.

Notices


Reply
  Search this Thread
Old 06-28-2019, 08:01 PM   #1
chickenwing101
LQ Newbie
 
Registered: Jun 2019
Posts: 1

Rep: Reputation: Disabled
Unhappy ICM-20948 issues using ioctl and spi_ioc_message


I am using a DM3730 Torpedo and trying to use SPI to grab information from an ICM-20948 IMU sensor.

I am using the spidev framework and am having issues actually grabbing information. I am able to retriever the WHO_AM_I register at 0h by sending 0x80 (1 at the MSB to say read) but am unable to get access to any other registers. Below is attached code that return 00 EA (EA is the who_am_i value). Does anybody have suggestions on what I need to change in order to read other registers?

Thanks

Code:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <stdint.h>


#include <linux/types.h>
#include <linux/ioctl.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.1";
static uint8_t mode = 0;
static uint8_t bits = 8;
static uint32_t speed = 100000;
static uint16_t delay = 100;

static void transfer(int fd)
{
int ret;
uint8_t tx[] = {
 0x80, 0x00,
};
uint8_t rx[ARRAY_SIZE(tx)] = {0, };
struct spi_ioc_transfer tr = {
 .tx_buf = (unsigned long)tx,
 .rx_buf = (unsigned long)rx,
 .len = 3,
 .delay_usecs = delay,
 .speed_hz = speed,
 .bits_per_word = bits,
};

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

for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
 if (!(ret % 6))
  puts("");
 printf("%.2X ", rx[ret]);
}
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;
}
 
Old 12-21-2023, 02:27 AM   #2
pippalla
LQ Newbie
 
Registered: Dec 2023
Posts: 1

Rep: Reputation: 0
Question

Hi @chickenwing101 ,

Good Day!

I am also trying to grab information from an ICM-20948 IMU sensor Using SPI.

In my case i used the same code you used for reading the WHO_AM_I register.MISO Always returing the 0xFF 0xFFF

I hope you had an improvement in your side , please help on this same or if you share the piece of code also find


Thanks regards
Pippalla
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Using ioctl SPI_IOC_MESSAGE function Jim232 Linux - Embedded & Single-board computer 3 05-02-2018 11:20 AM
Issues with using ioctl and SIOCGARP to get ARP entry on Linux Kernal bostan Programming 1 08-04-2014 09:59 AM
New monitor, and icm profile Jeebizz Slackware 1 08-13-2008 06:12 PM
How to pass IOCTL arguments from usespace ioctl call devkpict Linux - Kernel 1 12-07-2007 06:45 PM
ICM color profile Vookimedlo Linux - Software 0 12-23-2005 11:18 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer

All times are GMT -5. The time now is 10:08 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration