diff --git a/bsp_linux_board/InitMission.cpp b/bsp_linux_board/InitMission.cpp index a94c2e7d..16dab475 100644 --- a/bsp_linux_board/InitMission.cpp +++ b/bsp_linux_board/InitMission.cpp @@ -163,6 +163,12 @@ void initmission::initTasks() { initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); } #endif /* RPI_ADD_GPIO_TEST == 1 */ +#if RPI_ADD_UART_TEST == 1 + result = testTask->addComponent(objects::UART_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("UART_TEST", objects::UART_TEST); + } +#endif /* RPI_ADD_GPIO_TEST == 1 */ sif::info << "Starting tasks.." << std::endl; tmTcDistributor->startTask(); diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 648d1376..adc50dd0 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -8,32 +8,32 @@ #include "tmtc/pusIds.h" #include "spiConf.h" -#include -#include +#include "linux/boardtest/LibgpiodTest.h" +#include "linux/boardtest/SpiTestClass.h" +#include "linux/boardtest/UartTestClass.h" -//#include -#include -#include -#include -#include -#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" -#include +#include "mission/core/GenericFactory.h" +#include "mission/utility/TmFunnel.h" +#include "mission/devices/MGMHandlerLIS3MDL.h" +#include "mission/devices/MGMHandlerRM3100.h" +#include "mission/devices/GyroADIS16507Handler.h" -#include -#include -#include -#include -#include +#include "fsfw/datapoollocal/LocalDataPoolManager.h" +#include "fsfw/tmtcservices/CommandingServiceBase.h" +#include "fsfw/tmtcservices/PusServiceBase.h" +#include "fsfw/tmtcpacket/pus/TmPacketStored.h" +#include "fsfw/tasks/TaskFactory.h" /* UDP server includes */ -#include -#include +#include "fsfw/osal/common/UdpTmTcBridge.h" +#include "fsfw/osal/common/UdpTcPollingTask.h" -#include -#include -#include -#include -#include +#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" +#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +#include "fsfw_hal/linux/rpi/GpioRPi.h" +#include "fsfw_hal/common/gpio/GpioCookie.h" +#include "fsfw_hal/linux/spi/SpiCookie.h" +#include "fsfw_hal/linux/spi/SpiComIF.h" void Factory::setStaticFrameworkObjectIds() { PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; @@ -61,10 +61,15 @@ void ObjectFactory::produce(void* args){ GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF); GpioCookie* gpioCookie = nullptr; + static_cast(gpioCookie); #if RPI_ADD_SPI_TEST == 1 new SpiTestClass(objects::SPI_TEST, gpioIF); #endif +#if RPI_ADD_UART_TEST == 1 + new UartTestClass(objects::UART_TEST); +#endif + #if RPI_LOOPBACK_TEST_GPIO == 1 GpioCookie* gpioCookieLoopback = new GpioCookie(); /* Loopback pins. Adapt according to setup */ @@ -83,6 +88,7 @@ void ObjectFactory::produce(void* args){ std::string spiDev; SpiCookie* spiCookie = nullptr; + static_cast(spiCookie); #if RPI_TEST_ACS_BOARD == 1 if(gpioCookie == nullptr) { diff --git a/bsp_linux_board/boardconfig/rpiConfig.h.in b/bsp_linux_board/boardconfig/rpiConfig.h.in index 31d6c157..0094903c 100644 --- a/bsp_linux_board/boardconfig/rpiConfig.h.in +++ b/bsp_linux_board/boardconfig/rpiConfig.h.in @@ -6,11 +6,18 @@ #define RPI_ADD_GPIO_TEST 0 #define RPI_LOOPBACK_TEST_GPIO 0 -#define RPI_TEST_ADIS16507 1 +#define RPI_TEST_ADIS16507 0 -/* Only one of those 2 should be enabled! */ +// Only one of those 2 should be enabled! #define RPI_ADD_SPI_TEST 0 +#if RPI_ADD_SPI_TEST == 0 #define RPI_TEST_ACS_BOARD 0 +#endif + +#define RPI_ADD_UART_TEST 1 +#if RPI_ADD_UART_TEST == 1 +#define RPI_TEST_GPS_DEVICE 0 +#endif /* Adapt these values accordingly */ namespace gpio { diff --git a/linux/boardtest/UartTestClass.cpp b/linux/boardtest/UartTestClass.cpp index dc9f79c3..9fcff9e9 100644 --- a/linux/boardtest/UartTestClass.cpp +++ b/linux/boardtest/UartTestClass.cpp @@ -1,8 +1,110 @@ -#include +#include "UartTestClass.h" +#include "rpiConfig.h" + +#include "fsfw/serviceinterface/ServiceInterface.h" + +#include "lwgps/lwgps.h" + +#include // Contains file controls like O_RDWR +#include // Error integer and strerror() function +#include // write(), read(), close() + +#define GPS_REPLY_WIRETAPPING 0 UartTestClass::UartTestClass(object_id_t objectId): TestTask(objectId) { } -ReturnValue_t UartTestClass::performPeriodicAction() { +ReturnValue_t UartTestClass::initialize() { +#if RPI_TEST_GPS_DEVICE == 1 + int result = lwgps_init(&gpsData); + if(result == 0) { + sif::warning << "lwgps_init error: " << result << std::endl; + } + + /* Get file descriptor */ + serialPort = open("/dev/serial0", O_RDWR); + if(serialPort < 0) { + sif::warning << "open call failed with error [" << errno << ", " << strerror(errno) + << std::endl; + } + /* Setting up UART parameters */ + tty.c_cflag &= ~PARENB; // Clear parity bit + tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication + tty.c_cflag &= ~CSIZE; // Clear all the size bits + tty.c_cflag |= CS8; // 8 bits per byte + tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control + tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1) + // Use canonical mode for GPS device + tty.c_lflag |= ICANON; + tty.c_lflag &= ~ECHO; // Disable echo + tty.c_lflag &= ~ECHOE; // Disable erasure + tty.c_lflag &= ~ECHONL; // Disable new-line echo + tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes + tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars) + tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed + + // Non-blocking mode + tty.c_cc[VTIME] = 0; + tty.c_cc[VMIN] = 0; + + cfsetispeed(&tty, B9600); + cfsetospeed(&tty, B9600); + if (tcsetattr(serialPort, TCSANOW, &tty) != 0) { + sif::warning << "tcsetattr call failed with error [" << errno << ", " << + strerror(errno) << std::endl;; + } + // Flush received and unread data. Those are old NMEA strings which are not relevant anymore + tcflush(serialPort, TCIFLUSH); +#endif + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t UartTestClass::performOneShotAction() { +#if RPI_TEST_GPS_DEVICE == 1 +#endif + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t UartTestClass::performPeriodicAction() { +#if RPI_TEST_GPS_DEVICE == 1 + int bytesRead = 0; + do { + bytesRead = read(serialPort, + reinterpret_cast(recBuf.data()), + static_cast(recBuf.size())); + if(bytesRead < 0) { + sif::warning << "UartTestClass::performPeriodicAction: read call failed with error [" << + errno << ", " << strerror(errno) << "]" << std::endl; + break; + } + else if(bytesRead >= static_cast(recBuf.size())) { + sif::debug << "UartTestClass::performPeriodicAction: " + "recv buffer might not be large enough" << std::endl; + } + else if(bytesRead > 0) { + // pass data to lwgps for processing +#if GPS_REPLY_WIRETAPPING == 1 + sif::info << recBuf.data() << std::endl; +#endif + int result = lwgps_process(&gpsData, recBuf.data(), bytesRead); + if(result == 0) { + sif::warning << "UartTestClass::performPeriodicAction: lwgps_process error" + << std::endl; + } + recvCnt++; + if(recvCnt == 6) { + recvCnt = 0; + sif::info << "GPS Data" << std::endl; + // Print messages + printf("Valid status: %d\n", gpsData.is_valid); + printf("Latitude: %f degrees\n", gpsData.latitude); + printf("Longitude: %f degrees\n", gpsData.longitude); + printf("Altitude: %f meters\n", gpsData.altitude); + } + } + } while(bytesRead > 0); +#endif return HasReturnvaluesIF::RETURN_OK; } diff --git a/linux/boardtest/UartTestClass.h b/linux/boardtest/UartTestClass.h index 406d2af5..aeb2c396 100644 --- a/linux/boardtest/UartTestClass.h +++ b/linux/boardtest/UartTestClass.h @@ -1,15 +1,27 @@ #ifndef LINUX_BOARDTEST_UARTTESTCLASS_H_ #define LINUX_BOARDTEST_UARTTESTCLASS_H_ -#include +#include "test/testtasks/TestTask.h" +#include "lwgps/lwgps.h" + +#include +#include // Contains POSIX terminal control definitions class UartTestClass: public TestTask { public: UartTestClass(object_id_t objectId); + ReturnValue_t initialize() override; + ReturnValue_t performOneShotAction() override; ReturnValue_t performPeriodicAction() override; private: + lwgps_t gpsData = {}; + struct termios tty = {}; + int serialPort = 0; + std::array recBuf; + uint8_t recvCnt = 0; + }; #endif /* LINUX_BOARDTEST_UARTTESTCLASS_H_ */ diff --git a/linux/fsfwconfig/objects/systemObjectList.h b/linux/fsfwconfig/objects/systemObjectList.h index 3f7fddc4..8558e335 100644 --- a/linux/fsfwconfig/objects/systemObjectList.h +++ b/linux/fsfwconfig/objects/systemObjectList.h @@ -60,6 +60,7 @@ namespace objects { TEST_TASK = 0x54694269, LIBGPIOD_TEST = 0x54123456, SPI_TEST = 0x54000010, + UART_TEST = 0x54000020, DUMMY_INTERFACE = 0x5400CAFE, DUMMY_HANDLER = 0x5400AFFE, P60DOCK_TEST_TASK = 0x00005060 diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 64ffb4e1..148cef2b 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -560,7 +560,7 @@ ReturnValue_t pst::pollingSequenceTest(FixedTimeslotTaskIF* thisSequence) { thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); #endif - + static_cast(length); if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) { return HasReturnvaluesIF::RETURN_OK; }