SPI working! when using SPI, the order of writing out ctrl_reg's matters....but seemingly not when using i2c
This commit is contained in:
parent
f6020e9d15
commit
485922d898
@ -21,7 +21,7 @@ See the `examples/` dir for complete code examples
|
|||||||
## Implementation
|
## Implementation
|
||||||
This driver requires the user to implement the following interface functions:
|
This driver requires the user to implement the following interface functions:
|
||||||
|
|
||||||
This project has example interface code for I2C and SPI (broken) used on Raspberry Pi 4.
|
This project has example interface code for I2C and SPI used on Raspberry Pi 4.
|
||||||
```c
|
```c
|
||||||
/* initialise the "interface" */
|
/* initialise the "interface" */
|
||||||
int init(void);
|
int init(void);
|
||||||
@ -52,6 +52,9 @@ int i2c_write(uint8_t reg, uint8_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
||||||
|
if (size > 1) {
|
||||||
|
reg |= 0x80; /* auto-increment bit */
|
||||||
|
}
|
||||||
uint8_t send[2] = { reg, 0x00 };
|
uint8_t send[2] = { reg, 0x00 };
|
||||||
HAL_I2C_Master_Transmit(&hi2c2, LIS3DH_I2C_ADDR << 1, send, 2, HAL_MAX_DELAY);
|
HAL_I2C_Master_Transmit(&hi2c2, LIS3DH_I2C_ADDR << 1, send, 2, HAL_MAX_DELAY);
|
||||||
HAL_I2C_Master_Receive(&hi2c2, LIS3DH_I2C_ADDR << 1, dst, size, HAL_MAX_DELAY);
|
HAL_I2C_Master_Receive(&hi2c2, LIS3DH_I2C_ADDR << 1, dst, size, HAL_MAX_DELAY);
|
||||||
|
19
i2c.c
19
i2c.c
@ -24,19 +24,19 @@ Example I2C use on linux/raspberry pi
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define I2C_DEVICE "/dev/i2c-1"
|
#define I2C_DEVICE "/dev/i2c-1"
|
||||||
#define I2C_LIS3DH_ADDRESS 0x18
|
#define I2C_LIS3DH_ADDRESS 0x18 /* Can also be 0x19 */
|
||||||
|
|
||||||
static int fd;
|
static int fd;
|
||||||
|
|
||||||
int i2c_init(void) {
|
int i2c_init(void) {
|
||||||
fd = open(I2C_DEVICE, O_RDWR);
|
fd = open(I2C_DEVICE, O_RDWR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr, "[i2c] could not open device: %s\n", I2C_DEVICE);
|
fprintf(stderr, "i2c_init(): could not open device: %s\n", I2C_DEVICE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, I2C_SLAVE, I2C_LIS3DH_ADDRESS) < 0) {
|
if (ioctl(fd, I2C_SLAVE, I2C_LIS3DH_ADDRESS) < 0) {
|
||||||
fprintf(stderr, "[i2c] failed to acquire bus/talk to slave\n");
|
fprintf(stderr, "i2c_init(): failed to acquire bus/talk to slave\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -44,7 +44,6 @@ int i2c_init(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
||||||
uint8_t cmd[2];
|
uint8_t cmd[2];
|
||||||
|
|
||||||
@ -55,10 +54,13 @@ int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
|||||||
cmd[0] = reg;
|
cmd[0] = reg;
|
||||||
cmd[1] = 0x00;
|
cmd[1] = 0x00;
|
||||||
|
|
||||||
write(fd, cmd, 2);
|
if (write(fd, cmd, 2) != 2) {
|
||||||
|
fprintf(stderr, "i2c_read(): error write()\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (read(fd, dst, size) != (ssize_t)size) {
|
if (read(fd, dst, size) != (int)size) {
|
||||||
fprintf(stderr, "[i2c] error read()\n");
|
fprintf(stderr, "i2c_read(): error read()\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -66,7 +68,6 @@ int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int i2c_write(uint8_t reg, uint8_t value) {
|
int i2c_write(uint8_t reg, uint8_t value) {
|
||||||
uint8_t cmd[2];
|
uint8_t cmd[2];
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ int i2c_write(uint8_t reg, uint8_t value) {
|
|||||||
cmd[1] = value;
|
cmd[1] = value;
|
||||||
|
|
||||||
if (write(fd, cmd, 2) != 2) {
|
if (write(fd, cmd, 2) != 2) {
|
||||||
fprintf(stderr, "[i2c] error write()\n");
|
fprintf(stderr, "i2c_write(): error write()\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
lis3dh.c
22
lis3dh.c
@ -175,7 +175,9 @@ int lis3dh_configure(lis3dh_t *lis3dh) {
|
|||||||
ctrl_reg0 |= 0x10;
|
ctrl_reg0 |= 0x10;
|
||||||
ctrl_reg0 |= (lis3dh->cfg.sdo_pullup & 1) << 7;
|
ctrl_reg0 |= (lis3dh->cfg.sdo_pullup & 1) << 7;
|
||||||
|
|
||||||
/* write these before the control regs that start the device */
|
err |= lis3dh->dev.write(REG_CTRL_REG4, ctrl_reg4);
|
||||||
|
err |= lis3dh->dev.write(REG_CTRL_REG5, ctrl_reg5);
|
||||||
|
|
||||||
err |= lis3dh->dev.write(REG_FIFO_CTRL_REG, fifo_ctrl_reg);
|
err |= lis3dh->dev.write(REG_FIFO_CTRL_REG, fifo_ctrl_reg);
|
||||||
err |= lis3dh->dev.write(REG_INT1_CFG, int1_cfg);
|
err |= lis3dh->dev.write(REG_INT1_CFG, int1_cfg);
|
||||||
err |= lis3dh->dev.write(REG_INT1_THS, int1_ths);
|
err |= lis3dh->dev.write(REG_INT1_THS, int1_ths);
|
||||||
@ -193,16 +195,15 @@ int lis3dh_configure(lis3dh_t *lis3dh) {
|
|||||||
err |= lis3dh->dev.write(REG_TEMP_CFG_REG, temp_cfg_reg);
|
err |= lis3dh->dev.write(REG_TEMP_CFG_REG, temp_cfg_reg);
|
||||||
err |= lis3dh->dev.write(REG_REFERENCE, lis3dh->cfg.reference);
|
err |= lis3dh->dev.write(REG_REFERENCE, lis3dh->cfg.reference);
|
||||||
|
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG0, ctrl_reg0);
|
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG1, ctrl_reg1);
|
err |= lis3dh->dev.write(REG_CTRL_REG1, ctrl_reg1);
|
||||||
|
|
||||||
|
err |= lis3dh->dev.write(REG_CTRL_REG6, ctrl_reg6);
|
||||||
|
err |= lis3dh->dev.write(REG_CTRL_REG0, ctrl_reg0);
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG2, ctrl_reg2);
|
err |= lis3dh->dev.write(REG_CTRL_REG2, ctrl_reg2);
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG3, ctrl_reg3);
|
err |= lis3dh->dev.write(REG_CTRL_REG3, ctrl_reg3);
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG4, ctrl_reg4);
|
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG5, ctrl_reg5);
|
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG6, ctrl_reg6);
|
|
||||||
|
|
||||||
/* sleep for a period TBD ~ ODR */
|
/* sleep for a period TBD ~ ODR */
|
||||||
lis3dh->dev.sleep(50000); /* 50 ms */
|
lis3dh->dev.sleep(1000); /* 50 ms */
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,6 +336,9 @@ int lis3dh_reset(lis3dh_t *lis3dh) {
|
|||||||
/* set BOOT bit so device reloads internal trim parameters */
|
/* set BOOT bit so device reloads internal trim parameters */
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG5, 0x80);
|
err |= lis3dh->dev.write(REG_CTRL_REG5, 0x80);
|
||||||
|
|
||||||
|
/* wait 30 ms */
|
||||||
|
lis3dh->dev.sleep(30000);
|
||||||
|
|
||||||
/* write default values to rw regs */
|
/* write default values to rw regs */
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG0, 0x10);
|
err |= lis3dh->dev.write(REG_CTRL_REG0, 0x10);
|
||||||
err |= lis3dh->dev.write(REG_CTRL_REG1, 0x07);
|
err |= lis3dh->dev.write(REG_CTRL_REG1, 0x07);
|
||||||
@ -357,6 +361,12 @@ int lis3dh_reset(lis3dh_t *lis3dh) {
|
|||||||
err |= lis3dh->dev.write(REG_TIME_WINDOW, 0x00);
|
err |= lis3dh->dev.write(REG_TIME_WINDOW, 0x00);
|
||||||
err |= lis3dh->dev.write(REG_ACT_THS, 0x00);
|
err |= lis3dh->dev.write(REG_ACT_THS, 0x00);
|
||||||
err |= lis3dh->dev.write(REG_ACT_DUR, 0x00);
|
err |= lis3dh->dev.write(REG_ACT_DUR, 0x00);
|
||||||
|
|
||||||
|
/* set BOOT bit again so device reloads internal trim parameters */
|
||||||
|
err |= lis3dh->dev.write(REG_CTRL_REG5, 0x80);
|
||||||
|
|
||||||
|
/* wait 30 ms */
|
||||||
|
lis3dh->dev.sleep(30000);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
98
main.c
98
main.c
@ -1,107 +1,65 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <math.h>
|
#include <stdio.h>
|
||||||
#include "lis3dh.h"
|
#include "lis3dh.h"
|
||||||
#include "interrupt.h"
|
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
#include "spi.h"
|
||||||
/* GPIO 12 or Pin 32 */
|
|
||||||
#define GPIO_INTERRUPT_PIN 12
|
|
||||||
|
|
||||||
static void quit(const char *msg, lis3dh_t *lis) {
|
|
||||||
lis->dev.deinit();
|
|
||||||
fprintf(stderr, "%s\n", msg);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float mag(float x, float y, float z) {
|
|
||||||
return (float) sqrt(x*x + y*y + z*z);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
lis3dh_t lis;
|
lis3dh_t lis;
|
||||||
struct lis3dh_fifo_data fifo;
|
struct lis3dh_fifo_data data;
|
||||||
int k;
|
int i;
|
||||||
|
|
||||||
lis.dev.init = i2c_init;
|
lis.dev.init = spi_init;
|
||||||
lis.dev.read = i2c_read;
|
lis.dev.read = spi_read;
|
||||||
lis.dev.write = i2c_write;
|
lis.dev.write = spi_write;
|
||||||
lis.dev.sleep = usleep;
|
lis.dev.sleep = usleep;
|
||||||
lis.dev.deinit = i2c_deinit;
|
lis.dev.deinit = spi_deinit;
|
||||||
|
|
||||||
/* initalise LIS3DH struct */
|
/* initialise LIS3DH struct */
|
||||||
if (lis3dh_init(&lis)) {
|
if (lis3dh_init(&lis)) {
|
||||||
quit("init()", &lis);
|
puts("init()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset device just in case */
|
/* reset device just in case */
|
||||||
if (lis3dh_reset(&lis)) {
|
if (lis3dh_reset(&lis)) {
|
||||||
quit("reset()", &lis);
|
puts("reset()");
|
||||||
}
|
|
||||||
|
|
||||||
/* register interrupt */
|
|
||||||
if (int_register(GPIO_INTERRUPT_PIN)) {
|
|
||||||
quit("int_register()", &lis);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lis.cfg.mode = LIS3DH_MODE_HR;
|
lis.cfg.mode = LIS3DH_MODE_HR;
|
||||||
lis.cfg.range = LIS3DH_FS_2G;
|
lis.cfg.range = LIS3DH_FS_2G;
|
||||||
lis.cfg.rate = LIS3DH_ODR_400_HZ;
|
lis.cfg.rate = LIS3DH_ODR_400_HZ;
|
||||||
|
|
||||||
lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_STREAM_TO_FIFO;
|
lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_STREAM_TO_FIFO;
|
||||||
lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT1; /* trigger interrupt into int pin1 */
|
lis.cfg.fifo.size = 20;
|
||||||
lis.cfg.pin1.wtm = 1; /* trigger upon FIFO watermark level reached */
|
|
||||||
|
|
||||||
lis.cfg.en_adc =1;
|
|
||||||
lis.cfg.en_temp = 1;
|
|
||||||
|
|
||||||
/* write device config */
|
/* write device config */
|
||||||
if (lis3dh_configure(&lis)) {
|
if (lis3dh_configure(&lis)) {
|
||||||
quit("configure()", &lis);
|
puts("configure()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for interrupt from LIS3DH */
|
A:
|
||||||
if (int_poll(GPIO_INTERRUPT_PIN)) {
|
/* poll fifo register until it reports that the watermark level has
|
||||||
|
been reached, or that it has overwritten old data, whichever
|
||||||
quit("int_poll()", &lis);
|
happens first. */
|
||||||
|
if (lis3dh_poll_fifo(&lis)) {
|
||||||
|
puts("poll_fifo()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read as many [x y z] sets as specified by watermark level (fth) */
|
/* read as many [x y z] sets as specified by watermark level (fth) */
|
||||||
/* copy them to the fifo data struct given below as `fifo' */
|
/* copy them to the fifo data struct given below as `fifo' */
|
||||||
if (lis3dh_read_fifo(&lis, &fifo)) {
|
if (lis3dh_read_fifo(&lis, &data)) {
|
||||||
quit("read_fifo()", &lis);
|
puts("read_fifo()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* above function also writes out the qty of [x y z] sets stored in `fifo' */
|
/* read out fifo buffer data */
|
||||||
for(k=0; k<fifo.size; k++) {
|
for(i=0; i<data.size; i++) {
|
||||||
printf("x: %d, y: %d z: %d\n",
|
printf("x: %d mg, y: %d mg, z: %d mg\n", data.x[i], data.y[i], data.z[i]);
|
||||||
fifo.x[k], fifo.y[k], fifo.z[k]);
|
|
||||||
}
|
}
|
||||||
|
goto A;
|
||||||
printf("mag: %04.04f\n", mag(100.0, 45.0, 120.0));
|
/* deinitialise struct */
|
||||||
|
|
||||||
|
|
||||||
if (lis3dh_read_adc(&lis)) {
|
|
||||||
quit("adc()", &lis);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lis3dh_read_temp(&lis)) {
|
|
||||||
quit("temp()", &lis);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("ADC1: %d mV, temp: %d\n", lis.adc.adc1, lis.adc.adc3);
|
|
||||||
|
|
||||||
/* unregister interrupt */
|
|
||||||
if (int_unregister(GPIO_INTERRUPT_PIN)) {
|
|
||||||
quit("int_unregister()", &lis);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* deinitalise struct */
|
|
||||||
if (lis3dh_deinit(&lis)) {
|
if (lis3dh_deinit(&lis)) {
|
||||||
quit("deinit()", &lis);
|
puts("deinit()");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
70
spi.c
70
spi.c
@ -16,81 +16,68 @@ Example SPI use on linux/raspberry pi
|
|||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
|
|
||||||
#define SPI_DEVICE "/dev/spidev0.0"
|
#define SPI_DEVICE "/dev/spidev0.0"
|
||||||
|
#define SPI_SPEED 1000 * 1000 /* 1 MHz */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pinout config for this example
|
* Pinout config for this example
|
||||||
*
|
*
|
||||||
* MOSI - GPIO 10 (physical pin 19) => LIS3DH "SDA" or "SDI"
|
* MOSI - GPIO 10 (physical pin 19) => LIS3DH "SDA" or "SDI"
|
||||||
* MISO - GPIO 9 (physical pin 21) => LIS3DH "SDO"
|
* MISO - GPIO 9 (physical pin 21) => LIS3DH "SDO"
|
||||||
* SCLK - GPIO 11 (physical pin 23) => LIS3DH "SCK"
|
* SCLK - GPIO 11 (physical pin 23) => LIS3DH "SCL"
|
||||||
* CE0 - GPIO 8 (physical pin 24) => LIS3DH "!CS"
|
* CE0 - GPIO 8 (physical pin 24) => LIS3DH "!CS"
|
||||||
*
|
|
||||||
* Broken for unknown reason on Pi 4
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SPI_SPEED 500 * 1000 /* 500 KHz */
|
|
||||||
|
|
||||||
static int fd;
|
static int fd;
|
||||||
static uint8_t rx[256];
|
|
||||||
static uint8_t tx[256];
|
|
||||||
|
|
||||||
int spi_init(void) {
|
int spi_init(void) {
|
||||||
uint8_t mode = SPI_MODE_3;
|
uint8_t mode = SPI_MODE_0;
|
||||||
uint8_t bits = 8;
|
uint8_t bits = 8;
|
||||||
uint32_t speed = SPI_SPEED;
|
uint32_t speed = SPI_SPEED;
|
||||||
|
|
||||||
if ((fd = open(SPI_DEVICE, O_RDWR)) < 0) {
|
if ((fd = open(SPI_DEVICE, O_RDWR)) < 0) {
|
||||||
fprintf(stderr, "spi open(%s)\n", SPI_DEVICE);
|
fprintf(stderr, "spi_init(): open(%s)\n", SPI_DEVICE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, SPI_IOC_RD_MODE, &mode) == -1) {
|
if (ioctl(fd, SPI_IOC_RD_MODE, &mode) == -1) {
|
||||||
fprintf(stderr, "SPI_IOC_RD_MODE\n");
|
fprintf(stderr, "spi_init(): SPI_IOC_RD_MODE\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) {
|
if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) {
|
||||||
fprintf(stderr, "SPI_IOC_WR_MODE\n");
|
fprintf(stderr, "spi_init(): SPI_IOC_WR_MODE\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) {
|
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) {
|
||||||
fprintf(stderr, "SPI_IOC_WR_BITS_PER_WORD\n");
|
fprintf(stderr, "spi_init(): SPI_IOC_WR_BITS_PER_WORD\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) == -1) {
|
if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) == -1) {
|
||||||
fprintf(stderr, "SPI_IOC_RD_BITS_PER_WORD\n");
|
fprintf(stderr, "spi_init(): SPI_IOC_RD_BITS_PER_WORD\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) {
|
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) {
|
||||||
fprintf(stderr, "SPI_IOC_WR_MAX_SPEED_HZ\n");
|
fprintf(stderr, "spi_init(): SPI_IOC_WR_MAX_SPEED_HZ\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1) {
|
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1) {
|
||||||
fprintf(stderr, "SPI_IOC_RD_MAX_SPEED_HZ\n");
|
fprintf(stderr, "spi_init(): SPI_IOC_RD_MAX_SPEED_HZ\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spi_transaction(uint8_t *tx, uint8_t *rx, uint32_t size) {
|
|
||||||
struct spi_ioc_transfer tr = {0};
|
|
||||||
|
|
||||||
tr.tx_buf = (unsigned long) tx;
|
|
||||||
tr.rx_buf = (unsigned long) rx;
|
|
||||||
tr.len = size;
|
|
||||||
|
|
||||||
return ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int spi_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
int spi_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
||||||
|
|
||||||
|
uint8_t send[2];
|
||||||
|
struct spi_ioc_transfer tr[2] = {0};
|
||||||
|
|
||||||
/* clear 2 MSbits */
|
/* clear 2 MSbits */
|
||||||
reg &= 0x3F;
|
reg &= 0x3F;
|
||||||
|
|
||||||
@ -102,28 +89,41 @@ int spi_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
|||||||
reg |= 0x40;
|
reg |= 0x40;
|
||||||
}
|
}
|
||||||
|
|
||||||
tx[0] = reg;
|
send[0] = reg;
|
||||||
|
send[1] = 0x00;
|
||||||
|
|
||||||
if (spi_transaction(tx, rx, size + 1) < 0) {
|
tr[0].tx_buf = (unsigned long) send;
|
||||||
fprintf(stderr, "spi_read()\n");
|
tr[0].rx_buf = (unsigned long) 0;
|
||||||
|
tr[0].len = 2;
|
||||||
|
|
||||||
|
tr[1].tx_buf = (unsigned long) 0;
|
||||||
|
tr[1].rx_buf = (unsigned long) dst;
|
||||||
|
tr[1].len = size;
|
||||||
|
|
||||||
|
if (ioctl(fd, SPI_IOC_MESSAGE(2), tr) < 0) {
|
||||||
|
fprintf(stderr, "spi_read(): error ioctl()\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dst, rx + 1, size);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spi_write(uint8_t reg, uint8_t value) {
|
int spi_write(uint8_t reg, uint8_t value) {
|
||||||
|
struct spi_ioc_transfer tr[2] = {0};
|
||||||
|
|
||||||
/* clear 2 MSbits */
|
/* clear 2 MSbits */
|
||||||
reg &= 0x3F;
|
reg &= 0x3F;
|
||||||
|
|
||||||
tx[0] = reg;
|
tr[0].tx_buf = (unsigned long) ®
|
||||||
tx[1] = value;
|
tr[0].rx_buf = (unsigned long) 0;
|
||||||
|
tr[0].len = 1;
|
||||||
|
|
||||||
if (spi_transaction(tx, rx, 2) < 0) {
|
tr[1].tx_buf = (unsigned long) &value;
|
||||||
fprintf(stderr, "spi_write()\n");
|
tr[1].rx_buf = (unsigned long) 0;
|
||||||
|
tr[1].len = 1;
|
||||||
|
|
||||||
|
if (ioctl(fd, SPI_IOC_MESSAGE(2), tr) < 0) {
|
||||||
|
fprintf(stderr, "spi_write(): error ioctl()\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user