Replace c-periphery with submodule

This commit is contained in:
Шляк Павел Вячеславович 2022-04-13 12:58:15 +03:00
parent f92b27e439
commit 32e7570259
No known key found for this signature in database
GPG Key ID: A924C155948F097C
9 changed files with 5 additions and 2252 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "sys/arm-linux/c-periphery"]
path = sys/arm-linux/c-periphery
url = https://github.com/vsergeev/c-periphery

@ -0,0 +1 @@
Subproject commit 2379567960b9f72ccfb8f9db7271092612e89bdf

1
sys/arm-linux/drivers Symbolic link
View File

@ -0,0 +1 @@
./c-periphery/src

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +0,0 @@
/*
* c-periphery
* https://github.com/vsergeev/c-periphery
* License: MIT
*/
#ifndef _PERIPHERY_GPIO_H
#define _PERIPHERY_GPIO_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
enum gpio_error_code {
GPIO_ERROR_ARG = -1, /* Invalid arguments */
GPIO_ERROR_OPEN = -2, /* Opening GPIO */
GPIO_ERROR_NOT_FOUND = -3, /* Line name not found */
GPIO_ERROR_QUERY = -4, /* Querying GPIO attributes */
GPIO_ERROR_CONFIGURE = -5, /* Configuring GPIO attributes */
GPIO_ERROR_UNSUPPORTED = -6, /* Unsupported attribute or operation */
GPIO_ERROR_INVALID_OPERATION = -7, /* Invalid operation */
GPIO_ERROR_IO = -8, /* Reading/writing GPIO */
GPIO_ERROR_CLOSE = -9, /* Closing GPIO */
};
typedef enum gpio_direction {
GPIO_DIR_IN, /* Input */
GPIO_DIR_OUT, /* Output, initialized to low */
GPIO_DIR_OUT_LOW, /* Output, initialized to low */
GPIO_DIR_OUT_HIGH, /* Output, initialized to high */
} gpio_direction_t;
typedef enum gpio_edge {
GPIO_EDGE_NONE, /* No interrupt edge */
GPIO_EDGE_RISING, /* Rising edge 0 -> 1 */
GPIO_EDGE_FALLING, /* Falling edge 1 -> 0 */
GPIO_EDGE_BOTH /* Both edges X -> !X */
} gpio_edge_t;
typedef enum gpio_bias {
GPIO_BIAS_DEFAULT, /* Default line bias */
GPIO_BIAS_PULL_UP, /* Pull-up */
GPIO_BIAS_PULL_DOWN, /* Pull-down */
GPIO_BIAS_DISABLE, /* Disable line bias */
} gpio_bias_t;
typedef enum gpio_drive {
GPIO_DRIVE_DEFAULT, /* Default line drive (push-pull) */
GPIO_DRIVE_OPEN_DRAIN, /* Open drain */
GPIO_DRIVE_OPEN_SOURCE, /* Open source */
} gpio_drive_t;
/* Configuration structure for gpio_open_*advanced() functions */
typedef struct gpio_config {
gpio_direction_t direction;
gpio_edge_t edge;
gpio_bias_t bias;
gpio_drive_t drive;
bool inverted;
const char *label; /* Can be NULL for default consumer label */
} gpio_config_t;
typedef struct gpio_handle gpio_t;
/* Primary Functions */
gpio_t *gpio_new(void);
int gpio_open(gpio_t *gpio, const char *path, unsigned int line, gpio_direction_t direction);
int gpio_open_name(gpio_t *gpio, const char *path, const char *name, gpio_direction_t direction);
int gpio_open_advanced(gpio_t *gpio, const char *path, unsigned int line, const gpio_config_t *config);
int gpio_open_name_advanced(gpio_t *gpio, const char *path, const char *name, const gpio_config_t *config);
int gpio_open_sysfs(gpio_t *gpio, unsigned int line, gpio_direction_t direction);
int gpio_read(gpio_t *gpio, bool *value);
int gpio_write(gpio_t *gpio, bool value);
int gpio_poll(gpio_t *gpio, int timeout_ms);
int gpio_close(gpio_t *gpio);
void gpio_free(gpio_t *gpio);
/* Read Event (for character device GPIOs) */
int gpio_read_event(gpio_t *gpio, gpio_edge_t *edge, uint64_t *timestamp);
/* Poll Multiple */
int gpio_poll_multiple(gpio_t **gpios, size_t count, int timeout_ms, bool *gpios_ready);
/* Getters */
int gpio_get_direction(gpio_t *gpio, gpio_direction_t *direction);
int gpio_get_edge(gpio_t *gpio, gpio_edge_t *edge);
int gpio_get_bias(gpio_t *gpio, gpio_bias_t *bias);
int gpio_get_drive(gpio_t *gpio, gpio_drive_t *drive);
int gpio_get_inverted(gpio_t *gpio, bool *inverted);
/* Setters */
int gpio_set_direction(gpio_t *gpio, gpio_direction_t direction);
int gpio_set_edge(gpio_t *gpio, gpio_edge_t edge);
int gpio_set_bias(gpio_t *gpio, gpio_bias_t bias);
int gpio_set_drive(gpio_t *gpio, gpio_drive_t drive);
int gpio_set_inverted(gpio_t *gpio, bool inverted);
/* Miscellaneous Properties */
unsigned int gpio_line(gpio_t *gpio);
int gpio_fd(gpio_t *gpio);
int gpio_name(gpio_t *gpio, char *str, size_t len);
int gpio_label(gpio_t *gpio, char *str, size_t len);
int gpio_chip_fd(gpio_t *gpio);
int gpio_chip_name(gpio_t *gpio, char *str, size_t len);
int gpio_chip_label(gpio_t *gpio, char *str, size_t len);
int gpio_tostring(gpio_t *gpio, char *str, size_t len);
/* Error Handling */
int gpio_errno(gpio_t *gpio);
const char *gpio_errmsg(gpio_t *gpio);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,136 +0,0 @@
/*
* c-periphery
* https://github.com/vsergeev/c-periphery
* License: MIT
*/
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "i2c.h"
struct i2c_handle {
int fd;
struct {
int c_errno;
char errmsg[96];
} error;
};
static int _i2c_error(i2c_t *i2c, int code, int c_errno, const char *fmt, ...) {
va_list ap;
i2c->error.c_errno = c_errno;
va_start(ap, fmt);
vsnprintf(i2c->error.errmsg, sizeof(i2c->error.errmsg), fmt, ap);
va_end(ap);
/* Tack on strerror() and errno */
if (c_errno) {
char buf[64];
strerror_r(c_errno, buf, sizeof(buf));
snprintf(i2c->error.errmsg+strlen(i2c->error.errmsg), sizeof(i2c->error.errmsg)-strlen(i2c->error.errmsg), ": %s [errno %d]", buf, c_errno);
}
return code;
}
i2c_t *i2c_new(void) {
i2c_t *i2c = calloc(1, sizeof(i2c_t));
if (i2c == NULL)
return NULL;
i2c->fd = -1;
return i2c;
}
void i2c_free(i2c_t *i2c) {
free(i2c);
}
int i2c_open(i2c_t *i2c, const char *path) {
unsigned long supported_funcs;
memset(i2c, 0, sizeof(i2c_t));
/* Open device */
if ((i2c->fd = open(path, O_RDWR)) < 0)
return _i2c_error(i2c, I2C_ERROR_OPEN, errno, "Opening I2C device \"%s\"", path);
/* Query supported functions */
if (ioctl(i2c->fd, I2C_FUNCS, &supported_funcs) < 0) {
int errsv = errno;
close(i2c->fd);
i2c->fd = -1;
return _i2c_error(i2c, I2C_ERROR_QUERY, errsv, "Querying I2C functions");
}
if (!(supported_funcs & I2C_FUNC_I2C)) {
close(i2c->fd);
i2c->fd = -1;
return _i2c_error(i2c, I2C_ERROR_NOT_SUPPORTED, 0, "I2C not supported on %s", path);
}
return 0;
}
int i2c_transfer(i2c_t *i2c, struct i2c_msg *msgs, size_t count) {
struct i2c_rdwr_ioctl_data i2c_rdwr_data;
/* Prepare I2C transfer structure */
memset(&i2c_rdwr_data, 0, sizeof(struct i2c_rdwr_ioctl_data));
i2c_rdwr_data.msgs = msgs;
i2c_rdwr_data.nmsgs = count;
/* Transfer */
if (ioctl(i2c->fd, I2C_RDWR, &i2c_rdwr_data) < 0)
return _i2c_error(i2c, I2C_ERROR_TRANSFER, errno, "I2C transfer");
return 0;
}
int i2c_close(i2c_t *i2c) {
if (i2c->fd < 0)
return 0;
/* Close fd */
if (close(i2c->fd) < 0)
return _i2c_error(i2c, I2C_ERROR_CLOSE, errno, "Closing I2C device");
i2c->fd = -1;
return 0;
}
int i2c_tostring(i2c_t *i2c, char *str, size_t len) {
return snprintf(str, len, "I2C (fd=%d)", i2c->fd);
}
const char *i2c_errmsg(i2c_t *i2c) {
return i2c->error.errmsg;
}
int i2c_errno(i2c_t *i2c) {
return i2c->error.c_errno;
}
int i2c_fd(i2c_t *i2c) {
return i2c->fd;
}

View File

@ -1,70 +0,0 @@
/*
* c-periphery
* https://github.com/vsergeev/c-periphery
* License: MIT
*/
#ifndef _PERIPHERY_I2C_H
#define _PERIPHERY_I2C_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
#include <limits.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
enum i2c_error_code {
I2C_ERROR_ARG = -1, /* Invalid arguments */
I2C_ERROR_OPEN = -2, /* Opening I2C device */
I2C_ERROR_QUERY = -3, /* Querying I2C device attributes */
I2C_ERROR_NOT_SUPPORTED = -4, /* I2C not supported on this device */
I2C_ERROR_TRANSFER = -5, /* I2C transfer */
I2C_ERROR_CLOSE = -6, /* Closing I2C device */
};
typedef struct i2c_handle i2c_t;
/* Primary Functions */
i2c_t *i2c_new(void);
int i2c_open(i2c_t *i2c, const char *path);
int i2c_transfer(i2c_t *i2c, struct i2c_msg *msgs, size_t count);
int i2c_close(i2c_t *i2c);
void i2c_free(i2c_t *i2c);
/* Miscellaneous */
int i2c_fd(i2c_t *i2c);
int i2c_tostring(i2c_t *i2c, char *str, size_t len);
/* Error Handling */
int i2c_errno(i2c_t *i2c);
const char *i2c_errmsg(i2c_t *i2c);
/* struct i2c_msg from <linux/i2c.h>:
struct i2c_msg {
__u16 addr;
__u16 flags;
#define I2C_M_TEN 0x0010
#define I2C_M_RD 0x0001
#define I2C_M_STOP 0x8000
#define I2C_M_NOSTART 0x4000
#define I2C_M_REV_DIR_ADDR 0x2000
#define I2C_M_IGNORE_NAK 0x1000
#define I2C_M_NO_RD_ACK 0x0800
#define I2C_M_RECV_LEN 0x0400
__u16 len;
__u8 *buf;
};
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,404 +0,0 @@
/*
* c-periphery
* https://github.com/vsergeev/c-periphery
* License: MIT
*/
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <linux/spi/spidev.h>
#include "spi.h"
struct spi_handle {
int fd;
struct {
int c_errno;
char errmsg[96];
} error;
};
static int _spi_error(spi_t *spi, int code, int c_errno, const char *fmt, ...) {
va_list ap;
spi->error.c_errno = c_errno;
va_start(ap, fmt);
vsnprintf(spi->error.errmsg, sizeof(spi->error.errmsg), fmt, ap);
va_end(ap);
/* Tack on strerror() and errno */
if (c_errno) {
char buf[64];
strerror_r(c_errno, buf, sizeof(buf));
snprintf(spi->error.errmsg+strlen(spi->error.errmsg), sizeof(spi->error.errmsg)-strlen(spi->error.errmsg), ": %s [errno %d]", buf, c_errno);
}
return code;
}
spi_t *spi_new(void) {
spi_t *spi = calloc(1, sizeof(spi_t));
if (spi == NULL)
return NULL;
spi->fd = -1;
return spi;
}
void spi_free(spi_t *spi) {
free(spi);
}
int spi_open(spi_t *spi, const char *path, unsigned int mode, uint32_t max_speed) {
return spi_open_advanced(spi, path, mode, max_speed, MSB_FIRST, 8, 0);
}
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) {
return spi_open_advanced2(spi, path, mode, max_speed, bit_order, bits_per_word, extra_flags);
}
int spi_open_advanced2(spi_t *spi, const char *path, unsigned int mode, uint32_t max_speed, spi_bit_order_t bit_order, uint8_t bits_per_word, uint32_t extra_flags) {
uint32_t data32;
uint8_t data8;
/* Validate arguments */
if (mode & ~0x3)
return _spi_error(spi, SPI_ERROR_ARG, 0, "Invalid mode (can be 0,1,2,3)");
if (bit_order != MSB_FIRST && bit_order != LSB_FIRST)
return _spi_error(spi, SPI_ERROR_ARG, 0, "Invalid bit order (can be MSB_FIRST,LSB_FIRST)");
#ifndef SPI_IOC_WR_MODE32
if (extra_flags > 0xff)
return _spi_error(spi, SPI_ERROR_UNSUPPORTED, 0, "Kernel version does not support 32-bit SPI mode flags");
#endif
memset(spi, 0, sizeof(spi_t));
/* Open device */
if ((spi->fd = open(path, O_RDWR)) < 0)
return _spi_error(spi, SPI_ERROR_OPEN, errno, "Opening SPI device \"%s\"", path);
/* Set mode, bit order, extra flags */
#ifndef SPI_IOC_WR_MODE32
(void)data32;
data8 = mode | ((bit_order == LSB_FIRST) ? SPI_LSB_FIRST : 0) | extra_flags;
if (ioctl(spi->fd, SPI_IOC_WR_MODE, &data8) < 0) {
int errsv = errno;
close(spi->fd);
spi->fd = -1;
return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI mode");
}
#else
if (extra_flags > 0xff) {
/* Use 32-bit mode if extra_flags is wider than 8-bits */
data32 = mode | ((bit_order == LSB_FIRST) ? SPI_LSB_FIRST : 0) | extra_flags;
if (ioctl(spi->fd, SPI_IOC_WR_MODE32, &data32) < 0) {
int errsv = errno;
close(spi->fd);
spi->fd = -1;
return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI mode");
}
} else {
/* Prefer 8-bit mode, in case this library is inadvertently used on an
* older kernel. */
data8 = mode | ((bit_order == LSB_FIRST) ? SPI_LSB_FIRST : 0) | extra_flags;
if (ioctl(spi->fd, SPI_IOC_WR_MODE, &data8) < 0) {
int errsv = errno;
close(spi->fd);
spi->fd = -1;
return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI mode");
}
}
#endif
/* Set max speed */
if (ioctl(spi->fd, SPI_IOC_WR_MAX_SPEED_HZ, &max_speed) < 0) {
int errsv = errno;
close(spi->fd);
spi->fd = -1;
return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI max speed");
}
/* Set bits per word */
if (ioctl(spi->fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) < 0) {
int errsv = errno;
close(spi->fd);
spi->fd = -1;
return _spi_error(spi, SPI_ERROR_CONFIGURE, errsv, "Setting SPI bits per word");
}
return 0;
}
int spi_transfer(spi_t *spi, const uint8_t *txbuf, uint8_t *rxbuf, size_t len) {
struct spi_ioc_transfer spi_xfer;
/* Prepare SPI transfer structure */
memset(&spi_xfer, 0, sizeof(struct spi_ioc_transfer));
spi_xfer.tx_buf = (uintptr_t)txbuf;
spi_xfer.rx_buf = (uintptr_t)rxbuf;
spi_xfer.len = len;
spi_xfer.delay_usecs = 0;
spi_xfer.speed_hz = 0;
spi_xfer.bits_per_word = 0;
spi_xfer.cs_change = 0;
/* Transfer */
if (ioctl(spi->fd, SPI_IOC_MESSAGE(1), &spi_xfer) < 1)
return _spi_error(spi, SPI_ERROR_TRANSFER, errno, "SPI transfer");
return 0;
}
int spi_close(spi_t *spi) {
if (spi->fd < 0)
return 0;
/* Close fd */
if (close(spi->fd) < 0)
return _spi_error(spi, SPI_ERROR_CLOSE, errno, "Closing SPI device");
spi->fd = -1;
return 0;
}
int spi_get_mode(spi_t *spi, unsigned int *mode) {
uint8_t data8;
if (ioctl(spi->fd, SPI_IOC_RD_MODE, &data8) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI mode");
*mode = data8 & (SPI_CPHA | SPI_CPOL);
return 0;
}
int spi_get_max_speed(spi_t *spi, uint32_t *max_speed) {
uint32_t data32;
if (ioctl(spi->fd, SPI_IOC_RD_MAX_SPEED_HZ, &data32) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI max speed");
*max_speed = data32;
return 0;
}
int spi_get_bit_order(spi_t *spi, spi_bit_order_t *bit_order) {
uint8_t data8;
if (ioctl(spi->fd, SPI_IOC_RD_LSB_FIRST, &data8) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI bit order");
if (data8)
*bit_order = LSB_FIRST;
else
*bit_order = MSB_FIRST;
return 0;
}
int spi_get_bits_per_word(spi_t *spi, uint8_t *bits_per_word) {
uint8_t data8;
if (ioctl(spi->fd, SPI_IOC_RD_BITS_PER_WORD, &data8) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI bits per word");
*bits_per_word = data8;
return 0;
}
int spi_get_extra_flags(spi_t *spi, uint8_t *extra_flags) {
uint8_t data8;
if (ioctl(spi->fd, SPI_IOC_RD_MODE, &data8) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI mode flags");
/* Extra mode flags without mode 0-3 and bit order */
*extra_flags = data8 & ~( SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST );
return 0;
}
int spi_get_extra_flags32(spi_t *spi, uint32_t *extra_flags) {
#ifdef SPI_IOC_RD_MODE32
uint32_t mode32;
if (ioctl(spi->fd, SPI_IOC_RD_MODE32, &mode32) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting 32-bit SPI mode flags");
/* Extra mode flags without mode 0-3 and bit order */
*extra_flags = mode32 & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST);
return 0;
#else
(void)extra_flags;
return _spi_error(spi, SPI_ERROR_UNSUPPORTED, 0, "Kernel version does not support 32-bit SPI mode flags");
#endif
}
int spi_set_mode(spi_t *spi, unsigned int mode) {
uint8_t data8;
if (mode & ~0x3)
return _spi_error(spi, SPI_ERROR_ARG, 0, "Invalid mode (can be 0,1,2,3)");
if (ioctl(spi->fd, SPI_IOC_RD_MODE, &data8) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI mode");
data8 &= ~(SPI_CPOL | SPI_CPHA);
data8 |= mode;
if (ioctl(spi->fd, SPI_IOC_WR_MODE, &data8) < 0)
return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI mode");
return 0;
}
int spi_set_bit_order(spi_t *spi, spi_bit_order_t bit_order) {
uint8_t data8;
if (bit_order != MSB_FIRST && bit_order != LSB_FIRST)
return _spi_error(spi, SPI_ERROR_ARG, 0, "Invalid bit order (can be MSB_FIRST,LSB_FIRST)");
if (bit_order == LSB_FIRST)
data8 = 1;
else
data8 = 0;
if (ioctl(spi->fd, SPI_IOC_WR_LSB_FIRST, &data8) < 0)
return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI bit order");
return 0;
}
int spi_set_extra_flags(spi_t *spi, uint8_t extra_flags) {
uint8_t data8;
if (ioctl(spi->fd, SPI_IOC_RD_MODE, &data8) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting SPI mode flags");
/* Keep mode 0-3 and bit order */
data8 &= (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST);
/* Set extra flags */
data8 |= extra_flags;
if (ioctl(spi->fd, SPI_IOC_WR_MODE, &data8) < 0)
return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI mode flags");
return 0;
}
int spi_set_extra_flags32(spi_t *spi, uint32_t extra_flags) {
#ifdef SPI_IOC_WR_MODE32
uint32_t mode32;
if (ioctl(spi->fd, SPI_IOC_RD_MODE32, &mode32) < 0)
return _spi_error(spi, SPI_ERROR_QUERY, errno, "Getting 32-bit SPI mode flags");
/* Keep mode 0-3 and bit order */
mode32 &= (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST);
/* Set extra flags */
mode32 |= extra_flags;
if (ioctl(spi->fd, SPI_IOC_WR_MODE32, &mode32) < 0)
return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting 32-bit SPI mode flags");
return 0;
#else
(void)extra_flags;
return _spi_error(spi, SPI_ERROR_UNSUPPORTED, 0, "Kernel version does not support 32-bit SPI mode flags");
#endif
}
int spi_set_max_speed(spi_t *spi, uint32_t max_speed) {
if (ioctl(spi->fd, SPI_IOC_WR_MAX_SPEED_HZ, &max_speed) < 0)
return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI max speed");
return 0;
}
int spi_set_bits_per_word(spi_t *spi, uint8_t bits_per_word) {
if (ioctl(spi->fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) < 0)
return _spi_error(spi, SPI_ERROR_CONFIGURE, errno, "Setting SPI bits per word");
return 0;
}
int spi_tostring(spi_t *spi, char *str, size_t len) {
unsigned int mode;
char mode_str[2];
uint32_t max_speed;
char max_speed_str[16];
uint8_t bits_per_word;
char bits_per_word_str[4];
spi_bit_order_t bit_order;
const char *bit_order_str;
uint8_t extra_flags8;
uint32_t extra_flags32;
char extra_flags_str[11];
if (spi_get_mode(spi, &mode) < 0)
strcpy(mode_str, "?");
else
snprintf(mode_str, sizeof(mode_str), "%u", mode);
if (spi_get_max_speed(spi, &max_speed) < 0)
strcpy(max_speed_str, "?");
else
snprintf(max_speed_str, sizeof(max_speed_str), "%u", max_speed);
if (spi_get_bit_order(spi, &bit_order) < 0)
bit_order_str = "?";
else
bit_order_str = (bit_order == LSB_FIRST) ? "LSB_FIRST" : "MSB_FIRST";
if (spi_get_bits_per_word(spi, &bits_per_word) < 0)
strcpy(bits_per_word_str, "?");
else
snprintf(bits_per_word_str, sizeof(bits_per_word_str), "%u", bits_per_word);
if (spi_get_extra_flags32(spi, &extra_flags32) < 0) {
if (spi_get_extra_flags(spi, &extra_flags8) < 0)
strcpy(extra_flags_str, "?");
else
snprintf(extra_flags_str, sizeof(extra_flags_str), "0x%02x", extra_flags8);
} else {
snprintf(extra_flags_str, sizeof(extra_flags_str), "0x%08x", extra_flags32);
}
return snprintf(str, len, "SPI (fd=%d, mode=%s, max_speed=%s, bit_order=%s, bits_per_word=%s, extra_flags=%s)", spi->fd, mode_str, max_speed_str, bit_order_str, bits_per_word_str, extra_flags_str);
}
const char *spi_errmsg(spi_t *spi) {
return spi->error.errmsg;
}
int spi_errno(spi_t *spi) {
return spi->error.c_errno;
}
int spi_fd(spi_t *spi) {
return spi->fd;
}

View File

@ -1,77 +0,0 @@
/*
* c-periphery
* https://github.com/vsergeev/c-periphery
* License: MIT
*/
#ifndef _PERIPHERY_SPI_H
#define _PERIPHERY_SPI_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
enum spi_error_code {
SPI_ERROR_ARG = -1, /* Invalid arguments */
SPI_ERROR_OPEN = -2, /* Opening SPI device */
SPI_ERROR_QUERY = -3, /* Querying SPI device attributes */
SPI_ERROR_CONFIGURE = -4, /* Configuring SPI device attributes */
SPI_ERROR_TRANSFER = -5, /* SPI transfer */
SPI_ERROR_CLOSE = -6, /* Closing SPI device */
SPI_ERROR_UNSUPPORTED = -7, /* Unsupported attribute or operation */
};
typedef enum spi_bit_order {
MSB_FIRST,
LSB_FIRST,
} spi_bit_order_t;
typedef struct spi_handle spi_t;
/* Primary Functions */
spi_t *spi_new(void);
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_open_advanced2(spi_t *spi, const char *path, unsigned int mode,
uint32_t max_speed, spi_bit_order_t bit_order,
uint8_t bits_per_word, uint32_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);
void spi_free(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);
int spi_get_extra_flags32(spi_t *spi, uint32_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);
int spi_set_extra_flags32(spi_t *spi, uint32_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);
#ifdef __cplusplus
}
#endif
#endif