forked from ckolivas/cgminer
-
Notifications
You must be signed in to change notification settings - Fork 30
/
bf16-spidevice.c
110 lines (91 loc) · 2.71 KB
/
bf16-spidevice.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
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <unistd.h>
#include "bf16-spidevice.h"
#include "miner.h"
char *spi0_device_name = "/dev/spidev1.1";
char *spi1_device_name = "/dev/spidev2.1";
int8_t spi_init(device_t* attr, spi_channel_id_t channel_id, int8_t mode, uint32_t speed, uint16_t size)
{
switch (channel_id) {
case SPI_CHANNEL1:
attr->device = spi1_device_name;
break;
case SPI_CHANNEL2:
attr->device = spi0_device_name;
break;
}
attr->mode = mode;
attr->speed = speed;
attr->bits = 8;
attr->size = size;
attr->rx = malloc(size);
attr->tx = malloc(size);
int fd;
if ((fd = open(attr->device, O_RDWR)) < 0) {
applog(LOG_ERR, "BF16: %s() failed to open device [%s]: %s",
__func__, attr->device, strerror(errno));
return -1;
}
/* SPI mode */
if (ioctl(fd, SPI_IOC_WR_MODE, &(attr->mode)) < 0) {
applog(LOG_ERR, "BF16: %s() failed to set SPI mode: %s", __func__, strerror(errno));
return -1;
}
if (ioctl(fd, SPI_IOC_RD_MODE, &(attr->mode)) < 0) {
applog(LOG_ERR, "BF16: %s() failed to get SPI mode: %s", __func__, strerror(errno));
return -1;
}
/* bits per word */
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &(attr->bits)) < 0) {
applog(LOG_ERR, "BF16: %s() failed to set SPI bits per word: %s", __func__, strerror(errno));
return -1;
}
if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &(attr->bits)) < 0) {
applog(LOG_ERR, "BF16: %s() failed to get SPI bits per word: %s", __func__, strerror(errno));
return -1;
}
/* max speed hz */
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &(attr->speed)) < 0) {
applog(LOG_ERR, "BF16: %s() failed to set SPI max speed hz: %s", __func__, strerror(errno));
return -1;
}
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &(attr->speed)) < 0) {
applog(LOG_ERR, "BF16: %s() failed to get SPI max speed hz: %s", __func__, strerror(errno));
return -1;
}
attr->fd = fd;
return 0;
}
void spi_transfer(device_t *attr)
{
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long) (attr->tx),
.rx_buf = (unsigned long) (attr->rx),
.len = attr->datalen,
.delay_usecs = attr->delay,
.speed_hz = attr->speed,
.bits_per_word = attr->bits
};
if (ioctl(attr->fd, SPI_IOC_MESSAGE(1), &tr) < 0)
quit(1, "BF16: %s() failed to send SPI message: %s", __func__, strerror(errno));
#if 0
uint16_t i;
char data[2*4096];
memset(data, 0, sizeof(data));
for (i = 0; i < attr->datalen; i++)
sprintf(data, "%s%02x", data, attr->tx[i]);
applog(LOG_DEBUG, "BF16: TX -> [%s]", data);
memset(data, 0, sizeof(data));
for (i = 0; i < attr->datalen; i++)
sprintf(data, "%s%02x", data, attr->rx[i]);
applog(LOG_DEBUG, "BF16: RX <- [%s]", data);
#endif
}
void spi_release(device_t *attr)
{
free(attr->rx);
free(attr->tx);
close(attr->fd);
}