Personal tools

Difference between revisions of "How to use VisionSOM-6ULL SPI interface in C programs"

From SomLabs Wiki

Jump to: navigation, search
(Created page with "{{PageHeader|How to use VisionSOM-6ULL SPI interface in C programs}} == Configuring device tree to enable I2C interface == To enable SPI interface you may need to add (or mo...")
 
 
Line 116: Line 116:
 
         if (result == 1)
 
         if (result == 1)
 
                 handleError("Sending SPI frame failed!");
 
                 handleError("Sending SPI frame failed!");
 
 
        for (int i = 1; i < 7; i++) printf("%2x, ", rx[i]);
 
        printf("\n");
 
  
 
         *x = (int)(rx[1] | (rx[2] << 8));
 
         *x = (int)(rx[1] | (rx[2] << 8));
Line 154: Line 150:
  
 
}</pre>
 
}</pre>
 +
 +
 +
[[File:Visionsom6-ull-spi-example.jpg|center|VisionSOM-6ULL i.MX6 SPI Example]]

Latest revision as of 00:43, 23 November 2017

How to use VisionSOM-6ULL SPI interface in C programs


Configuring device tree to enable I2C interface

To enable SPI interface you may need to add (or modify) interface definition, your dts file should contain:

&ecspi3 {
    fsl,spi-num-chipselects = <1>;
    cs-gpios = <&gpio1 20 0>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_spi3>;
    status = "okay";
    spidev@0 {
        compatible = "spidev";
        spi-max-frequency = <1000000>;
        reg = <0>;
    };
};

Line GPIO1_20 will be used as CS (Chip Select).

In iomux section add or modify SPI pin definition:

                pinctrl_spi3: spi3grp {
                        fsl,pins= <
                                MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI      0x100b1
                                MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x100b1
                                MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20     0x100b1
                                MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO      0x100b1
                        >;
                };

Those definitions may need modifications depending on which interface and pins you want to use. You can find more informations on customizing device tree in this tutorial. In this example there is used VisionSOM-6ULL, VisionCB-STD and KAmodL3GD20 module with L3GD20 gyroscope). KAmodL3GD20 module is connected to Raspberry Pi connector on VisionCB-STD:

VisionSOM-CB-STD RPi connector pin number KAmodL3GD20 pin
VCC-3V3 +3.3V
GND GND
UART2-CTS SDA
UART2-RXD SCL
UART2-RTS SDO
UART2-TXD CS


Using SPI interface in C program

The program below writes 0xFF to L3GD20 CTRL1 register (address 0x20) in function configL3GD20, then it reads 6 registers (addresses 0x28, 0x29...) to read gyroscope X, Y and Z values in function readL3DG20. Note that if you would use write and read functions instead of ioctl(fd, SPI_IOC_MESSAGE(1), &tr) the program would not work, because CS line would go high between read and write calls.


#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <linux/spi/spidev.h>
#include <linux/types.h>
#include <stdint.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/ioctl.h>


void handleError(char * msg) {
        printf("Error: %s", msg);
        abort();
}

void configL3GD20(int fd) {
        int result;
        uint8_t tx[] = {0x20, 0xFF};
        uint8_t rx[] = {0, 0, };
        struct spi_ioc_transfer tr = {
                .tx_buf = (unsigned long)tx,
                .rx_buf = (unsigned long)rx,
                .len = 2,
                .delay_usecs = 0,
                .speed_hz = 0,
                .bits_per_word = 0,
        };

        result = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
        if (result == 1)
                handleError("Sending SPI frame failed!");
}


void readL3DG20(int fd, int *x, int *y, int *z) {
        int result;
        uint8_t tx[] = {0x28 | (1<<7) | (1<<6), 0, 0, 0, 0, 0, 0};
        uint8_t rx[] = {0, 0, 0, 0, 0, 0, 0};
        struct spi_ioc_transfer tr = {
                .tx_buf = (unsigned long)tx,
                .rx_buf = (unsigned long)rx,
                .len = 7,
                .delay_usecs = 0,
                .speed_hz = 0,
                .bits_per_word = 0,
        };

        result = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
        if (result == 1)
                handleError("Sending SPI frame failed!");

        *x = (int)(rx[1] | (rx[2] << 8));
        *y = (int)(rx[3] | (rx[4] << 8));
        *z = (int)(rx[5] | (rx[6] << 8));
}


int main() {
        int fd = open("/dev/spidev2.0", O_RDWR);
        int result;
        static uint8_t mode = SPI_MODE_3;
        static uint32_t speed = 1000000;
        int x, y, z;

        result = ioctl(fd, SPI_IOC_WR_MODE, &mode);
        if (result == -1)
                handleError("Setting SPI mode failed!");

        result = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
        if (result == -1)
                printf("Setting SPI speed failed!");

        if (fd >= 0) {
                configL3GD20(fd);

                readL3DG20(fd, &x, &y, &z);

                printf("x=%5d, y=%5d, z=%5d\n", x, y, z);

                close(fd);
        }
        else printf("open err %d\n", errno);

}


VisionSOM-6ULL i.MX6 SPI Example
NXP Partner ST Partner Renesas Partner