Skip to content

Latest commit

 

History

History
210 lines (148 loc) · 6.99 KB

spi.md

File metadata and controls

210 lines (148 loc) · 6.99 KB

NAME

SPI wrapper functions for Linux userspace spidev devices.

SYNOPSIS

#include <periphery/spi.h>

/* Primary Functions */
int spi_open(spi_t *spi, const char *path, unsigned int mode, uint32_t max_speed);
int spi_open_advanced(spi_t *spi, const char *path, unsigned int mode,
                        uint32_t max_speed, spi_bit_order_t bit_order,
                        uint8_t bits_per_word, uint8_t extra_flags);
int spi_transfer(spi_t *spi, const uint8_t *txbuf, uint8_t *rxbuf, size_t len);
int spi_close(spi_t *spi);

/* Getters */
int spi_get_mode(spi_t *spi, unsigned int *mode);
int spi_get_max_speed(spi_t *spi, uint32_t *max_speed);
int spi_get_bit_order(spi_t *spi, spi_bit_order_t *bit_order);
int spi_get_bits_per_word(spi_t *spi, uint8_t *bits_per_word);
int spi_get_extra_flags(spi_t *spi, uint8_t *extra_flags);

/* Setters */
int spi_set_mode(spi_t *spi, unsigned int mode);
int spi_set_max_speed(spi_t *spi, uint32_t max_speed);
int spi_set_bit_order(spi_t *spi, spi_bit_order_t bit_order);
int spi_set_bits_per_word(spi_t *spi, uint8_t bits_per_word);
int spi_set_extra_flags(spi_t *spi, uint8_t extra_flags);

/* Miscellaneous */
int spi_fd(spi_t *spi);
int spi_tostring(spi_t *spi, char *str, size_t len);

/* Error Handling */
int spi_errno(spi_t *spi);
const char *spi_errmsg(spi_t *spi);

ENUMERATIONS

  • spi_bit_order_t
    • MSB_FIRST: Most significant bit first transfer (typical)
    • LSB_FIRST: Least significant bit first transfer

DESCRIPTION

int spi_open(spi_t *spi, const char *path, unsigned int mode, uint32_t max_speed);

Open the spidev device at the specified path (e.g. "/dev/spidev1.0"), with the specified SPI mode, specified max speed in hertz, and the defaults of MSB_FIRST bit order, and 8 bits per word.

spi should be a valid pointer to an allocated SPI handle structure. SPI mode can be 0, 1, 2, or 3.

Returns 0 on success, or a negative SPI error code on failure.


int spi_open_advanced(spi_t *spi, const char *path, unsigned int mode, uint32_t max_speed,
                        spi_bit_order_t bit_order, uint8_t bits_per_word, uint8_t extra_flags);

Open the spidev device at the specified path, with the specified SPI mode, max speed in hertz, bit order, bits per word, and extra flags.

spi should be a valid pointer to an allocated SPI handle structure. SPI mode can be 0, 1, 2, or 3. Bit order can be MSB_FIRST or LSB_FIRST, as defined above. Bits per word specifies the transfer word size. Extra flags specified additional flags bitwise-ORed with the SPI mode.

Returns 0 on success, or a negative SPI error code on failure.


int spi_transfer(spi_t *spi, const uint8_t *txbuf, uint8_t *rxbuf, size_t len);

Shift out len word counts of the txbuf buffer, while shifting in len word counts to the rxbuf buffer.

spi should be a valid pointer to an SPI handle opened with spi_open() or spi_open_advanced().

rxbuf may be NULL. txbuf and rxbuf may point to the same buffer.

Returns 0 on success, or a negative SPI error code on failure.


int spi_close(spi_t *spi);

Close the spidev device.

spi should be a valid pointer to an SPI handle opened with spi_open() or spi_open_advanced().

Returns 0 on success, or a negative SPI error code on failure.


int spi_get_mode(spi_t *spi, unsigned int *mode);
int spi_get_max_speed(spi_t *spi, uint32_t *max_speed);
int spi_get_bit_order(spi_t *spi, spi_bit_order_t *bit_order);
int spi_get_bits_per_word(spi_t *spi, uint8_t *bits_per_word);
int spi_get_extra_flags(spi_t *spi, uint8_t *extra_flags);

Query the mode, max speed, bit order, bits per word, or extra flags, respectively, of the underlying spidev device.

spi should be a valid pointer to a SPI handle opened with spi_open() or spi_open_advanced().

Returns 0 on success, or a negative SPI error code on failure.


int spi_set_mode(spi_t *spi, unsigned int mode);
int spi_set_max_speed(spi_t *spi, uint32_t max_speed);
int spi_set_bit_order(spi_t *spi, spi_bit_order_t bit_order);
int spi_set_bits_per_word(spi_t *spi, uint8_t bits_per_word);
int spi_set_extra_flags(spi_t *spi, uint8_t extra_flags);

Set the mode, max speed, bit order, bits per word, or extra flags, respectively, on the underlying spidev device.

spi should be a valid pointer to a SPI handle opened with spi_open() or spi_open_advanced().

Returns 0 on success, or a negative SPI error code on failure.


int spi_fd(spi_t *spi);

Return the file descriptor (for the underlying spidev device) of the SPI handle.

spi should be a valid pointer to a SPI handle opened with spi_open() or spi_open_advanced().

This function is a simple accessor to the SPI handle structure and always succeeds.


int spi_tostring(spi_t *spi, char *str, size_t len);

Return a string representation of the SPI handle.

spi should be a valid pointer to a SPI handle opened with spi_open() or spi_open_advanced().

This function behaves and returns like snprintf().


int spi_errno(spi_t *spi);

Return the libc errno of the last failure that occurred.

spi should be a valid pointer to a SPI handle opened with spi_open() or spi_open_advanced().


const char *spi_errmsg(spi_t *spi);

Return a human readable error message of the last failure that occurred.

spi should be a valid pointer to a SPI handle opened with spi_open() or spi_open_advanced().

RETURN VALUE

The periphery SPI functions return 0 on success or one of the negative error codes below on failure.

The libc errno of the failure in an underlying libc library call can be obtained with the spi_errno() helper function. A human readable error message can be obtained with the spi_errmsg() helper function.

Error Code Description
SPI_ERROR_ARG Invalid arguments
SPI_ERROR_OPEN Opening SPI device
SPI_ERROR_QUERY Querying SPI device settings
SPI_ERROR_CONFIGURE Configuring SPI device
SPI_ERROR_TRANSFER SPI transfer
SPI_ERROR_CLOSE Closing SPI device

EXAMPLE

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "spi.h"

int main(void) {
    spi_t spi;
    uint8_t buf[4] = { 0xaa, 0xbb, 0xcc, 0xdd };

    /* Open spidev1.0 with mode 0 and max speed 1MHz */
    if (spi_open(&spi, "/dev/spidev1.0", 0, 1000000) < 0) {
        fprintf(stderr, "spi_open(): %s\n", spi_errmsg(&spi));
        exit(1);
    }

    /* Shift out and in 4 bytes */
    if (spi_transfer(&spi, buf, buf, sizeof(buf)) < 0) {
        fprintf(stderr, "spi_transfer(): %s\n", spi_errmsg(&spi));
        exit(1);
    }

    printf("shifted in: 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[0], buf[1], buf[2], buf[3]);

    spi_close(&spi);
    return 0;
}