-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspi.c
141 lines (106 loc) · 2.92 KB
/
spi.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
Example SPI use on linux/raspberry pi
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <string.h>
#include "spi.h"
#define SPI_DEVICE "/dev/spidev0.0"
#define SPI_SPEED 1000 * 1000 /* 1 MHz */
/*
* Pinout config for this example
*
* MOSI - GPIO 10 (physical pin 19) => LIS3DH "SDA" or "SDI"
* MISO - GPIO 9 (physical pin 21) => LIS3DH "SDO"
* SCLK - GPIO 11 (physical pin 23) => LIS3DH "SCL"
* CE0 - GPIO 8 (physical pin 24) => LIS3DH "!CS"
*
*/
static int fd;
int spi_init(void) {
uint8_t mode = SPI_MODE_0;
uint8_t bits = 8;
uint32_t speed = SPI_SPEED;
if ((fd = open(SPI_DEVICE, O_RDWR)) < 0) {
fprintf(stderr, "spi_init(): open(%s)\n", SPI_DEVICE);
return 1;
}
if (ioctl(fd, SPI_IOC_RD_MODE, &mode) == -1) {
fprintf(stderr, "spi_init(): SPI_IOC_RD_MODE\n");
return 1;
}
if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) {
fprintf(stderr, "spi_init(): SPI_IOC_WR_MODE\n");
return 1;
}
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) {
fprintf(stderr, "spi_init(): SPI_IOC_WR_BITS_PER_WORD\n");
return 1;
}
if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) == -1) {
fprintf(stderr, "spi_init(): SPI_IOC_RD_BITS_PER_WORD\n");
return 1;
}
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) {
fprintf(stderr, "spi_init(): SPI_IOC_WR_MAX_SPEED_HZ\n");
return 1;
}
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1) {
fprintf(stderr, "spi_init(): SPI_IOC_RD_MAX_SPEED_HZ\n");
return 1;
}
return 0;
}
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 */
reg &= 0x3F;
/* set READ bit */
reg |= 0x80;
if (size > 1) {
/* set AUTO INC bit */
reg |= 0x40;
}
send[0] = reg;
send[1] = 0x00;
tr[0].tx_buf = (unsigned long) send;
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 0;
}
int spi_write(uint8_t reg, uint8_t value) {
struct spi_ioc_transfer tr[2] = {0};
/* clear 2 MSbits */
reg &= 0x3F;
tr[0].tx_buf = (unsigned long) ®
tr[0].rx_buf = (unsigned long) 0;
tr[0].len = 1;
tr[1].tx_buf = (unsigned long) &value;
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 0;
}
int spi_deinit(void) {
if (fd) {
close(fd);
}
return 0;
}