#include #include #include #include #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); }