From 54f86b83b60192f8b33dad90b33b47246165ac51 Mon Sep 17 00:00:00 2001 From: Harsh Sharma Date: Thu, 3 Mar 2022 14:44:44 -0600 Subject: LoRa updates with MTAC-003 --- src/AccessoryCards/AccessoryCard.cpp | 26 ++ src/AccessoryCards/AcessoryCard.cpp | 21 - src/AccessoryCards/Gpiob.cpp | 36 +- src/AccessoryCards/LoraCard.cpp | 38 +- src/AccessoryCards/LoraCard03.cpp | 53 +++ src/AccessoryCards/LoraCard10.cpp | 38 ++ src/AccessoryCards/LoraCard15.cpp | 195 ++------- src/AccessoryCards/LoraCard21.cpp | 48 ++- src/AccessoryCards/LoraCard21Ext.cpp | 42 +- src/AccessoryCards/LoraCard2G4.cpp | 32 ++ src/AccessoryCards/Mfser.cpp | 47 +- src/AccessoryCards/Mtac15Fpga.cpp | 803 +++++++++++++++++++++++++++++++++++ 12 files changed, 1109 insertions(+), 270 deletions(-) create mode 100644 src/AccessoryCards/AccessoryCard.cpp delete mode 100644 src/AccessoryCards/AcessoryCard.cpp create mode 100644 src/AccessoryCards/LoraCard03.cpp create mode 100644 src/AccessoryCards/LoraCard10.cpp create mode 100644 src/AccessoryCards/LoraCard2G4.cpp create mode 100644 src/AccessoryCards/Mtac15Fpga.cpp (limited to 'src/AccessoryCards') 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; +} -- cgit v1.2.3