summaryrefslogtreecommitdiff
path: root/src/AccessoryCards
diff options
context:
space:
mode:
authorHarsh Sharma <harsh.sharma@multitech.com>2022-03-03 14:44:44 -0600
committerJohn Klug <john.klug@multitech.com>2022-03-03 14:53:34 -0600
commit54f86b83b60192f8b33dad90b33b47246165ac51 (patch)
treec7183f8ff02d3090989530740d36164db3630620 /src/AccessoryCards
parent964e90992d6ac73cf287722a3dc136dda86c3ac2 (diff)
downloadmts-io-sysfs-54f86b83b60192f8b33dad90b33b47246165ac51.tar.gz
mts-io-sysfs-54f86b83b60192f8b33dad90b33b47246165ac51.tar.bz2
mts-io-sysfs-54f86b83b60192f8b33dad90b33b47246165ac51.zip
LoRa updates with MTAC-003
Diffstat (limited to 'src/AccessoryCards')
-rw-r--r--src/AccessoryCards/AccessoryCard.cpp26
-rw-r--r--src/AccessoryCards/AcessoryCard.cpp21
-rw-r--r--src/AccessoryCards/Gpiob.cpp36
-rw-r--r--src/AccessoryCards/LoraCard.cpp38
-rw-r--r--src/AccessoryCards/LoraCard03.cpp53
-rw-r--r--src/AccessoryCards/LoraCard10.cpp38
-rw-r--r--src/AccessoryCards/LoraCard15.cpp195
-rw-r--r--src/AccessoryCards/LoraCard21.cpp48
-rw-r--r--src/AccessoryCards/LoraCard21Ext.cpp42
-rw-r--r--src/AccessoryCards/LoraCard2G4.cpp32
-rw-r--r--src/AccessoryCards/Mfser.cpp47
-rw-r--r--src/AccessoryCards/Mtac15Fpga.cpp803
12 files changed, 1109 insertions, 270 deletions
diff --git a/src/AccessoryCards/AccessoryCard.cpp b/src/AccessoryCards/AccessoryCard.cpp
new file mode 100644
index 0000000..0c7c2a0
--- /dev/null
+++ b/src/AccessoryCards/AccessoryCard.cpp
@@ -0,0 +1,26 @@
+/**********************************************************************
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
+
+#include "Device.h"
+
+Device::AccessoryCard::AccessoryCard(Device &d, const std::regex Name)
+ : device(d), name(Name) {}
+
+void Device::AccessoryCard::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {}
+
+const std::regex Device::AccessoryCard::GetName() { return name; } \ No newline at end of file
diff --git a/src/AccessoryCards/AcessoryCard.cpp b/src/AccessoryCards/AcessoryCard.cpp
deleted file mode 100644
index 6a7a0d8..0000000
--- a/src/AccessoryCards/AcessoryCard.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/**********************************************************************
-* COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
-*
-* ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
-* MULTI-TECH SYSTEMS, INC.
-*
-* MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
-* INFORMATION AND/OR TRADE SECRET.
-*
-* NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
-* DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
-* INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
-* USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
-* WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
-*
-***********************************************************************/
-
-#include "Device.h"
-
-Device::AccessoryCard::AccessoryCard(Device& d, const std::string ProductId, const std::string Port) : device(d), productId(ProductId), port(Port) {
-}
diff --git a/src/AccessoryCards/Gpiob.cpp b/src/AccessoryCards/Gpiob.cpp
index 44728ae..c580aeb 100644
--- a/src/AccessoryCards/Gpiob.cpp
+++ b/src/AccessoryCards/Gpiob.cpp
@@ -1,23 +1,27 @@
/**********************************************************************
-* COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
-*
-* ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
-* MULTI-TECH SYSTEMS, INC.
-*
-* MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
-* INFORMATION AND/OR TRADE SECRET.
-*
-* NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
-* DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
-* INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
-* USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
-* WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
-*
-***********************************************************************/
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
#include "Device.h"
-Device::Gpiob::Gpiob(Device& d, const std::string ProductId, const std::string Port) : AccessoryCard(d, ProductId, Port) {
+Device::Gpiob::Gpiob(Device &d)
+ : AccessoryCard(d, std::regex("(MTAC-GPIOB)|(MMTAC-GPIOI)")) {}
+
+void Device::Gpiob::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
capabilityList["adc"] = true;
capabilityList["din"] = true;
capabilityList["dout"] = true;
diff --git a/src/AccessoryCards/LoraCard.cpp b/src/AccessoryCards/LoraCard.cpp
index 7a248dc..fe2a8d2 100644
--- a/src/AccessoryCards/LoraCard.cpp
+++ b/src/AccessoryCards/LoraCard.cpp
@@ -1,26 +1,26 @@
/**********************************************************************
-* COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
-*
-* ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
-* MULTI-TECH SYSTEMS, INC.
-*
-* MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
-* INFORMATION AND/OR TRADE SECRET.
-*
-* NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
-* DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
-* INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
-* USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
-* WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
-*
-***********************************************************************/
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
#include "Device.h"
-Device::LoraCard::LoraCard(Device& d, const std::string ProductId, const std::string Port) : AccessoryCard(d, ProductId, Port), spiPath("/dev/spidev0.0") {}
+Device::LoraCard::LoraCard(Device &d, const std::regex Name)
+ : AccessoryCard(d, Name), spiPath("/dev/spidev0.0"), fpgaVersion(255) {}
-void Device::LoraCard::setCapabilities() {
+void Device::LoraCard::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
device.capabilityList["lora"] = true;
- device.accessoryCard.AddMember("fpgaVersion", fpgaVersion, device.accessoryCardsAlloc);
- device.accessoryCard.AddMember("spiPath", rapidjson::Value().SetString(spiPath.c_str(), device.accessoryCardsAlloc), device.accessoryCardsAlloc);
} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard03.cpp b/src/AccessoryCards/LoraCard03.cpp
new file mode 100644
index 0000000..7e9f9ae
--- /dev/null
+++ b/src/AccessoryCards/LoraCard03.cpp
@@ -0,0 +1,53 @@
+/**********************************************************************
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
+
+#include "Device.h"
+
+Device::Lora03Card::Lora03Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-003)(.*)|(MTCAP3-003)(.*)")) {}
+
+void Device::Lora03Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+ /* Map the spi path to the port/hw version */
+ std::string deviceHwVersion = "";
+ MTS::System::readFile(HW_VERSION_PATH, deviceHwVersion);
+ if (deviceHwVersion.find("MTCAP3") != std::string::npos) {
+ spiPath = "/dev/spidev1.0";
+ spiPath1261 = "/dev/spidev1.1";
+ tmp102 = 0x48;
+ } else if (Port.back() == '2') {
+ spiPath = "/dev/spidev1.0";
+ spiPath1261 = "/dev/spidev1.1";
+ tmp102 = 0x49;
+ } else {
+ spiPath = "/dev/spidev0.0";
+ spiPath1261 = "/dev/spidev0.1";
+ tmp102 = 0x48;
+ }
+
+ device.accessoryCard.AddMember(
+ "spiPath",
+ rapidjson::Value().SetString(spiPath.c_str(), device.acAlloc),
+ device.acAlloc);
+ device.accessoryCard.AddMember(
+ "spiPath1261",
+ rapidjson::Value().SetString(spiPath1261.c_str(), device.acAlloc),
+ device.acAlloc);
+ device.accessoryCard.AddMember("tmp102", tmp102, device.acAlloc);
+} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard10.cpp b/src/AccessoryCards/LoraCard10.cpp
new file mode 100644
index 0000000..e74b848
--- /dev/null
+++ b/src/AccessoryCards/LoraCard10.cpp
@@ -0,0 +1,38 @@
+/**********************************************************************
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
+
+#include "Device.h"
+
+Device::Lora10Card::Lora10Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-LORA-915)|(MTAC-LORA-868)")) {}
+
+void Device::Lora10Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+
+ if (Port.back() == '2') {
+ spiPath = "/dev/spidev1.2";
+ } else {
+ spiPath = "/dev/spidev0.2";
+ }
+
+ device.accessoryCard.AddMember(
+ "spiPath",
+ rapidjson::Value().SetString(spiPath.c_str(), device.acAlloc),
+ device.acAlloc);
+} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard15.cpp b/src/AccessoryCards/LoraCard15.cpp
index a7a1dad..3ed0f31 100644
--- a/src/AccessoryCards/LoraCard15.cpp
+++ b/src/AccessoryCards/LoraCard15.cpp
@@ -1,172 +1,45 @@
/**********************************************************************
-* COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
-*
-* ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
-* MULTI-TECH SYSTEMS, INC.
-*
-* MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
-* INFORMATION AND/OR TRADE SECRET.
-*
-* NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
-* DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
-* INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
-* USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
-* WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
-*
-***********************************************************************/
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
#include "Device.h"
-Device::Lora15Card::Lora15Card(Device& d, const std::string ProductId, const std::string Port) : LoraCard(d, ProductId, Port) {
- int ret;
- std::string deviceHwVersion = "";
- /* Map the spi path to the device hw version/mtac product id, with the default being spidev0.0 */
- MTS::System::readFile(HW_VERSION_PATH, deviceHwVersion);
- if (deviceHwVersion.find("MTCDT3-") != std::string::npos) {
- if (port.back() == '2') {
- spiPath = "/dev/spidev1.2";
- } else {
- spiPath = "/dev/spidev0.2";
- }
- } else if (productId.find("MTAC-LORA-") == 0) {
- if (port.back() == '2') {
- spiPath = "/dev/spidev32765.2";
- } else {
- spiPath = "/dev/spidev32766.2";
- }
- }
- ret = spiOpen(spiPath.c_str());
- if (ret != 0) {
- printf("Could not open SPI port %s", spiPath.c_str());
- return;
- }
- /* detect if the gateway has an FPGA with SPI mux header support */
- ret = spiRead(MTAC_FPGA_ADDRESS, &fpgaVersion);
- if (ret != 0) {
- printf("Could not read FPGA version");
- fpgaVersion = 255;
- }
-
- spiClose();
- spi_target_ptr = NULL;
- setCapabilities();
-}
-
-int Device::Lora15Card::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;
- }
+Device::Lora15Card::Lora15Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-LORA-H)(.*)|(MTAC-LORA-F)(.*)|(MTCAP-LORA-)"
+ "(.*)|(MTLGA-)(.*)|(MTCDT3-)(.*)")) {}
- /* 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;
- }
+void Device::Lora15Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
- /* 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;
- }
+ LoraCard::AddToDeviceInfo(Port, ProductID);
- /* 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 Device::Lora15Card::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;
+ if (ProductID.rfind("MTCAP", 0) == 0) {
+ spiPath = "/dev/spidev0.0";
+ } else if (Port.back() == '2') {
+ spiPath = "/dev/spidev1.2";
} else {
- *data = in_buf[command_size - 1];
- return 0;
+ spiPath = "/dev/spidev0.2";
}
-}
-
-int Device::Lora15Card::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;
- }
+ Mtac15Fpga mtac15Fpga(spiPath);
+ mtac15Fpga.getFpgaVersion();
+ fpgaVersion = mtac15Fpga.FpgaVersion();
+ device.accessoryCard.AddMember(
+ "spiPath",
+ rapidjson::Value().SetString(spiPath.c_str(), device.acAlloc),
+ device.acAlloc);
+ device.accessoryCard.AddMember("fpgaVersion", fpgaVersion, device.acAlloc);
} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard21.cpp b/src/AccessoryCards/LoraCard21.cpp
index d40876b..4337bfa 100644
--- a/src/AccessoryCards/LoraCard21.cpp
+++ b/src/AccessoryCards/LoraCard21.cpp
@@ -1,25 +1,39 @@
/**********************************************************************
-* COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
-*
-* ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
-* MULTI-TECH SYSTEMS, INC.
-*
-* MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
-* INFORMATION AND/OR TRADE SECRET.
-*
-* NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
-* DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
-* INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
-* USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
-* WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
-*
-***********************************************************************/
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
#include "Device.h"
-Device::Lora21Card::Lora21Card(Device& d, const std::string ProductId, const std::string Port): LoraCard(d, ProductId, Port) {
+Device::Lora21Card::Lora21Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-LORA-G16)(.*)")) {}
+Device::Lora21Card::Lora21Card(Device &d, const std::regex Name)
+ : LoraCard(d, Name) {}
+
+void Device::Lora21Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+
spiPath = "/dev/spidev32766.2";
MTS::System::cmd(LORA_2_1_FPGA_VERSION, cmdFpgaVersion);
fpgaVersion = std::stoi(cmdFpgaVersion);
- setCapabilities();
+
+ device.accessoryCard.AddMember("fpgaVersion", fpgaVersion, device.acAlloc);
+ device.accessoryCard.AddMember(
+ "spiPath",
+ rapidjson::Value().SetString(spiPath.c_str(), device.acAlloc),
+ device.acAlloc);
} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard21Ext.cpp b/src/AccessoryCards/LoraCard21Ext.cpp
index 2595286..b25dbfe 100644
--- a/src/AccessoryCards/LoraCard21Ext.cpp
+++ b/src/AccessoryCards/LoraCard21Ext.cpp
@@ -1,23 +1,31 @@
/**********************************************************************
-* COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
-*
-* ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
-* MULTI-TECH SYSTEMS, INC.
-*
-* MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
-* INFORMATION AND/OR TRADE SECRET.
-*
-* NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
-* DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
-* INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
-* USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
-* WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
-*
-***********************************************************************/
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
#include "Device.h"
-Device::Lora21ExtCard::Lora21ExtCard(Device& d, const std::string ProductId, const std::string Port): Lora21Card(d, ProductId, Port) {
+Device::Lora21ExtCard::Lora21ExtCard(Device &d)
+ : Lora21Card(d, std::regex("(MTAC-LORA-G64)(.*)")) {}
+
+void Device::Lora21ExtCard::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+
MTS::System::cmd(LORA_2_1_EXT_FPGA_VERSION, cmdFpgaVersion2);
- device.accessoryCard.AddMember("fpgaVersion2", std::stoi(cmdFpgaVersion2), device.accessoryCardsAlloc);
+ device.accessoryCard.AddMember("fpgaVersion2", std::stoi(cmdFpgaVersion2),
+ device.acAlloc);
} \ No newline at end of file
diff --git a/src/AccessoryCards/LoraCard2G4.cpp b/src/AccessoryCards/LoraCard2G4.cpp
new file mode 100644
index 0000000..10691ce
--- /dev/null
+++ b/src/AccessoryCards/LoraCard2G4.cpp
@@ -0,0 +1,32 @@
+/**********************************************************************
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
+
+#include "Device.h"
+
+Device::Lora2G4Card::Lora2G4Card(Device &d)
+ : LoraCard(d, std::regex("(MTAC-LORA-2G4)")) {}
+
+void Device::Lora2G4Card::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ LoraCard::AddToDeviceInfo(Port, ProductID);
+ std::string ttyPath = "/dev/ttyACM0";
+ device.accessoryCard.AddMember(
+ "ttyPath",
+ rapidjson::Value().SetString(ttyPath.c_str(), device.acAlloc),
+ device.acAlloc);
+} \ No newline at end of file
diff --git a/src/AccessoryCards/Mfser.cpp b/src/AccessoryCards/Mfser.cpp
index dfdfeb3..03a00b7 100644
--- a/src/AccessoryCards/Mfser.cpp
+++ b/src/AccessoryCards/Mfser.cpp
@@ -1,28 +1,37 @@
/**********************************************************************
-* COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
-*
-* ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
-* MULTI-TECH SYSTEMS, INC.
-*
-* MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
-* INFORMATION AND/OR TRADE SECRET.
-*
-* NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
-* DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
-* INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
-* USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
-* WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
-*
-***********************************************************************/
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
#include "Device.h"
-Device::Mfser::Mfser(Device& d, const std::string ProductId, const std::string Port) : AccessoryCard(d, ProductId, Port) {
- capabilityList["rs232"] = true;
+
+Device::Mfser::Mfser(Device &d)
+ : AccessoryCard(
+ d, std::regex("(MTAC-MFSER-DTE)|(MTAC-MFSER-DCE)|(MTR-)(.*)")) {}
+
+void Device::Mfser::AddToDeviceInfo(const std::string Port,
+ const std::string ProductID) {
+
+ capabilityList["rs232"] = true;
capabilityList["rs422"] = true;
capabilityList["rs485"] = true;
capabilityList["serial"] = true;
- if (!fileExists("/dev/ext_serial") && port.size() > 0) {
+ if (!fileExists("/dev/ext_serial") && Port.size() > 0) {
std::string temp;
- MTS::System::cmd(std::string("ln -s /dev/ttyAP") + port.back() + " /dev/ext_serial", temp);
+ MTS::System::cmd(std::string("ln -s /dev/ttyAP") + Port.back() +
+ " /dev/ext_serial",
+ temp);
}
} \ No newline at end of file
diff --git a/src/AccessoryCards/Mtac15Fpga.cpp b/src/AccessoryCards/Mtac15Fpga.cpp
new file mode 100644
index 0000000..151ff77
--- /dev/null
+++ b/src/AccessoryCards/Mtac15Fpga.cpp
@@ -0,0 +1,803 @@
+/**********************************************************************
+ * COPYRIGHT 2020 MULTI-TECH SYSTEMS, INC.
+ *
+ * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
+ * MULTI-TECH SYSTEMS, INC.
+ *
+ * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
+ * INFORMATION AND/OR TRADE SECRET.
+ *
+ * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
+ * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
+ * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
+ * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
+ * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
+ *
+ ***********************************************************************/
+
+#include "Fpga.h"
+
+/* -------------------------------------------------------------------------- */
+/* --- Flash opcodes ---------------------------------------------------------*/
+#define WR_STATUS_REG 0x01 /* Write Status Register */
+#define PAGE_PROGRAM 0x02 /* Write up to a Page of the Memory */
+#define READ_DATA 0x03 /* Read from the Memory */
+#define WRITE_DISABLE 0x04 /* Disable Writing to the Memory */
+#define RD_STATUS_REG_1 0x05 /* Read Status Register-1 */
+#define WRITE_ENABLE 0x06 /* Enable Writing to the Memory */
+#define FAST_READ_DATA 0x0B /* Fast Read from the Memory */
+#define SECTOR_ERASE 0x20 /* Erase a Sector (4kb) */ u
+#define RD_STATUS_REG_2 0x35 /* Read Status Register-2 */
+#define UNIQUE_ID 0x4B /* Read Unique ID */
+#define WE_STATUS_REG 0x50 /* Write Enable for Status Registers */
+#define BLOCK_ERASE_32 0x52 /* Erase a Block (32kb) */
+#define CHIP_ERASE 0x60 /* Erase Entire Chip */
+#define MNFTR_DEV_ID 0x90 /* Read Manufacturer ID followed by Device ID */
+#define JEDEC_ID 0x9F /* Read JEDEC ID */
+#define CHIP_RELEASE 0xAB /* Release chip from power down */
+#define BLOCK_ERASE_64 0xD8 /* Erase a Block (64kb) */
+
+static const uint8_t fpga_version[] = {28, 31, 33, 35, 37};
+static const struct mtac_reg_s loregs[3] = {
+ {-1, 0, 0, 0, 2, 0, 0}, /* PAGE_REG */
+ {-1, 0, 7, 0, 1, 0, 0}, /* SOFT_RESET */
+ {-1, 1, 0, 0, 8, 1, 103} /* VERSION */
+};
+
+/* -------------------------------------------------------------------------- */
+/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
+
+static const char
+ *valid_hashes[3][4] =
+ {
+ {
+ "d9f811fcab57947db3c2323242885a32a7f095a069d3386a148466e7f3da53"
+ "53", /* mtcdt v28*/
+ "903c1199df46d38683b1aa9fc88310abe2f317c01c3aefa77987990874aba4"
+ "20", /* mtcdt v31*/
+ "7c190506b969aea6198daffb6c9b47685f3a4dc3ce18565c66542bac27d6f2"
+ "4e", /* mtcdt v33*/
+ "72bcdfda72bf8677d585330caa3d609615d08d4ca6d7951f0ebbcb5a93306b"
+ "3c" /* mtcdt v35*/
+ },
+ {
+ "54e41b186b2c91f1bcf249648c50357165d361101fc4fe20ee9b8f0c40dce2"
+ "5d" /* mtcdt3 v35*/
+ },
+ {
+ "07317fe9ca59393c074215c9d923d8d01025654883291a5e89b27d21668e22"
+ "63", /* mtcap v28*/
+ "f208ef5cae03e703951bb8799172a5eaadb74ddb90bf3e65c32030c008a88e"
+ "75", /* mtcap v31*/
+ "aaecd468b187703dbbf76022b00268dba2a5f25300da6486d420f476c83638"
+ "5c", /* mtcap v33*/
+ "876cc5683f612c09f96bacb27fff170358c90f3bd76a5c61ec41504eabba83"
+ "13" /* mtcap v35*/
+ },
+};
+
+/* -------------------------------------------------------------------------- */
+/* --- PRIVATE FUNCTIONS DEFINITION ------------------------------------------
+ */
+
+/* hash outputBuffer */
+void Mtac15Fpga::sha256_hash_string(unsigned char hash[SHA256_DIGEST_LENGTH],
+ char outputBuffer[65]) {
+ int i = 0;
+ for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+ sprintf(outputBuffer + (i * 2), "%02x", (unsigned char)hash[i]);
+ }
+ outputBuffer[64] = 0;
+ printInfo("OutputBuffer hash: %s", outputBuffer);
+}
+
+/* Initialize, update and finalize sha256 */
+void Mtac15Fpga::sha256(char *string, char outputBuffer[65]) {
+ unsigned char hash[SHA256_DIGEST_LENGTH];
+ int len;
+ SHA256_CTX sha256;
+ SHA256_Init(&sha256);
+ len = strlen(string);
+ SHA256_Update(&sha256, string, len);
+ SHA256_Final(hash, &sha256);
+ int i = 0;
+ for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+ sprintf(outputBuffer + (i * 2), "%02x", (unsigned char)hash[i]);
+ }
+ outputBuffer[64] = 0;
+ printInfo("OutputBuffer finalized: %s", outputBuffer);
+}
+
+/* Open input file and verify sha256 with verified list */
+int Mtac15Fpga::sha256_file(const char *path) {
+ printInfo("Checking hash on input file: %s", path);
+
+ FILE *file = fopen(path, "rb");
+ if (!file) {
+ printError("File %s not found", path);
+ return -1;
+ } else {
+ printInfo("Checking file %s", path);
+ }
+
+ unsigned int i;
+ char file_hash[65];
+ unsigned char hash[SHA256_DIGEST_LENGTH];
+ SHA256_CTX sha256;
+ SHA256_Init(&sha256);
+ const int bufSize = 32768;
+ unsigned char *buffer = (unsigned char *)malloc(bufSize);
+ int bytesRead = 0;
+
+ if (!buffer)
+ return ENOMEM;
+ while ((bytesRead = fread(buffer, 1, bufSize, file))) {
+ SHA256_Update(&sha256, buffer, bytesRead);
+ }
+ SHA256_Final(hash, &sha256);
+ sha256_hash_string(hash, file_hash);
+ fclose(file);
+ free(buffer);
+
+ printInfo("Calculated input file hash: %s", file_hash);
+ for (i = 0; i < sizeof(valid_hashes[hardwareType]) /
+ sizeof(valid_hashes[hardwareType][0]);
+ ++i) {
+ if (!strcmp(valid_hashes[hardwareType][i], file_hash)) {
+ printInfo("File verified");
+ return 0;
+ }
+ }
+ printError("Invalid input file");
+ return -1;
+}
+
+int Mtac15Fpga::spiOpen() {
+ 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) {
+ printError("Malloc failed");
+ return -1;
+ }
+
+ /* open SPI device */
+ dev = open(spiPath.c_str(), O_RDWR);
+ if (dev < 0) {
+ printError("Failed to open SPI device %s", spiPath.c_str());
+ 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)) {
+ printError("SPI port failed to set IOC MODE 0");
+ 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)) {
+ printError("SPI port failed to set MAX SPEED");
+ 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)) {
+ printError("SPI port failed to set MSB FIRST");
+ 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)) {
+ printError("SPI port failed to set 8 bits-per-word");
+ close(dev);
+ return -1;
+ }
+
+ *spi_device = dev;
+ spi_target_ptr = (void *)spi_device;
+ return 0;
+}
+
+int Mtac15Fpga::spiRead(uint8_t spi_mux_target, 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] = spi_mux_target;
+ 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) {
+ printError("SPI read failure");
+ return -1;
+ } else {
+ *data = in_buf[command_size - 1];
+ return 0;
+ }
+}
+
+/* Simple spi write to fpga*/
+int Mtac15Fpga::spiWrite(uint8_t spi_mux_target, uint8_t address,
+ uint8_t data) {
+ int spi_device;
+ uint8_t out_buf[3];
+ 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] = spi_mux_target;
+ out_buf[1] = WRITE_ACCESS | (address & 0x7F);
+ out_buf[2] = data;
+ command_size = 3;
+
+ /* I/O transaction */
+ memset(&k, 0, sizeof(k)); /* clear k */
+ k.tx_buf = (unsigned long)out_buf;
+ k.len = command_size;
+ k.speed_hz = SPI_SPEED;
+ k.cs_change = 1;
+ k.bits_per_word = 8;
+ a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+
+ /* determine return code */
+ if (a != (int)k.len) {
+ printError("SPI write failure");
+ return -1;
+ } else {
+ printDebug("SPI write success");
+ return 0;
+ }
+}
+
+int Mtac15Fpga::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) {
+ printError("SPI port failed to close");
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+/* write to creset pin */
+int Mtac15Fpga::cresetWrite(char num) {
+ std::string cresetPath = SYSFS_PLATFORM + port + CRESET;
+ int fd = open(cresetPath.c_str(), O_WRONLY);
+ if (fd < 0) {
+ printError("Unable to lock file, are you root?");
+ return -1;
+ }
+ write(fd, &num, 1);
+ close(fd);
+ return 0;
+}
+
+/*
+ Release Power-down instruction releases the device from
+ said state allowing device communication
+*/
+int Mtac15Fpga::releaseDevice() {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int ret;
+ size_t command_size = 5;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = CHIP_RELEASE;
+ out_buf[1] = 0;
+ out_buf[2] = 0;
+ out_buf[3] = 0;
+ out_buf[4] = 0;
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 1;
+ k.bits_per_word = 8;
+ ret = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+ mtac_ret = spiClose();
+
+ /* determine return code */
+ if (ret != (int)k.len) {
+ printError("Release failed");
+ mtac_ret = -1;
+ } else {
+ usleep(1000);
+ mtac_ret = 0;
+ }
+ return mtac_ret;
+}
+
+/*
+ Write enable instruction sets the write enable latch
+ in the status register to 1. It needs to be set before
+ a page can be programmed or chip erased
+*/
+int Mtac15Fpga::writeEnable() {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int ret;
+ size_t command_size = 1;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = 0x06;
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 0;
+ k.bits_per_word = 8;
+ ret = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+ mtac_ret = spiClose();
+
+ /* determine return code */
+ if (ret != (int)k.len) {
+ printError("Write Enable failed");
+ mtac_ret = -1;
+ } else {
+ usleep(1000);
+ printDebug("Write Enable successful");
+ mtac_ret = 0;
+ }
+ return mtac_ret;
+}
+
+/*
+ Verify that the chip erase was successful
+*/
+int Mtac15Fpga::chipEraseVerify() {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int a, ret;
+ uint16_t command_size = 256 + 5;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = 0x0B;
+ out_buf[1] = 0x00;
+ out_buf[2] = 0x00;
+ out_buf[3] = 0x00;
+ out_buf[4] = 0x00;
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 1;
+ k.bits_per_word = 8;
+ ret = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+
+ /* determine return code */
+ if (ret != (int)k.len) {
+ printError("Chip transfer failed");
+ mtac_ret = -1;
+ } else {
+ printDebug("Chip transfer successful");
+ mtac_ret = 0;
+ }
+ mtac_ret = spiClose();
+ /* verify that the chip was erased */
+ for (a = 5; a < command_size; a++) {
+ if (in_buf[a] != 0xFF) {
+ mtac_ret = spiClose();
+ return mtac_ret;
+ }
+ }
+ return mtac_ret;
+}
+
+/*
+ Chip erase instruction sets all memory within
+ the device to the erased state of all 1s (FFh)
+*/
+int Mtac15Fpga::chipErase() {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int ret;
+ size_t command_size = 1;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = CHIP_ERASE;
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 0;
+ k.bits_per_word = 8;
+ ret = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+ sleep(5);
+ mtac_ret = spiClose();
+
+ /* determine return code */
+ if (ret != (int)k.len) {
+ printError("Chip Erase transfer failed");
+ mtac_ret = -1;
+ } else {
+ printDebug("Chip Erase transfer successful");
+ chipEraseVerify();
+ mtac_ret = 0;
+ }
+ return mtac_ret;
+}
+
+/* erase entire flash */
+int Mtac15Fpga::mtacErase() {
+ int ret;
+ printInfo("Erasing flash");
+ /* pull device out of powerdown state */
+ ret = releaseDevice();
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* enable writing to flash */
+ ret = writeEnable();
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* send chip erase command to flash */
+ ret = chipErase();
+ if (ret != 0) {
+ return ret;
+ }
+ /* pull device out of powerdown state */
+ ret = releaseDevice();
+ if (ret != 0) {
+ return ret;
+ }
+ return 0;
+}
+
+/*
+ Page Program instruction allows writing upto 256 bytes (a page) of
+ data to be programmed at previously erased memory locations Write
+ enable must be issued first
+*/
+int Mtac15Fpga::pageProgram(uint8_t adr_lower, uint8_t adr_higher,
+ uint32_t data[256]) {
+ int mtac_ret;
+ int spi_device;
+ struct spi_ioc_transfer k;
+ int a, h;
+ size_t command_size = 260;
+ char out_buf[command_size];
+ char in_buf[command_size];
+
+ /* prepare frame to be sent */
+ out_buf[0] = PAGE_PROGRAM;
+ out_buf[1] = adr_higher;
+ out_buf[2] = adr_lower;
+ out_buf[3] = 0x00;
+ for (h = 0; h < 256; h++) {
+ out_buf[h + 4] = data[h];
+ }
+
+ /* I/O transaction */
+ mtac_ret = spiOpen();
+ spi_device =
+ *(int *)spi_target_ptr; /* spi_target cannot be null beforehand */
+ 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.speed_hz = SPI_SPEED;
+ k.cs_change = 1;
+ k.bits_per_word = 8;
+ a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
+ printDebug("Writing Page %x%x to MTAC\r", adr_higher, adr_lower);
+ usleep(10000);
+
+ mtac_ret = spiClose();
+
+ /* determine return code */
+ if (a != (int)k.len) {
+ printError("SPI write failure");
+ mtac_ret = -1;
+ } else {
+ printDebug("SPI write success");
+ mtac_ret = 0;
+ }
+ return mtac_ret;
+}
+
+/* write to mtac card with input file */
+int Mtac15Fpga::mtacProgram(const char input_file[]) {
+ FILE *f;
+ struct stat st;
+ size_t file_size;
+ int ret = 0;
+ uint32_t i = 0, index, result, offset, page_address, no_pages,
+ page_data[256];
+ uint8_t adr_lower, adr_higher;
+
+ /* get data array from file to be writen */
+ f = fopen(input_file, "r");
+ stat(input_file, &st);
+ file_size = st.st_size;
+ uint8_t *p_array;
+ p_array = (uint8_t *)malloc(sizeof(uint8_t) * file_size);
+ unsigned int data[file_size];
+ while ((result = fscanf(f, "%x ", data + i)) == 1) {
+ i++;
+ }
+ fclose(f);
+ no_pages = ceil(i / 256.0);
+
+ /* program one page at a time */
+ for (page_address = 0x00; page_address < no_pages; page_address++) {
+ /* mask page address */
+ adr_higher = (page_address >> 8) & 0xff;
+ adr_lower = page_address & 0xff;
+ /* calculate initial data offset */
+ offset = page_address * 256;
+ /* enable writing to flash */
+ ret = writeEnable();
+ if (ret != 0) {
+ free(p_array);
+ break;
+ }
+ /* assign data for page to be written */
+ for (index = 0; index < 256; index++) {
+ page_data[index] = index + offset > i ? 0xff : data[index + offset];
+ }
+ /* program single page*/
+ ret = pageProgram(adr_lower, adr_higher, page_data);
+ if (ret != 0) {
+ free(p_array);
+ break;
+ }
+ /* release device from page program powerdown */
+ ret = releaseDevice();
+ if (ret != 0) {
+ free(p_array);
+ break;
+ }
+ }
+ free(p_array);
+ return ret;
+}
+
+/* Make sure no device is using the spidev bus to prevent contention*/
+int Mtac15Fpga::busContention() {
+ char number[1024];
+ FILE *f = popen("lsof", "r");
+ while (fgets(number, 1024, f) != NULL) {
+ if (strstr(number, "spidev") != NULL) {
+ printError("The accessory card is being used by another process: "
+ "\n %sPlease "
+ "close all LoRaWAN processes and try again",
+ number);
+ pclose(f);
+ return -1;
+ }
+ }
+ pclose(f);
+ return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
+
+/* Constructor used fpga upgrade utility */
+Mtac15Fpga::Mtac15Fpga(std::string inputFile, std::string forcedPath) {
+ FILE *fp = fopen(DEVICE_INFO_FILE, "r");
+ char buf[0XFFFF];
+ rapidjson::FileReadStream input(fp, buf, sizeof(buf));
+ deviceInfo.ParseStream(input);
+ fclose(fp);
+
+ if (!deviceInfo.HasMember("hardwareVersion")) {
+ printError("%s does not have hardware version info, exiting",
+ DEVICE_INFO_FILE);
+ return;
+ }
+ std::string hwVersion = deviceInfo["hardwareVersion"].GetString();
+
+ if (deviceInfo.HasMember("accessoryCards") &&
+ deviceInfo["accessoryCards"].IsArray() &&
+ deviceInfo["accessoryCards"].Size() > 0) {
+ if (hwVersion.find("MTCDT3") != std::string::npos) {
+ hardwareType = HARDWARE_MTCDT3;
+ } else if (hwVersion.find("MTCDT") != std::string::npos) {
+ hardwareType = HARDWARE_MTCDT;
+ } else {
+ return;
+ }
+ if (inputFile.empty()) {
+ input_file = MTCDT_DEFAULT_FILE;
+ } else {
+ input_file = inputFile;
+ }
+ port = deviceInfo["accessoryCards"][0]["port"].GetString();
+ if (port.back() == '2') {
+ spiPath = "/dev/spidev1.2";
+ } else {
+ spiPath = "/dev/spidev0.2";
+ }
+ getFpgaVersion();
+ printInfo("Current FPGA version: %d", fpgaVersion);
+ } else if (hwVersion.find("MTCAP") != std::string::npos) {
+ hardwareType = HARDWARE_MTCAP;
+ if (inputFile.empty()) {
+ input_file = MTCAP_DEFAULT_FILE;
+ } else {
+ input_file = inputFile;
+ }
+ spiPath = "/dev/spidev0.0";
+ getFpgaVersion();
+ printInfo("Current FPGA version: %d", fpgaVersion);
+ }
+}
+
+/* Constructor used by device_info.json generator */
+Mtac15Fpga::Mtac15Fpga(const std::string path) { spiPath = path; }
+
+int Mtac15Fpga::FpgaVersion() { return fpgaVersion; }
+
+/* Open spi device and get fpga version from register */
+int Mtac15Fpga::getFpgaVersion() {
+ int ret = spiOpen();
+ if (ret != 0) {
+ printError("Could not open SPI port %s", spiPath.c_str());
+ } else {
+ /* detect if the gateway has an FPGA with SPI mux header support */
+ ret = spiRead(MTAC_FPGA, loregs[MTAC_VERSION].addr, &fpgaVersion);
+ if (ret != 0) {
+ printError("Could not read FPGA version");
+ }
+ spiClose();
+ }
+ spi_target_ptr = NULL;
+ return ret;
+}
+
+/* setup and upgrade the mtac card with the file specified */
+int Mtac15Fpga::upgradeFpga() {
+ if (hardwareType == HARDWARE_INVALID) {
+ printError("Invalid hardware");
+ return -1;
+ }
+
+ int ret;
+
+ if (input_file.empty()) {
+ printError("Invalid input file %s", input_file.c_str());
+ return -1;
+ }
+ /* check that no other device is using the bus */
+ ret = busContention();
+ if (ret != 0) {
+ return ret;
+ }
+ /* check MTAC Hardware Compatibility */
+ printInfo("Checking hardware compatibility");
+
+ /* check input file checksum */
+ ret = sha256_file(input_file.c_str());
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* pull creset down to access spi flash */
+ ret = cresetWrite('0');
+ if (ret != 0) {
+ return ret;
+ }
+ sleep(1);
+
+ /* erase chip before flashing new firmware */
+ ret = mtacErase();
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* program user specified firmware */
+ printInfo("Programming flash");
+ ret = mtacProgram(input_file.c_str());
+ if (ret != 0) {
+ return ret;
+ } else {
+ printInfo("Write Complete. Resetting FPGA");
+ }
+
+ /* pull creset up to access FPGA */
+ ret = cresetWrite('1');
+ if (ret != 0) {
+ return ret;
+ }
+ sleep(5);
+ printInfo("Reading New FPGA configuration");
+ ret = getFpgaVersion();
+ if (ret != 0) {
+ return ret;
+ }
+ printInfo("New FPGA version: %d", fpgaVersion);
+ return 0;
+}