-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathspi.c
executable file
·96 lines (78 loc) · 2.73 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
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include "spi.h"
// Reference:
// https://www.kernel.org/doc/Documentation/spi/
// https://www.kernel.org/doc/Documentation/spi/spi-summary
// https://www.kernel.org/doc/Documentation/spi/spidev
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define SPI_MSB_FIRST 0
#define SPI_BITS_PER_WORD_8 8
#define SPI_BITS_PER_WORD_9 9
#define SPI_SPEED_500KHZ 500 * 1000 // Raspberry Pi minimum
#define SPI_SPEED_6MHZ 6 * 1000 * 1000 // Rerported LCD Maximum
#define SPI_SPEED_3815HZ 3815 // Linux minimum
#define SPI_DELAY_0 0
#define SPI_DELAY_MIN 2980 // Minimum tested value
#define SPI_CS_CHANGE 1 // Don't clear CS between messages
// Actually should be cleared according
// to the epson data sheets
const uint32_t DELAY = SPI_DELAY_0;
const uint32_t SPEED = SPI_SPEED_6MHZ;
const uint32_t BPW = SPI_BITS_PER_WORD_9;
const uint32_t CS_CHANGE = SPI_CS_CHANGE;
int spi_init(const char* dev) {
uint8_t mode = SPI_CPOL; // => SPI_CPOL (per the EPSON data sheet)
// not SPI_CPHA
uint8_t lsb_first = SPI_MSB_FIRST;
uint8_t bpw = BPW;
uint32_t speed = SPEED;
int fd = open(dev, O_RDWR);
if (fd < 0)
return fd;
if (ioctl(fd, SPI_IOC_WR_MODE , &mode ) < 0) return -1;
if (ioctl(fd, SPI_IOC_WR_LSB_FIRST , &lsb_first) < 0) return -1;
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bpw ) < 0) return -1;
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ , &speed ) < 0) return -1;
// printf("initializing device: %s\n" , dev);
// printf("spi mode: %d\n" , mode);
// printf("*lsb first: %d\n" , lsb_first);
// printf("bits per word: %d\n" , bpw);
// printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
return fd;
}
int spi_send_word(int fd, uint16_t word) {
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long) &word,
.rx_buf = (unsigned long) 0,
.len = 2,
.delay_usecs = DELAY,
.speed_hz = SPEED,
.bits_per_word = BPW,
.cs_change = 0,
};
if (ioctl(fd, SPI_IOC_MESSAGE(1), &tr) < 0) {
return -1;
}
return 0;
}
int spi_send_buffer(int fd, uint32_t len, void* data) {
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long) data,
.rx_buf = (unsigned long) 0,
.len = 2 * len,
.delay_usecs = DELAY,
.speed_hz = SPEED,
.bits_per_word = BPW,
.cs_change = 0,
};
if (ioctl(fd, SPI_IOC_MESSAGE(1), &tr) < 0) {
return -1;
}
return 0;
}