#include "AccessoryCardLora15.h" AccessoryCardLora15::AccessoryCardLora15(std::string ProductId, std::string Port) : AccessoryCardLora(ProductId, Port) { } int AccessoryCardLora15::spiOpen(const char *spidev) { int *spi_device = NULL; int dev; int a = 0, b = 0; int i; /* allocate memory for the device descriptor */ spi_device = (int *)malloc(sizeof(int)); if (spi_device == NULL) { printf("ERROR: MALLOC FAIL\n"); return -1; } /* open SPI device */ dev = open(spidev, O_RDWR); if (dev < 0) { printf("ERROR: failed to open SPI device %s\n", spidev); return -1; } /* setting SPI mode to 'mode 0' */ i = SPI_MODE_3; a = ioctl(dev, SPI_IOC_WR_MODE, &i); b = ioctl(dev, SPI_IOC_RD_MODE, &i); if ((a < 0) || (b < 0)) { printf("ERROR: SPI PORT FAIL TO SET IN MODE 0\n"); close(dev); free(spi_device); return -1; } /* setting SPI max clk (in Hz) */ i = SPI_SPEED; a = ioctl(dev, SPI_IOC_WR_MAX_SPEED_HZ, &i); b = ioctl(dev, SPI_IOC_RD_MAX_SPEED_HZ, &i); if ((a < 0) || (b < 0)) { printf("ERROR: SPI PORT FAIL TO SET MAX SPEED\n"); close(dev); free(spi_device); return -1; } /* setting SPI to MSB first */ i = 0; a = ioctl(dev, SPI_IOC_WR_LSB_FIRST, &i); b = ioctl(dev, SPI_IOC_RD_LSB_FIRST, &i); if ((a < 0) || (b < 0)) { printf("ERROR: SPI PORT FAIL TO SET MSB FIRST\n"); close(dev); free(spi_device); return -1; } /* setting SPI to 8 bits per word */ i = 0; a = ioctl(dev, SPI_IOC_WR_BITS_PER_WORD, &i); b = ioctl(dev, SPI_IOC_RD_BITS_PER_WORD, &i); if ((a < 0) || (b < 0)) { printf("ERROR: SPI PORT FAIL TO SET 8 BITS-PER-WORD\n"); close(dev); return -1; } *spi_device = dev; spi_target_ptr = (void *)spi_device; return 0; } int AccessoryCardLora15::spiRead(uint8_t address, uint8_t *data) { int spi_device; uint8_t out_buf[3]; uint8_t in_buf[ARRAY_SIZE(out_buf)]; uint8_t command_size; struct spi_ioc_transfer k; int a; spi_device = *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */ /* prepare frame to be sent */ out_buf[0] = MTAC_FPGA; out_buf[1] = READ_ACCESS | (address & 0x7F); out_buf[2] = 0x00; command_size = 3; /* I/O transaction */ memset(&k, 0, sizeof(k)); /* clear k */ k.tx_buf = (unsigned long)out_buf; k.rx_buf = (unsigned long)in_buf; k.len = command_size; k.cs_change = 1; a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k); /* determine return code */ if (a != (int)k.len) { printf("ERROR: SPI READ FAILURE\n"); return -1; } else { *data = in_buf[command_size - 1]; return 0; } } int AccessoryCardLora15::spiClose() { int spi_device; int a; /* close file & deallocate file descriptor */ spi_device = *(int *)spi_target_ptr; /* check that spi_target is not null */ a = close(spi_device); free(spi_target_ptr); /* determine return code */ if (a < 0) { printf("ERROR: SPI PORT FAILED TO CLOSE\n"); return -1; } else { return 0; } } uint8_t AccessoryCardLora15::getFPGAVersion() { int ret; uint8_t u = 255; ret = spiOpen(getPath().c_str()); if (ret != 0) { printf("Could not open SPI port %s", getPath().c_str()); return u; } /* detect if the gateway has an FPGA with SPI mux header support */ ret = spiRead(MTAC_FPGA_ADDRESS, &u); if (ret != 0) { printf("Could not read FPGA version"); } spiClose(); spi_target_ptr = NULL; return u; }