bf16-spidevice.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <fcntl.h>
  2. #include <sys/ioctl.h>
  3. #include <linux/spi/spidev.h>
  4. #include <unistd.h>
  5. #include "bf16-spidevice.h"
  6. #include "miner.h"
  7. char *spi0_device_name = "/dev/spidev1.1";
  8. char *spi1_device_name = "/dev/spidev2.1";
  9. int8_t spi_init(device_t* attr, spi_channel_id_t channel_id, int8_t mode, uint32_t speed, uint16_t size)
  10. {
  11. switch (channel_id) {
  12. case SPI_CHANNEL1:
  13. attr->device = spi1_device_name;
  14. break;
  15. case SPI_CHANNEL2:
  16. attr->device = spi0_device_name;
  17. break;
  18. }
  19. attr->mode = mode;
  20. attr->speed = speed;
  21. attr->bits = 8;
  22. attr->size = size;
  23. attr->rx = malloc(size);
  24. attr->tx = malloc(size);
  25. int fd;
  26. if ((fd = open(attr->device, O_RDWR)) < 0) {
  27. applog(LOG_ERR, "BF16: %s() failed to open device [%s]: %s",
  28. __func__, attr->device, strerror(errno));
  29. return -1;
  30. }
  31. /* SPI mode */
  32. if (ioctl(fd, SPI_IOC_WR_MODE, &(attr->mode)) < 0) {
  33. applog(LOG_ERR, "BF16: %s() failed to set SPI mode: %s", __func__, strerror(errno));
  34. return -1;
  35. }
  36. if (ioctl(fd, SPI_IOC_RD_MODE, &(attr->mode)) < 0) {
  37. applog(LOG_ERR, "BF16: %s() failed to get SPI mode: %s", __func__, strerror(errno));
  38. return -1;
  39. }
  40. /* bits per word */
  41. if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &(attr->bits)) < 0) {
  42. applog(LOG_ERR, "BF16: %s() failed to set SPI bits per word: %s", __func__, strerror(errno));
  43. return -1;
  44. }
  45. if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &(attr->bits)) < 0) {
  46. applog(LOG_ERR, "BF16: %s() failed to get SPI bits per word: %s", __func__, strerror(errno));
  47. return -1;
  48. }
  49. /* max speed hz */
  50. if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &(attr->speed)) < 0) {
  51. applog(LOG_ERR, "BF16: %s() failed to set SPI max speed hz: %s", __func__, strerror(errno));
  52. return -1;
  53. }
  54. if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &(attr->speed)) < 0) {
  55. applog(LOG_ERR, "BF16: %s() failed to get SPI max speed hz: %s", __func__, strerror(errno));
  56. return -1;
  57. }
  58. attr->fd = fd;
  59. return 0;
  60. }
  61. void spi_transfer(device_t *attr)
  62. {
  63. struct spi_ioc_transfer tr = {
  64. .tx_buf = (unsigned long) (attr->tx),
  65. .rx_buf = (unsigned long) (attr->rx),
  66. .len = attr->datalen,
  67. .delay_usecs = attr->delay,
  68. .speed_hz = attr->speed,
  69. .bits_per_word = attr->bits
  70. };
  71. if (ioctl(attr->fd, SPI_IOC_MESSAGE(1), &tr) < 0)
  72. quit(1, "BF16: %s() failed to send SPI message: %s", __func__, strerror(errno));
  73. #if 0
  74. uint16_t i;
  75. char data[2*4096];
  76. memset(data, 0, sizeof(data));
  77. for (i = 0; i < attr->datalen; i++)
  78. sprintf(data, "%s%02x", data, attr->tx[i]);
  79. applog(LOG_DEBUG, "BF16: TX -> [%s]", data);
  80. memset(data, 0, sizeof(data));
  81. for (i = 0; i < attr->datalen; i++)
  82. sprintf(data, "%s%02x", data, attr->rx[i]);
  83. applog(LOG_DEBUG, "BF16: RX <- [%s]", data);
  84. #endif
  85. }
  86. void spi_release(device_t *attr)
  87. {
  88. free(attr->rx);
  89. free(attr->tx);
  90. close(attr->fd);
  91. }