Merge pull request 'this fixes SCEX ping for RPi' (#147) from mueller/uart-test-task-update into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good

Reviewed-on: #147
Reviewed-by: Jakob.Meier <meierj@irs.uni-stuttgart.de>
This commit is contained in:
Jakob Meier 2022-02-23 18:49:39 +01:00
commit c83020d2c1
2 changed files with 48 additions and 44 deletions

View File

@ -1,16 +1,11 @@
#include "UartTestClass.h" #include "UartTestClass.h"
#include <fsfw/tasks/TaskFactory.h>
#if defined(RASPBERRY_PI)
#include "rpiConfig.h"
#elif defined(XIPHOS_Q7S)
#include "q7sConfig.h"
#endif
#include <errno.h> // Error integer and strerror() function #include <errno.h> // Error integer and strerror() function
#include <fcntl.h> // Contains file controls like O_RDWR #include <fcntl.h> // Contains file controls like O_RDWR
#include <fsfw/tasks/TaskFactory.h>
#include <unistd.h> // write(), read(), close() #include <unistd.h> // write(), read(), close()
#include "OBSWConfig.h"
#include "fsfw/globalfunctions/CRC.h" #include "fsfw/globalfunctions/CRC.h"
#include "fsfw/globalfunctions/DleEncoder.h" #include "fsfw/globalfunctions/DleEncoder.h"
#include "fsfw/globalfunctions/arrayprinter.h" #include "fsfw/globalfunctions/arrayprinter.h"
@ -42,7 +37,7 @@ ReturnValue_t UartTestClass::performPeriodicAction() {
} }
void UartTestClass::gpsInit() { void UartTestClass::gpsInit() {
#if RPI_TEST_GPS_DEVICE == 1 #if RPI_TEST_GPS_HANDLER == 1
int result = lwgps_init(&gpsData); int result = lwgps_init(&gpsData);
if (result == 0) { if (result == 0) {
sif::warning << "lwgps_init error: " << result << std::endl; sif::warning << "lwgps_init error: " << result << std::endl;
@ -90,7 +85,7 @@ void UartTestClass::gpsInit() {
} }
void UartTestClass::gpsPeriodic() { void UartTestClass::gpsPeriodic() {
#if RPI_TEST_GPS_DEVICE == 1 #if RPI_TEST_GPS_HANDLER == 1
int bytesRead = 0; int bytesRead = 0;
do { do {
bytesRead = read(serialPort, reinterpret_cast<void*>(recBuf.data()), bytesRead = read(serialPort, reinterpret_cast<void*>(recBuf.data()),
@ -129,7 +124,7 @@ void UartTestClass::gpsPeriodic() {
void UartTestClass::scexInit() { void UartTestClass::scexInit() {
#if defined(RASPBERRY_PI) #if defined(RASPBERRY_PI)
std::string devname = "/dev/ttyUSB1"; std::string devname = "/dev/serial0";
#else #else
std::string devname = "/dev/ul-scex"; std::string devname = "/dev/ul-scex";
#endif #endif
@ -156,6 +151,13 @@ void UartTestClass::scexInit() {
tty.c_cc[VTIME] = 1; // In units of 0.1 seconds tty.c_cc[VTIME] = 1; // In units of 0.1 seconds
tty.c_cc[VMIN] = 255; // Read up to 255 bytes tty.c_cc[VMIN] = 255; // Read up to 255 bytes
// Q7S UART Lite has fixed baud rate. For other linux systems, set baud rate here.
#if !defined(XIPHOS_Q7S)
if (cfsetispeed(&tty, B57600) != 0) {
sif::warning << "UartTestClass::scexInit: Setting baud rate failed" << std::endl;
}
#endif
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) { if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
sif::warning << "tcsetattr call failed with error [" << errno << ", " << strerror(errno) sif::warning << "tcsetattr call failed with error [" << errno << ", " << strerror(errno)
<< std::endl; << std::endl;
@ -165,37 +167,12 @@ void UartTestClass::scexInit() {
} }
void UartTestClass::scexPeriodic() { void UartTestClass::scexPeriodic() {
auto dleEncoder = DleEncoder(); sif::info << "UartTestClass::scexInit: Sending ping command to SCEX" << std::endl;
std::array<uint8_t, 128> tmpCmdBuf = {}; int result = prepareScexPing();
// Send ping command if (result != 0) {
tmpCmdBuf[0] = scex::CMD_PING;
// These two fields are the packet counter and the total packet count. Those are 1 and 1 for each
// telecommand so far
tmpCmdBuf[1] = 1;
tmpCmdBuf[2] = 1;
uint16_t userDataLen = 0;
tmpCmdBuf[3] = (userDataLen >> 8) & 0xff;
tmpCmdBuf[4] = userDataLen & 0xff;
uint16_t crc = CRC::crc16ccitt(tmpCmdBuf.data(), 5);
tmpCmdBuf[5] = (crc >> 8) & 0xff;
tmpCmdBuf[6] = crc & 0xff;
size_t encodedLen = 0;
ReturnValue_t result =
dleEncoder.encode(tmpCmdBuf.data(), 7, cmdBuf.data(), cmdBuf.size(), &encodedLen, true);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "UartTestClass::scexInit: Encoding failed" << std::endl;
return; return;
} };
arrayprinter::print(cmdBuf.data(), 9);
size_t bytesWritten = write(serialPort, cmdBuf.data(), encodedLen); size_t bytesWritten = write(serialPort, cmdBuf.data(), encodedLen);
if (bytesWritten != encodedLen) {
sif::warning << "Sending ping command to solar experiment failed" << std::endl;
}
TaskFactory::delayTask(20);
bytesWritten = write(serialPort, cmdBuf.data(), encodedLen);
if (bytesWritten != encodedLen) { if (bytesWritten != encodedLen) {
sif::warning << "Sending ping command to solar experiment failed" << std::endl; sif::warning << "Sending ping command to solar experiment failed" << std::endl;
} }
@ -210,12 +187,35 @@ void UartTestClass::scexPeriodic() {
<< ", " << strerror(errno) << "]" << std::endl; << ", " << strerror(errno) << "]" << std::endl;
break; break;
} else if (bytesRead >= static_cast<int>(recBuf.size())) { } else if (bytesRead >= static_cast<int>(recBuf.size())) {
sif::debug << "UartTestClass::performPeriodicAction: " sif::debug << "UartTestClass::performPeriodicAction: recv buffer might not be large enough"
"recv buffer might not be large enough"
<< std::endl; << std::endl;
} else if (bytesRead > 0) { } else if (bytesRead > 0) {
sif::info << "Received " << bytesRead << " from the Solar Cell Experiment:" << std::endl; sif::info << "Received " << bytesRead
arrayprinter::print(recBuf.data(), bytesRead); << " bytes from the Solar Cell Experiment:" << std::endl;
arrayprinter::print(recBuf.data(), bytesRead, OutputType::HEX, false);
} }
} while (bytesRead > 0); } while (bytesRead > 0);
} }
int UartTestClass::prepareScexPing() {
std::array<uint8_t, 128> tmpCmdBuf = {};
// Send ping command
tmpCmdBuf[0] = scex::CMD_PING;
// These two fields are the packet counter and the total packet count. Those are 1 and 1 for each
// telecommand so far
tmpCmdBuf[1] = 1;
tmpCmdBuf[2] = 1;
uint16_t userDataLen = 0;
tmpCmdBuf[3] = (userDataLen >> 8) & 0xff;
tmpCmdBuf[4] = userDataLen & 0xff;
uint16_t crc = CRC::crc16ccitt(tmpCmdBuf.data(), 5);
tmpCmdBuf[5] = (crc >> 8) & 0xff;
tmpCmdBuf[6] = crc & 0xff;
ReturnValue_t result =
dleEncoder.encode(tmpCmdBuf.data(), 7, cmdBuf.data(), cmdBuf.size(), &encodedLen, true);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "UartTestClass::scexInit: Encoding failed" << std::endl;
return -1;
}
return 0;
}

View File

@ -1,6 +1,7 @@
#ifndef LINUX_BOARDTEST_UARTTESTCLASS_H_ #ifndef LINUX_BOARDTEST_UARTTESTCLASS_H_
#define LINUX_BOARDTEST_UARTTESTCLASS_H_ #define LINUX_BOARDTEST_UARTTESTCLASS_H_
#include <fsfw/globalfunctions/DleEncoder.h>
#include <termios.h> // Contains POSIX terminal control definitions #include <termios.h> // Contains POSIX terminal control definitions
#include <array> #include <array>
@ -28,7 +29,10 @@ class UartTestClass : public TestTask {
void scexInit(); void scexInit();
void scexPeriodic(); void scexPeriodic();
int prepareScexPing();
TestModes mode = TestModes::GPS; TestModes mode = TestModes::GPS;
DleEncoder dleEncoder = DleEncoder();
size_t encodedLen = 0;
lwgps_t gpsData = {}; lwgps_t gpsData = {};
struct termios tty = {}; struct termios tty = {};
int serialPort = 0; int serialPort = 0;