meier/ImtqHandler #44

Merged
muellerr merged 25 commits from meier/ImtqHandler into develop 2021-06-21 17:47:22 +02:00
11 changed files with 266 additions and 7 deletions
Showing only changes of commit 486ca36cbc - Show all commits

View File

@ -83,6 +83,15 @@ void initmission::initTasks() {
initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK);
}
#if TEST_CCSDS_BRIDGE == 1
PeriodicTaskIF* ptmeTestTask = factory->createPeriodicTask(
"PTME_TEST", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = ptmeTestTask->addComponent(objects::CCSDS_IP_CORE_BRIDGE);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PTME_TEST", objects::CCSDS_IP_CORE_BRIDGE);
}
#endif
/* PUS Services */
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
@ -210,5 +219,9 @@ void initmission::initTasks() {
#if OBSW_ADD_TEST_CODE == 1
testTask->startTask();
#endif
#if TEST_CCSDS_BRIDGE == 1
ptmeTestTask->startTask();
#endif
sif::info << "Tasks started.." << std::endl;
}

View File

@ -35,6 +35,7 @@
#include <mission/devices/devicedefinitions/Max31865Definitions.h>
#include <mission/devices/devicedefinitions/SusDefinitions.h>
#include <mission/utility/TmFunnel.h>
#include <mission/obc/CCSDSIPCoreBridge.h>
#include <linux/csp/CspCookie.h>
#include <linux/csp/CspComIF.h>
@ -577,9 +578,22 @@ void ObjectFactory::produce(){
SpiCookie* spiCookieSus = new SpiCookie(addresses::SUS_1, std::string("/dev/spidev1.0"),
SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED);
SusHandler* sus1 = new SusHandler(objects::SUS_1, objects::SPI_COM_IF, spiCookieSus, gpioComIF,
new SusHandler(objects::SUS_1, objects::SPI_COM_IF, spiCookieSus, gpioComIF,
gpioIds::CS_SUS_1);
sus1->setStartUpImmediately();
#endif
#if TE0720 == 1 && TEST_CCSDS_BRIDGE == 1
GpioCookie* gpioCookieCcsdsIp = new GpioCookie;
GpiodRegular* papbBusyN = new GpiodRegular(std::string("gpiochip0"), 0, std::string("PAPBBusy_N"));
gpioCookieCcsdsIp->addGpio(gpioIds::PAPB_BUSY_N, papbBusyN);
GpiodRegular* papbEmpty = new GpiodRegular(std::string("gpiochip0"), 1,
std::string("Chip Select Sus Sensor"));
gpioCookieCcsdsIp->addGpio(gpioIds::PAPB_EMPTY, papbEmpty);
gpioComIF->addGpios(gpioCookieCcsdsIp);
new CCSDSIPCoreBridge(objects::CCSDS_IP_CORE_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE, gpioComIF, std::string("/dev/uio0"),
gpioIds::PAPB_BUSY_N, gpioIds::PAPB_EMPTY);
#endif
#if TE0720 == 1 && TEST_RADIATION_SENSOR_HANDLER == 1

@ -1 +1 @@
Subproject commit a0f698fffa4dd5c9f86337c5d6170f9321cb8de7
Subproject commit 6341da22123166ac5fafdbc09e823d7464f769e5

View File

@ -20,11 +20,12 @@ debugging. */
#define OBSW_PRINT_MISSED_DEADLINES 1
#define OBSW_ADD_TEST_CODE 1
#define TEST_LIBGPIOD 0
#define TEST_RADIATION_SENSOR_HANDLER 1
#define TEST_RADIATION_SENSOR_HANDLER 0
#define TEST_SUS_HANDLER 1
#define TEST_PLOC_HANDLER 0
#define TEST_CCSDS_BRIDGE 1
#define TE0720 0
#define TE0720 1
#define TE0720_HEATER_TEST 0
#define P60DOCK_DEBUG 0

View File

@ -65,7 +65,10 @@ namespace gpioIds {
SPI_MUX_BIT_5,
SPI_MUX_BIT_6,
CS_RAD_SENSOR
CS_RAD_SENSOR,
PAPB_BUSY_N,
PAPB_EMPTY
};
}

View File

@ -16,6 +16,7 @@ namespace objects {
PUS_PACKET_DISTRIBUTOR = 0x50000200,
UDP_BRIDGE = 0x50000300,
UDP_POLLING_TASK = 0x50000400,
CCSDS_IP_CORE_BRIDGE = 0x50000500,
PUS_SERVICE_3 = 0x51000300,
PUS_SERVICE_5 = 0x51000400,

View File

@ -21,7 +21,8 @@ enum {
SYRLINKS_HANDLER,
IMTQ_HANDLER,
PLOC_HANDLER,
SUS_HANDLER
SUS_HANDLER,
CCSDS_IP_CORE_BRIDGE
};
}

View File

@ -1,3 +1,4 @@
add_subdirectory(core)
add_subdirectory(devices)
add_subdirectory(obc)
add_subdirectory(utility)

View File

@ -0,0 +1,104 @@
#include <sys/mman.h>
#include <fcntl.h>
#include <mission/obc/CCSDSIPCoreBridge.h>
CCSDSIPCoreBridge::CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination,
object_id_t tmStoreId, object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF,
std::string uioPtme, gpioId_t papbBusyId, gpioId_t papbEmptyId) :
TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId), gpioComIF(gpioComIF), uioPtme(
uioPtme), papbBusyId(papbBusyId), papbEmptyId(papbEmptyId) {
}
CCSDSIPCoreBridge::~CCSDSIPCoreBridge() {
}
ReturnValue_t CCSDSIPCoreBridge::initialize() {
ReturnValue_t result = TmTcBridge::initialize();
fd = open("/dev/uio0", O_RDWR);
if (fd < 1) {
sif::debug << "CCSDSIPCoreBridge::initialize: Invalid UIO device file" << std::endl;
return RETURN_FAILED;
}
/**
* Map uio device in virtual address space
* PROT_WRITE: Map uio device in writable only mode
*/
ptmeBaseAddress = static_cast<uint32_t*>(mmap(NULL, MAP_SIZE, PROT_WRITE, MAP_SHARED, fd, 0));
if (ptmeBaseAddress == MAP_FAILED) {
sif::error << "CCSDSIPCoreBridge::initialize: Failed to map uio address" << std::endl;
return RETURN_FAILED;
}
return result;
}
ReturnValue_t CCSDSIPCoreBridge::handleTm() {
/** Size of one complete transfer frame data field amounts to 1105 bytes */
uint8_t testPacket[1105];
/** Fill one test packet */
for(int idx = 0; idx < 1105; idx++) {
testPacket[idx] = static_cast<uint8_t>(idx & 0xFF);
}
ReturnValue_t result = sendTm(testPacket, 1105);
if(result != RETURN_OK) {
return result;
}
return RETURN_OK;
}
ReturnValue_t CCSDSIPCoreBridge::sendTm(const uint8_t * data, size_t dataLen) {
if(pollPapbSignal() == RETURN_OK) {
startPacketTransfer();
}
for(size_t idx = 0; idx < dataLen; idx++) {
if(pollPapbSignal() == RETURN_OK) {
*(ptmeBaseAddress + PTME_DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
}
else {
sif::debug << "CCSDSIPCoreBridge::sendTm: Only written " << idx - 1 << " of " << dataLen
<< " data" << std::endl;
return RETURN_FAILED;
}
}
if(pollPapbSignal() == RETURN_OK) {
endPacketTransfer();
}
return RETURN_OK;
}
void CCSDSIPCoreBridge::startPacketTransfer() {
*(ptmeBaseAddress) = PTME_CONFIG_START;
}
void CCSDSIPCoreBridge::endPacketTransfer() {
*(ptmeBaseAddress) = PTME_CONFIG_END;
}
ReturnValue_t CCSDSIPCoreBridge::pollPapbSignal() {
int papbBusyState = 0;
ReturnValue_t result = RETURN_OK;
/** Check if PAPB interface is ready to receive data */
result = gpioComIF->readGpio(papbBusyId, &papbBusyState);
if (result != RETURN_OK) {
sif::debug << "CCSDSIPCoreBridge::pollPapbSignal: Failed to read papb busy signal"
<< std::endl;
return RETURN_FAILED;
}
if (!papbBusyState) {
sif::debug << "CCSDSIPCoreBridge::pollPapbSignal: PAPB busy" << std::endl;
return PAPB_BUSY;
}
return RETURN_OK;
}

View File

@ -0,0 +1,116 @@
#ifndef MISSION_OBC_CCSDSIPCOREBRIDGE_H_

maybe it would be better to move this file into the linux folder because it depends on linux components

maybe it would be better to move this file into the linux folder because it depends on linux components
#define MISSION_OBC_CCSDSIPCOREBRIDGE_H_
#include <fsfw/tmtcservices/TmTcBridge.h>
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <string.h>
/**
* @brief This class handles the interfacing to the telemetry (PTME) and telecommand (PDEC) IP
* cores responsible for the CCSDS encoding and decoding. The IP cores are implemented
* on the programmable logic and are accessible through the linux UIO driver.
*/
class CCSDSIPCoreBridge: public TmTcBridge {
public:
/**
* @brief Constructor
*
* @param objectId
* @param tcDestination
* @param tmStoreId
* @param tcStoreId
* @param uioPtme Name of the uio device file which provides access to the PTME IP Core.
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
* PTME IP Core. A low logic level indicates the PTME is not ready to
* receive more data.
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
* PTME IP Core. The signal is high when there are no packets in the
* external buffer memory (BRAM).
*/
CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF, std::string uioPtme,
gpioId_t papbBusyId, gpioId_t papbEmptyId);
virtual ~CCSDSIPCoreBridge();
ReturnValue_t initialize() override;
protected:
/**
* Overwriting this function for testing purpose. Function is periodically called in
* performOperation.
*/
virtual ReturnValue_t handleTm() override;
virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;
private:
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
/** Size of mapped address space. 4k (minimal size of pl device) */
static const int MAP_SIZE = 0xFA0;
/**
* Configuration bits:
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
* bit[2]: Set this bit to 1 to abort a transfered packet
* bit[3]: Signals to PTME the start of a new telemetry packet
*/
static const uint32_t PTME_CONFIG_START = 0x8;
/**
* Writing this word to the ptme base address signals to the PTME that a complete tm packet has
* been transferred.
*/
static const uint32_t PTME_CONFIG_END = 0x0;
/**
* Writing to this offset within the PTME memory space will insert data for encoding to the
* PTME IP core.
*/
static const int PTME_DATA_REG_OFFSET = 0x400;
LinuxLibgpioIF* gpioComIF = nullptr;
/** The uio device file related to the PTME IP Core */
std::string uioPtme;
/** Pulled to low when PTME not ready to receive data */
gpioId_t papbBusyId = gpio::NO_GPIO;
/** High when externally buffer memory of PTME is empty */
gpioId_t papbEmptyId = gpio::NO_GPIO;
/** The file descriptor of the UIO driver */
int fd;
/** PTME base address */
uint32_t* ptmeBaseAddress = nullptr;
/**
* @brief This function sends the config byte to the PTME IP Core to initiate a packet
* transfer.
*/
void startPacketTransfer();
/**
* @brief This function sends the config byte to the PTME IP Core to signal the end of a
* packet transfer.
*/
void endPacketTransfer();
/**
* @brief This function reads the papb busy signal indicating whether the PAPB interface is
* ready to receive more data or not. PAPB is ready when PAPB_Busy_N == '1'.
*
* @return RETURN_OK when ready to receive data else PAPB_BUSY.
*/
ReturnValue_t pollPapbSignal();
};
#endif /* MISSION_OBC_CCSDSIPCOREBRIDGE_H_ */

View File

@ -0,0 +1,5 @@
target_sources(${TARGET_NAME} PUBLIC
CCSDSIPCoreBridge.cpp
)