summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhii Voloshynov <serhii.voloshynov@globallogic.com>2024-05-15 16:20:54 +0300
committerSerhii Voloshynov <serhii.voloshynov@globallogic.com>2024-05-27 18:29:53 +0300
commit0b55b2997d17bbce5bea3ebe1f5700dca184574f (patch)
treedfb90e834968d88060eaf937f2e9cf83cd1ee477
parent1eea7eae25074cc18e37c80cd5ede91e13213920 (diff)
downloadmts-io-sysfs-0b55b2997d17bbce5bea3ebe1f5700dca184574f.tar.gz
mts-io-sysfs-0b55b2997d17bbce5bea3ebe1f5700dca184574f.tar.bz2
mts-io-sysfs-0b55b2997d17bbce5bea3ebe1f5700dca184574f.zip
[MTX-5302] MTR3 R.7.0: Serial IP functionality support GP-2336
-rw-r--r--include/Device/Device.h23
-rw-r--r--include/General.h1
-rw-r--r--src/Device/Device.cpp190
-rw-r--r--src/MtsIoSysfs.cpp17
4 files changed, 171 insertions, 60 deletions
diff --git a/include/Device/Device.h b/include/Device/Device.h
index bcf0cff..a1c0b1b 100644
--- a/include/Device/Device.h
+++ b/include/Device/Device.h
@@ -23,8 +23,6 @@ class Device {
static std::map<std::string, bool> capabilityList;
static std::map<std::string, std::string> ethSwitchList;
static std::map<std::string, std::string> deviceInfoList;
- static std::vector<std::string> dInputs;
- static std::vector<std::string> dOutputs;
static const std::regex apFilters;
static const std::regex serialModeFilter;
@@ -33,6 +31,8 @@ class Device {
static const std::regex mtcdt3HwVersionFilters;
static const std::regex iotRtrVersionFilters;
static const std::regex mtrFilters;
+ static std::string extIoStr;
+ static std::string serialStr;
const unsigned int accessoryCardsListSize = 7;
@@ -150,6 +150,18 @@ class Device {
std::vector<std::unique_ptr<AccessoryCard>> accessoryCardsList;
+ const std::string SERIAL_MODE = "mode";
+ const std::string SERIAL_TERMINATION = "rs4xx-term-res";
+ const std::string SERIAL_MODE_RS232 = "rs232";
+ const std::string SERIAL_MODE_RS485 = "rs485-half";
+ const std::map<std::string, uint32_t> mModes = {{SERIAL_MODE_RS232, 0}, {SERIAL_MODE_RS485, 0}};
+
+ const std::string CONTROL_PIN_SERIAL_MODE = "MXC2_RS485_EN";
+ const std::string CONTROL_PIN_TERMINATION = "MXC2_RS485_TERM_EN";
+ const std::string HW_VERSION_FILE = "/sys/devices/platform/mts-io/hw-version";
+ std::string program_name;
+ std::string hw_version;
+
public:
Device();
void getSystemTreeJson(const char *dir_name);
@@ -169,7 +181,7 @@ class Device {
std::vector<std::string> &results);
void printJson();
void printVersion(std::string name);
- void printUsage(std::string program);
+ void printUsage();
void show(std::string program);
void showTrigger(std::string name);
void sortAccessoryCards();
@@ -181,6 +193,11 @@ class Device {
void writeJson(const rapidjson::Document &json, const std::string &file);
bool readJson(rapidjson::Document &json, const std::string &file);
void simpleError(std::string msg, int error, int exitval);
+ void setSerialModesMTR3(const std::string &mode, const std::string &value);
+ void showSerialModesMTR3(const std::string &mode);
+ int getPinValue(const std::string &name);
+ void setProgramName(const std::string &name);
+ void setHWVersion();
};
#endif /* DEVICE_H_ */
diff --git a/include/General.h b/include/General.h
index 4429b3d..58c2a09 100644
--- a/include/General.h
+++ b/include/General.h
@@ -76,6 +76,7 @@ typedef unsigned int uint; // 32 bit - even on 64 bit machines
#define KEY_EXTIO "extIo"
#define KEY_DOUTPUTS "dOutputs"
#define KEY_DINPUTS "dInputs"
+#define KEY_SERIALS "serialPorts"
enum HardwareType {
HARDWARE_MTCDT,
diff --git a/src/Device/Device.cpp b/src/Device/Device.cpp
index b2588eb..be198f1 100644
--- a/src/Device/Device.cpp
+++ b/src/Device/Device.cpp
@@ -42,16 +42,12 @@ std::map<std::string, bool> Device::capabilityList = {
{"cell", false},
{"din", false},
{"dout", false},
- {"externalSerialPort", false},
{"gpio", false},
{"gps", false},
{"lora", false},
{"loraLbt", false},
{"loraNetworkServer", false},
{"nodeRed", false},
- {"rs232", false},
- {"rs422", false},
- {"rs485", false},
{"serial", false},
{"supercap", false},
{"wifi", false},
@@ -60,8 +56,8 @@ std::map<std::string, bool> Device::capabilityList = {
{"userDataEncryption", false}};
std::map<std::string, std::string> Device::ethSwitchList;
-std::vector<std::string> Device::dInputs;
-std::vector<std::string> Device::dOutputs;
+std::string Device::extIoStr;
+std::string Device::serialStr;
std::map<std::string, std::string> Device::deviceInfoList = {
{"deviceId", ""},
@@ -179,19 +175,33 @@ void Device::getSystemTreeJson(const char *dir_name) {
} else if (strcmp(d_name, "hw-version") == 0) {
deviceInfoList["hardwareVersion"] = fileData;
if (regex_match(fileData, mtcdt3HwVersionFilters)) {
- capabilityList["rs232"] = true;
- capabilityList["rs422"] = true;
- capabilityList["rs485"] = true;
capabilityList["serial"] = true;
}
if (regex_match(fileData, iotRtrVersionFilters)) {
+ mapMacAddress2Iotr();
/*
The order of the elements is important! This array is used to access Digital IOs,
in particular in SMS commands!
*/
- dInputs.push_back("USER_DIO_IN");
- dOutputs.push_back("USER_DIO_OUT");
- mapMacAddress2Iotr();
+ extIoStr = "{\"dInputs\":[\"USER_DIO_IN\"],\"dOutputs\":[\"USER_DIO_OUT\"]}";
+ capabilityList["serial"] = true;
+ serialStr = "[{"
+ "\"available\": true,"
+ "\"id\": \"serial0\","
+ "\"name\": \"RS232\","
+ "\"device\": \"/dev/ttymxc1\","
+ "\"role\": \"DCE\","
+ "\"modes\": {\"RS-232\": [\"hw-flowcontrol\", \"dcd-dtr\"]},"
+ "\"speed\": [9600, 19200, 38400, 57600, 115200]"
+ "},{"
+ "\"available\": true,"
+ "\"id\": \"serial1\","
+ "\"name\": \"RS232/485\","
+ "\"device\": \"/dev/ttymxc2\","
+ "\"role\": \"DCE\","
+ "\"modes\": {\"RS-232\": [\"hw-flowcontrol\"], \"RS-485-HALF\": [\"rs4xx-termination\"]},"
+ "\"speed\": [9600, 19200, 38400, 57600, 115200, 230400, 460800, 930600]"
+ "}]";
}
} else if (strcmp(d_name, "mac-eth") == 0) {
deviceInfoList["macAddress"] = fileData;
@@ -318,28 +328,14 @@ void Device::load() {
deviceInfo.AddMember("capabilities", capabilities, alloc);
deviceInfo.AddMember("ethSwitch", ethSwitch, alloc);
deviceInfo.AddMember("accessoryCards", accessoryCards, alloc);
- rapidjson::Document inp;
- auto &inpAlloc = inp.GetAllocator();
- inp.SetArray();
- for (const auto &input : dInputs) {
- rapidjson::Value value;
- value.SetString(input.c_str(), input.length(), inpAlloc);
- inp.PushBack(value, inpAlloc);
- }
- rapidjson::Document out;
- auto &outAlloc = out.GetAllocator();
- out.SetArray();
- for (const auto &output : dOutputs) {
- rapidjson::Value value;
- value.SetString(output.c_str(), output.length(), outAlloc);
- out.PushBack(value, outAlloc);
- }
rapidjson::Document extIo;
- extIo.SetObject();
+ extIo.Parse<0>(extIoStr.c_str());
auto &extAlloc = extIo.GetAllocator();
- extIo.AddMember(KEY_DINPUTS, inp, extAlloc);
- extIo.AddMember(KEY_DOUTPUTS, out, extAlloc);
deviceInfo.AddMember(KEY_EXTIO, extIo, extAlloc);
+ rapidjson::Document serial;
+ serial.Parse<0>(serialStr.c_str());
+ auto &serAlloc = serial.GetAllocator();
+ deviceInfo.AddMember(KEY_SERIALS, serial, serAlloc);
}
void Device::mapFileToCapability() {
@@ -350,10 +346,6 @@ void Device::mapFileToCapability() {
S_IFREG) { /* lora-network-server is a regular file */
capabilityList["loraNetworkServer"] = true;
}
- if (fileType("/dev/ext_serial") ==
- S_IFCHR) { /* ext_serial is a character device */
- capabilityList["externalSerialPort"] = true;
- }
if (fileType("/usr/bin/dockerd") ==
S_IFREG) { /* Docker is a regular file */
capabilityList["docker"] = true;
@@ -450,9 +442,10 @@ void Device::printVersion(std::string name) {
exitHandler(0);
}
-void Device::printUsage(std::string program) {
+
+void Device::printUsage() {
std::vector<std::string> showResults;
- printf("Usage: %s [ OPTIONS ] OBJECT [--] [ ARGUMENTS ]\n", program.c_str());
+ printf("Usage: %s [ OPTIONS ] OBJECT [--] [ ARGUMENTS ]\n", program_name.c_str());
printf("Legacy OBJECT options:\n");
printf(" init : init & make device info json\n");
printf(" json : init & make device info json\n");
@@ -489,7 +482,7 @@ void Device::printUsage(std::string program) {
printf("\n");
printf("show-name:\n");
printf("Usage:\n");
- printf("--show-name <name>\n");
+ printf("--show <name>\n");
printDir("", showResults);
sort(showResults.begin(),
showResults.end()); // Unix file tree is not sorted
@@ -498,10 +491,15 @@ void Device::printUsage(std::string program) {
if (!regex_match(showResult, showFilters))
printf(" %s\n", showResult.c_str());
}
+ if (regex_match(hw_version, iotRtrVersionFilters)) {
+ printf(" serial1/%s\n", SERIAL_TERMINATION.c_str());
+ printf(" serial1/%s\n", SERIAL_MODE.c_str());
+ printf("}\n");
+ }
printf("\n");
printf("store-name:\n");
printf("Usage:\n");
- printf("--store-name <name> <value>\n");
+ printf("--store <name> <value>\n");
for (std::string showResult : showResults) {
if (showResult == "radio-reset") {
printf(" %s { 0 }\n", showResult.c_str());
@@ -512,14 +510,23 @@ void Device::printUsage(std::string program) {
} else if (showResult == "reset-monitor-intervals") {
printf(" %s { short-interval long-interval }\n",
showResult.c_str());
- } else if (regex_match(showResult, serialModeFilter)) {
- printf(" %s { loopback | rs232 | rs485-half | "
- "rs422-485-full }\n",
- showResult.c_str());
} else if (!regex_match(showResult, storeFilters)) {
printf(" %s BOOLEAN\n", showResult.c_str());
}
}
+ if (regex_match(hw_version, iotRtrVersionFilters)) {
+ printf(" serial1/%s { 0 | 1 }\n", SERIAL_TERMINATION.c_str());
+ printf(" serial1/%s {", SERIAL_MODE.c_str());
+ unsigned int c = 1;
+ for (auto const &m : mModes) {
+ printf(" %s ", m.first.c_str());
+ if (c != mModes.size()) {
+ printf("|");
+ }
+ c++;
+ };
+ printf("}\n");
+ }
printf("\n");
exitHandler(0);
}
@@ -697,7 +704,8 @@ unsigned int Device::gpio_request::offset()
* driver. GPIOs can only be zero
* or one, never a text string.
*/
-void Device::show(std::string name) {
+
+int Device::getPinValue(const std::string &name) {
std::string fileData;
if(isupper(name[0])) {
gpio_request gr(this, name);
@@ -705,10 +713,9 @@ void Device::show(std::string name) {
enum gpiod_line_value lv = gpiod_line_request_get_value(gr.request(),gr.offset());
if(lv != GPIOD_LINE_VALUE_ERROR) {
if(lv == GPIOD_LINE_VALUE_INACTIVE)
- std::cout << "0\n";
+ return 0;
else
- std::cout << "1\n";
- exitHandler(0);
+ return 1;
} else
simpleError("Invalid GPIO line value", errno, 109);
}
@@ -716,12 +723,24 @@ void Device::show(std::string name) {
int32_t code = MTS::System::readFile(SYSFS_PLATFORM + name, fileData);
if (code == 0) {
- printf("%s", fileData.c_str());
- exitHandler(0);
+ if (fileData == "1") {
+ return 1;
+ } else {
+ return 0;
+ }
}
printError("cat: can't open %s%s: %s",
SYSFS_PLATFORM, name.c_str(),strerror(errno));
exitHandler(99);
+ return 99; // never be returned
+}
+
+void Device::show(std::string name) {
+ if (regex_match(hw_version, iotRtrVersionFilters)) {
+ showSerialModesMTR3(name);
+ }
+ printf("%i", getPinValue(name));
+ exitHandler(0);
} // End of show
void Device::showTrigger(std::string name) {
@@ -745,7 +764,9 @@ void Device::store(std::string name, std::string value) {
}
printDebug("Setting %s to %s", name.c_str(), value.c_str());
-
+ if (regex_match(hw_version, iotRtrVersionFilters)) {
+ setSerialModesMTR3(name, value);
+ }
if(isupper(name[0])) {
enum gpiod_line_value lv = GPIOD_LINE_VALUE_ERROR;
@@ -872,3 +893,72 @@ void Device::storeOutputStateToNonvolatile(const std::string& name, const std::s
}
writeJson(stateIo, STORED_DIGITAL_OUTPUTS_STATE_FILE);
}
+
+void Device::setSerialModesMTR3(const std::string &parameter, const std::string &value) {
+ std::vector<std::string> parts = MTS::Text::split(parameter, '/');
+ if (parts.size() < 2) {
+ return;
+ }
+ const std::string &serialName = parts[0];
+ const std::string &mode = parts[1];
+ if (serialName != "serial1") {
+ printUsage();
+ }
+ if ((mode != SERIAL_MODE) && (mode != SERIAL_TERMINATION)) {
+ printUsage();
+ }
+ if (mode == SERIAL_MODE) {
+ if ((value != SERIAL_MODE_RS232) && (value != SERIAL_MODE_RS485)) {
+ printUsage();
+ }
+ if (value == SERIAL_MODE_RS232) {
+ store(CONTROL_PIN_SERIAL_MODE, "0");
+ }
+ if (value == SERIAL_MODE_RS485) {
+ store(CONTROL_PIN_SERIAL_MODE, "1");
+ }
+ exitHandler(0);
+ } else if (mode == SERIAL_TERMINATION) {
+ store(CONTROL_PIN_TERMINATION, value);
+ exitHandler(0);
+ }
+}
+
+void Device::showSerialModesMTR3(const std::string &parameter) {
+ std::vector<std::string> parts = MTS::Text::split(parameter, '/');
+ if (parts.size() < 2) {
+ return;
+ }
+ const std::string &serialName = parts[0];
+ const std::string &mode = parts[1];
+ if (serialName != "serial1") {
+ printUsage();
+ }
+ if ((mode != SERIAL_MODE) && (mode != SERIAL_TERMINATION)) {
+ printUsage();
+ }
+ if (mode == SERIAL_MODE) {
+ if (getPinValue(CONTROL_PIN_SERIAL_MODE) == 1) {
+ std::cout << SERIAL_MODE_RS485 << std::endl;
+ } else {
+ std::cout << SERIAL_MODE_RS232 << std::endl;
+ }
+ exitHandler(0);
+ } else if (mode == SERIAL_TERMINATION) {
+ std::cout << getPinValue(CONTROL_PIN_TERMINATION) << std::endl;
+ exitHandler(0);
+ }
+}
+
+void Device::setProgramName(const std::string &name){
+ program_name = name;
+}
+
+void Device::setHWVersion(){
+ std::ifstream is(HW_VERSION_FILE);
+ if (!is.is_open()) {
+ printDebug("Can't read to %s: %s", HW_VERSION_FILE, strerror(errno));
+ return;
+ }
+ std::getline(is, hw_version);
+} \ No newline at end of file
diff --git a/src/MtsIoSysfs.cpp b/src/MtsIoSysfs.cpp
index ab68c8c..20e2925 100644
--- a/src/MtsIoSysfs.cpp
+++ b/src/MtsIoSysfs.cpp
@@ -44,10 +44,9 @@ static enum action_code action;
int main(int argc, char **argv) {
Device m;
+ m.setProgramName(argv[0]);
action = ACTION_NONE;
- if (argc < 2) {
- m.printUsage(argv[0]);
- }
+
std::string fpgaFilePath = "";
std::string forcedAP = "";
std::string name = "";
@@ -55,6 +54,10 @@ int main(int argc, char **argv) {
int duration = 0;
MTS::Logger::setPrintLevel(MTS::Logger::PrintLevel::INFO_LEVEL, true);
+ m.setHWVersion();
+ if (argc < 2) {
+ m.printUsage();
+ }
int c;
static struct option long_options[] = {
{"help", no_argument, nullptr, 'h'},
@@ -148,11 +151,11 @@ int main(int argc, char **argv) {
exit(-1);
}
case 'h': {
- m.printUsage(argv[0]);
+ m.printUsage();
exit(0);
}
default:
- m.printUsage(argv[0]);
+ m.printUsage();
exit(-1);
}
}
@@ -213,7 +216,7 @@ int main(int argc, char **argv) {
switch (action) {
case ACTION_NONE: {
- m.printUsage(argv[0]);
+ m.printUsage();
}
case ACTION_SHOW: {
m.show(name);
@@ -251,7 +254,7 @@ int main(int argc, char **argv) {
case ACTION_VERSION: {
m.printVersion(argv[0]);
}
- default: { m.printUsage(argv[0]); }
+ default: { m.printUsage(); }
}
return 0;