From 0f6395b460f989722e05b86cfe067001e9e496c0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 14 Jan 2021 00:40:30 +0100 Subject: [PATCH] added gpio sysfs if --- bsp_rpi/CMakeLists.txt | 5 ++ bsp_rpi/InitMission.cpp | 26 ++++-- bsp_rpi/ObjectFactory.cpp | 5 +- bsp_rpi/boardtest/CMakeLists.txt | 1 + bsp_rpi/boardtest/RPiGPIO.cpp | 123 ++++++++++++++++++++++++++ bsp_rpi/boardtest/RPiGPIO.h | 41 +++++++++ bsp_rpi/boardtest/SpiTest.cpp | 26 +++++- bsp_rpi/boardtest/SpiTest.h | 16 +++- fsfwconfig/objects/systemObjectList.h | 21 +++-- 9 files changed, 242 insertions(+), 22 deletions(-) create mode 100644 bsp_rpi/boardtest/RPiGPIO.cpp create mode 100644 bsp_rpi/boardtest/RPiGPIO.h diff --git a/bsp_rpi/CMakeLists.txt b/bsp_rpi/CMakeLists.txt index 7885ca28..281994bf 100644 --- a/bsp_rpi/CMakeLists.txt +++ b/bsp_rpi/CMakeLists.txt @@ -7,6 +7,11 @@ target_sources(${TARGET_NAME} PUBLIC add_subdirectory(boardconfig) add_subdirectory(boardtest) +# wiringPi is deprecated unfortunately.. +#target_link_libraries(${TARGET_NAME} PRIVATE +# wiringPi +#) + diff --git a/bsp_rpi/InitMission.cpp b/bsp_rpi/InitMission.cpp index 8dcb42d7..197abcc6 100644 --- a/bsp_rpi/InitMission.cpp +++ b/bsp_rpi/InitMission.cpp @@ -17,7 +17,7 @@ ServiceInterfaceStream sif::debug("DEBUG"); ServiceInterfaceStream sif::info("INFO"); ServiceInterfaceStream sif::warning("WARNING"); -ServiceInterfaceStream sif::error("ERROR", false, false, true); +ServiceInterfaceStream sif::error("ERROR"); ObjectManagerIF *objectManager = nullptr; @@ -39,11 +39,11 @@ void InitMission::initTasks(){ 0.100, nullptr); ReturnValue_t result = TmTcDistributor->addComponent( objects::CCSDS_PACKET_DISTRIBUTOR); - if(result!=HasReturnvaluesIF::RETURN_OK){ + if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } result = TmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); - if(result!=HasReturnvaluesIF::RETURN_OK){ + if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } result = TmTcDistributor->addComponent(objects::TM_FUNNEL); @@ -89,11 +89,11 @@ void InitMission::initTasks(){ PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); result = PusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result!=HasReturnvaluesIF::RETURN_OK){ + if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } result = PusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ + if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } @@ -102,11 +102,11 @@ void InitMission::initTasks(){ PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); result = PusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ + if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } result = PusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ + if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } @@ -114,7 +114,7 @@ void InitMission::initTasks(){ createPeriodicTask("PUSB", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, nullptr); result = PusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result!=HasReturnvaluesIF::RETURN_OK){ + if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } @@ -131,6 +131,14 @@ void InitMission::initTasks(){ #endif + PeriodicTaskIF* SpiTestTask = TaskFactory::instance()-> + createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 2.0, nullptr); + result = SpiTestTask->addComponent(objects::SPI_TEST); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Object add SPI test failed" << std::endl; + } + //Main thread sleep sif::info << "Starting tasks.." << std::endl; TmTcDistributor->startTask(); @@ -143,6 +151,8 @@ void InitMission::initTasks(){ PusMedPrio->startTask(); PusLowPrio->startTask(); + SpiTestTask->startTask(); + #if OBSW_ADD_TEST_CODE == 1 TestTimeslotTask->startTask(); #endif diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 4300fbeb..c90db492 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -1,5 +1,6 @@ -#include #include "ObjectFactory.h" +#include +#include #include #include @@ -42,4 +43,6 @@ void ObjectFactory::produce(){ objects::CCSDS_PACKET_DISTRIBUTOR, objects::TM_STORE, objects::TC_STORE); new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); + + new SpiTest(objects::SPI_TEST); } diff --git a/bsp_rpi/boardtest/CMakeLists.txt b/bsp_rpi/boardtest/CMakeLists.txt index 768fc52f..1e373efb 100644 --- a/bsp_rpi/boardtest/CMakeLists.txt +++ b/bsp_rpi/boardtest/CMakeLists.txt @@ -1,5 +1,6 @@ target_sources(${TARGET_NAME} PRIVATE SpiTest.cpp + RPiGPIO.cpp ) diff --git a/bsp_rpi/boardtest/RPiGPIO.cpp b/bsp_rpi/boardtest/RPiGPIO.cpp new file mode 100644 index 00000000..7ffb024c --- /dev/null +++ b/bsp_rpi/boardtest/RPiGPIO.cpp @@ -0,0 +1,123 @@ +#include "RPiGPIO.h" + +#include +#include +#include +#include +#include + + +int RPiGPIO::enablePin(int pin) { + char buffer[BUFFER_MAX]; + ssize_t bytes_written; + int fd; + + fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd == -1) { + sif::error << "Failed to open export of pin " << pin << " for writing!" << std::endl; + return -1; + } + + bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin); + write(fd, buffer, bytes_written); + close(fd); + return 0; +} + +int RPiGPIO::disablePin(int pin) { + char buffer[BUFFER_MAX]; + ssize_t bytes_written; + int fd; + + fd = open("/sys/class/gpio/unexport", O_WRONLY); + if (fd == -1) { + sif::error << "Failed to open unexport of pin " << pin << " for writing!" << std::endl; + return -1; + } + + bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin); + write(fd, buffer, bytes_written); + close(fd); + return(0); +} + +int RPiGPIO::pinDirection(int pin, Directions dir) { + + char path[DIRECTION_MAX]; + + snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin); + int fd = open(path, O_WRONLY); + if (fd == -1) { + sif::error << "Failed to open gpio " << pin << " direction for writing!" << std::endl; + return -1; + } + + int result = 0; + if(dir == Directions::IN) { + result = write(fd, "in", IN_WRITE_SIZE); + } + else { + result = write(fd, "out", OUT_WRITE_SIZE); + } + + if (result != 0) { + sif::error << "Failed to set direction!" << std::endl; + return -2; + } + + close(fd); + return 0; +} + +int RPiGPIO::readPin(int pin) { + char path[VALUE_MAX]; + char value_str[3]; + + snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin); + int fd = open(path, O_RDONLY); + if (fd == -1) { + sif::error << "RPiGPIO::readPin: Failed to open GPIO pin " << pin << "!" << std::endl; + return -1; + } + + if (read(fd, value_str, 3) == -1) { + sif::error << "Failed to read value!" << std::endl; + return -1; + } + + close(fd); + char* endPtr = nullptr; + + return strtol(value_str, &endPtr, 10); +} + +int RPiGPIO::writePin(int pin, States state) { + + char path[VALUE_MAX]; + int fd; + + snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin); + fd = open(path, O_WRONLY); + if (fd == -1) { + sif::error << "RPiGPIO::writePin: Failed to open GPIO pin " << pin << "!" << std::endl; + return -1; + } + + int result = 0; + if(state == States::LOW) { + result = write(fd, "0", 1); + } + else { + result = write(fd, "1", 1); + } + + + if (result != 0) { + sif::error << "Failed to write pin " << pin << " value to " << static_cast(state) + << "!" << std::endl; + return -1; + } + + close(fd); + return 0; +} diff --git a/bsp_rpi/boardtest/RPiGPIO.h b/bsp_rpi/boardtest/RPiGPIO.h new file mode 100644 index 00000000..400a37d8 --- /dev/null +++ b/bsp_rpi/boardtest/RPiGPIO.h @@ -0,0 +1,41 @@ +#ifndef BSP_RPI_BOARDTEST_RPIGPIO_H_ +#define BSP_RPI_BOARDTEST_RPIGPIO_H_ + +#include + +/** + * @brief Really simple C++ GPIO wrapper for the Raspberry Pi, using the sysfs interface. + * Use BCM pins notation (https://pinout.xyz/#) + * + */ +class RPiGPIO { +public: + enum Directions { + IN = 0, + OUT = 1 + }; + + enum States { + LOW = 0, + HIGH = 1 + }; + + static int enablePin(int pin); + static int disablePin(int pin); + static int pinDirection(int pin, Directions dir); + static int readPin(int pin); + static int writePin(int pin, States state); + +private: + + + static constexpr uint8_t BUFFER_MAX = 3; + static constexpr uint8_t DIRECTION_MAX = 35; + static constexpr uint8_t VALUE_MAX = 30; + + static constexpr uint8_t IN_WRITE_SIZE = 3; + static constexpr uint8_t OUT_WRITE_SIZE = 4; +}; + + +#endif /* BSP_RPI_BOARDTEST_RPIGPIO_H_ */ diff --git a/bsp_rpi/boardtest/SpiTest.cpp b/bsp_rpi/boardtest/SpiTest.cpp index 91939714..a78d0171 100644 --- a/bsp_rpi/boardtest/SpiTest.cpp +++ b/bsp_rpi/boardtest/SpiTest.cpp @@ -1,13 +1,31 @@ #include "SpiTest.h" -#include +#include #include #include -#include + + SpiTest::SpiTest(object_id_t objectId): SystemObject(objectId) { - wiringPiSetupGpio(); + sif::info << "Setting up Raspberry Pi WiringPi library." << std::endl; +// wiringPiSetupGpio(); + +// pinMode(SS_MGM_0_LIS3, OUTPUT); +// pinMode(SS_MGM_1_RM, OUTPUT); +// pinMode(SS_GYRO_0_ADIS, OUTPUT); +// pinMode(SS_GYRO_1_L3G, OUTPUT); +// pinMode(SS_GYRO_2_L3G, OUTPUT); +// pinMode(SS_MGM_2_LIS3, OUTPUT); +// pinMode(SS_MGM_3_RM, OUTPUT); +// +// digitalWrite(SS_MGM_0_LIS3, HIGH); +// digitalWrite(SS_MGM_1_RM, HIGH); +// digitalWrite(SS_GYRO_0_ADIS, HIGH); +// digitalWrite(SS_GYRO_1_L3G, HIGH); +// digitalWrite(SS_GYRO_2_L3G, HIGH); +// digitalWrite(SS_MGM_2_LIS3, HIGH); +// digitalWrite(SS_MGM_3_RM, HIGH); int spiFd = open(spiDeviceName.c_str(), O_RDWR); if (spiFd < 0){ @@ -40,4 +58,4 @@ ReturnValue_t SpiTest::initialize() { //transferHandle.speed_hz = 976000; //transferHandle.len = 2; return HasReturnvaluesIF::RETURN_OK; -} \ No newline at end of file +} diff --git a/bsp_rpi/boardtest/SpiTest.h b/bsp_rpi/boardtest/SpiTest.h index 9bdb8f25..b4f37fe2 100644 --- a/bsp_rpi/boardtest/SpiTest.h +++ b/bsp_rpi/boardtest/SpiTest.h @@ -6,13 +6,27 @@ #include #include -class SpiTest: public ExecutableObjectIF, SystemObject { +class SpiTest: + public SystemObject, + public ExecutableObjectIF { public: SpiTest(object_id_t objectId); ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t initialize() override; private: + // These chip selects (BCM number) will be pulled high if not used + // ACS board specific. + enum SpiChipSelects { + SS_MGM_0_LIS3 = 0, //!< MGM 0, LIS3MDLTR, U6, A side + SS_MGM_1_RM = 1, //!< MGM 1, RM3100, U7, A side + SS_GYRO_0_ADIS = 2, //!< Gyro 0, ADIS16485, U3, A side + SS_GYRO_1_L3G = 3, //!< Gyro 1, L3GD20H, U4, A side + SS_GYRO_2_L3G = 4, //!< Gyro 2, L3GD20h, U5, B side + SS_MGM_2_LIS3 = 17, //!< MGM 2, LIS3MDLTR, U8, B side + SS_MGM_3_RM = 27, //!< MGM 3, RM3100, U9, B side + }; + const std::string spiDeviceName = "/dev/spidev0.0"; int spiFd = 0; diff --git a/fsfwconfig/objects/systemObjectList.h b/fsfwconfig/objects/systemObjectList.h index a5863380..d2fb5490 100644 --- a/fsfwconfig/objects/systemObjectList.h +++ b/fsfwconfig/objects/systemObjectList.h @@ -2,10 +2,15 @@ #define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ #include +#include // The objects will be instantiated in the ID order namespace objects { enum sourceObjects: uint32_t { + /* 0x53 reserved for FSFW */ + FW_ADDRESS_START = PUS_SERVICE_1_VERIFICATION, + FW_ADDRESS_END = TIME_STAMPER, + /* First Byte 0x50-0x52 reserved for PUS Services **/ CCSDS_PACKET_DISTRIBUTOR = 0x50000100, PUS_PACKET_DISTRIBUTOR = 0x50000200, @@ -21,13 +26,6 @@ namespace objects { TM_FUNNEL = 0x52000002, - /* Test Task */ - - TEST_TASK = 0x42694269, - DUMMY_INTERFACE = 0xCAFECAFE, - DUMMY_HANDLER = 0x4400AFFE, - P60DOCK_TEST_TASK = 0x00005060, - /* 0x49 ('I') for Communication Interfaces **/ ARDUINO_COM_IF = 0x49000001, CSP_COM_IF = 0x49000002, @@ -36,7 +34,14 @@ namespace objects { P60DOCK_HANDLER = 0x44000001, PDU1_HANDLER = 0x44000002, PDU2_HANDLER = 0x44000003, - ACU_HANDLER = 0x44000004 + ACU_HANDLER = 0x44000004, + + /* 0x54 ('T') for test handlers */ + TEST_TASK = 0x54694269, + SPI_TEST = 0x54000010, + DUMMY_INTERFACE = 0x5400CAFE, + DUMMY_HANDLER = 0x5400AFFE, + P60DOCK_TEST_TASK = 0x00005060, }; }