mirror of
https://github.com/vsergeev/c-periphery.git
synced 2026-08-18 02:54:54 +08:00
spi: add spi_msg_t struct and spi_transfer_advanced() api
This commit is contained in:
+25
@@ -15,6 +15,7 @@ int spi_open_advanced(spi_t *spi, const char *path, unsigned int mode, uint32_t
|
||||
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_transfer_advanced(spi_t *spi, const spi_msg_t *msgs, size_t count);
|
||||
int spi_close(spi_t *spi);
|
||||
void spi_free(spi_t *spi);
|
||||
|
||||
@@ -108,6 +109,30 @@ Returns 0 on success, or a negative [SPI error code](#return-value) on failure.
|
||||
|
||||
------
|
||||
|
||||
``` c
|
||||
typedef struct spi_msg {
|
||||
const uint8_t *txbuf;
|
||||
uint8_t *rxbuf;
|
||||
size_t len;
|
||||
bool deselect;
|
||||
uint16_t deselect_delay_us;
|
||||
uint8_t word_delay_us;
|
||||
} spi_msg_t;
|
||||
|
||||
int spi_transfer_advanced(spi_t *spi, const spi_msg_t *msgs, size_t count);
|
||||
```
|
||||
Transfer messages, shifting out `len` word counts of the `txbuf` buffer, while shifting in `len` word counts to the `rxbuf` buffer for each message. If `deselect` is true, deselect the device before reselecting it for the following transfer.
|
||||
|
||||
`deselect_delay_us` specifies a delay in microseconds before deselection when `deselect` is true. `word_delay_us` specifies a delay in microseconds between words within a transfer. Note that `deselect_delay_us` and `word_delay_us` may not by supported by all SPI controllers and may be silently ignored.
|
||||
|
||||
`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](#return-value) on failure.
|
||||
|
||||
------
|
||||
|
||||
``` c
|
||||
int spi_close(spi_t *spi);
|
||||
```
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "spi.h"
|
||||
|
||||
@@ -164,6 +165,31 @@ int spi_transfer(spi_t *spi, const uint8_t *txbuf, uint8_t *rxbuf, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_transfer_advanced(spi_t *spi, const spi_msg_t *msgs, size_t count) {
|
||||
struct spi_ioc_transfer spi_xfer[count];
|
||||
|
||||
/* Prepare SPI transfer structures */
|
||||
memset(spi_xfer, 0, count * sizeof(struct spi_ioc_transfer));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
spi_xfer[i].tx_buf = (uintptr_t)msgs[i].txbuf;
|
||||
spi_xfer[i].rx_buf = (uintptr_t)msgs[i].rxbuf;
|
||||
spi_xfer[i].len = msgs[i].len;
|
||||
spi_xfer[i].speed_hz = 0;
|
||||
spi_xfer[i].delay_usecs = msgs[i].deselect_delay_us;
|
||||
spi_xfer[i].bits_per_word = 0;
|
||||
spi_xfer[i].cs_change = msgs[i].deselect;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
|
||||
spi_xfer[i].word_delay_usecs = msgs[i].word_delay_us;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Transfer */
|
||||
if (ioctl(spi->fd, SPI_IOC_MESSAGE(count), spi_xfer) < 0)
|
||||
return _spi_error(spi, SPI_ERROR_TRANSFER, errno, "SPI transfer");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_close(spi_t *spi) {
|
||||
if (spi->fd < 0)
|
||||
return 0;
|
||||
|
||||
@@ -12,6 +12,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum spi_error_code {
|
||||
@@ -29,6 +30,15 @@ typedef enum spi_bit_order {
|
||||
LSB_FIRST,
|
||||
} spi_bit_order_t;
|
||||
|
||||
typedef struct spi_msg {
|
||||
const uint8_t *txbuf;
|
||||
uint8_t *rxbuf;
|
||||
size_t len;
|
||||
bool deselect;
|
||||
uint16_t deselect_delay_us;
|
||||
uint8_t word_delay_us;
|
||||
} spi_msg_t;
|
||||
|
||||
typedef struct spi_handle spi_t;
|
||||
|
||||
/* Primary Functions */
|
||||
@@ -42,6 +52,7 @@ 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_transfer_advanced(spi_t *spi, const spi_msg_t *msgs, size_t count);
|
||||
int spi_close(spi_t *spi);
|
||||
void spi_free(spi_t *spi);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user