added gpio sysfs if

This commit is contained in:
Robin Müller 2021-01-14 00:40:30 +01:00 committed by Robin Mueller
parent cca4d89114
commit 162c0ded02
9 changed files with 242 additions and 22 deletions

View File

@ -7,6 +7,11 @@ target_sources(${TARGET_NAME} PUBLIC
add_subdirectory(boardconfig) add_subdirectory(boardconfig)
add_subdirectory(boardtest) add_subdirectory(boardtest)
# wiringPi is deprecated unfortunately..
#target_link_libraries(${TARGET_NAME} PRIVATE
# wiringPi
#)

View File

@ -17,7 +17,7 @@
ServiceInterfaceStream sif::debug("DEBUG"); ServiceInterfaceStream sif::debug("DEBUG");
ServiceInterfaceStream sif::info("INFO"); ServiceInterfaceStream sif::info("INFO");
ServiceInterfaceStream sif::warning("WARNING"); ServiceInterfaceStream sif::warning("WARNING");
ServiceInterfaceStream sif::error("ERROR", false, false, true); ServiceInterfaceStream sif::error("ERROR");
ObjectManagerIF *objectManager = nullptr; ObjectManagerIF *objectManager = nullptr;
@ -131,6 +131,14 @@ void InitMission::initTasks(){
#endif #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 //Main thread sleep
sif::info << "Starting tasks.." << std::endl; sif::info << "Starting tasks.." << std::endl;
TmTcDistributor->startTask(); TmTcDistributor->startTask();
@ -143,6 +151,8 @@ void InitMission::initTasks(){
PusMedPrio->startTask(); PusMedPrio->startTask();
PusLowPrio->startTask(); PusLowPrio->startTask();
SpiTestTask->startTask();
#if OBSW_ADD_TEST_CODE == 1 #if OBSW_ADD_TEST_CODE == 1
TestTimeslotTask->startTask(); TestTimeslotTask->startTask();
#endif #endif

View File

@ -1,5 +1,6 @@
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
#include "ObjectFactory.h" #include "ObjectFactory.h"
#include <bsp_rpi/boardtest/SpiTest.h>
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
#include <objects/systemObjectList.h> #include <objects/systemObjectList.h>
#include <OBSWConfig.h> #include <OBSWConfig.h>
@ -42,4 +43,6 @@ void ObjectFactory::produce(){
objects::CCSDS_PACKET_DISTRIBUTOR, objects::CCSDS_PACKET_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE); objects::TM_STORE, objects::TC_STORE);
new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
new SpiTest(objects::SPI_TEST);
} }

View File

@ -1,5 +1,6 @@
target_sources(${TARGET_NAME} PRIVATE target_sources(${TARGET_NAME} PRIVATE
SpiTest.cpp SpiTest.cpp
RPiGPIO.cpp
) )

View File

@ -0,0 +1,123 @@
#include "RPiGPIO.h"
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdint>
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<int>(state)
<< "!" << std::endl;
return -1;
}
close(fd);
return 0;
}

View File

@ -0,0 +1,41 @@
#ifndef BSP_RPI_BOARDTEST_RPIGPIO_H_
#define BSP_RPI_BOARDTEST_RPIGPIO_H_
#include <cstdint>
/**
* @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_ */

View File

@ -1,13 +1,31 @@
#include "SpiTest.h" #include "SpiTest.h"
#include <fsfw/serviceinterface/ServiceInterfaceStream.h> #include <fsfw/serviceinterface/ServiceInterface.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <wiringPi.h>
SpiTest::SpiTest(object_id_t objectId): SystemObject(objectId) { 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); int spiFd = open(spiDeviceName.c_str(), O_RDWR);
if (spiFd < 0){ if (spiFd < 0){

View File

@ -6,13 +6,27 @@
#include <linux/spi/spidev.h> #include <linux/spi/spidev.h>
#include <string> #include <string>
class SpiTest: public ExecutableObjectIF, SystemObject { class SpiTest:
public SystemObject,
public ExecutableObjectIF {
public: public:
SpiTest(object_id_t objectId); SpiTest(object_id_t objectId);
ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
private: 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"; const std::string spiDeviceName = "/dev/spidev0.0";
int spiFd = 0; int spiFd = 0;

View File

@ -2,10 +2,15 @@
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ #define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
#include <cstdint> #include <cstdint>
#include <fsfw/objectmanager/frameworkObjects.h>
// The objects will be instantiated in the ID order // The objects will be instantiated in the ID order
namespace objects { namespace objects {
enum sourceObjects: uint32_t { 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 **/ /* First Byte 0x50-0x52 reserved for PUS Services **/
CCSDS_PACKET_DISTRIBUTOR = 0x50000100, CCSDS_PACKET_DISTRIBUTOR = 0x50000100,
PUS_PACKET_DISTRIBUTOR = 0x50000200, PUS_PACKET_DISTRIBUTOR = 0x50000200,
@ -21,13 +26,6 @@ namespace objects {
TM_FUNNEL = 0x52000002, TM_FUNNEL = 0x52000002,
/* Test Task */
TEST_TASK = 0x42694269,
DUMMY_INTERFACE = 0xCAFECAFE,
DUMMY_HANDLER = 0x4400AFFE,
P60DOCK_TEST_TASK = 0x00005060,
/* 0x49 ('I') for Communication Interfaces **/ /* 0x49 ('I') for Communication Interfaces **/
ARDUINO_COM_IF = 0x49000001, ARDUINO_COM_IF = 0x49000001,
CSP_COM_IF = 0x49000002, CSP_COM_IF = 0x49000002,
@ -36,7 +34,14 @@ namespace objects {
P60DOCK_HANDLER = 0x44000001, P60DOCK_HANDLER = 0x44000001,
PDU1_HANDLER = 0x44000002, PDU1_HANDLER = 0x44000002,
PDU2_HANDLER = 0x44000003, 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,
}; };
} }