PDEC IRQ Handling #310

Merged
muellerr merged 26 commits from mueller/pdec_irq_handling into develop 2022-11-02 18:16:19 +01:00
5 changed files with 223 additions and 113 deletions
Showing only changes of commit 95d2bc0887 - Show all commits

View File

@ -21,7 +21,7 @@ static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio_pdec_regs";
static constexpr char UIO_PTME[] = "/dev/uio_ptme"; static constexpr char UIO_PTME[] = "/dev/uio_ptme";
static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio_pdec_cfg_mem"; static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio_pdec_cfg_mem";
static constexpr char UIO_PDEC_RAM[] = "/dev/uio_pdec_ram"; static constexpr char UIO_PDEC_RAM[] = "/dev/uio_pdec_ram";
static constexpr char UIO_PDEC_IRQ = "/dev/uio_pdec_irq"; static constexpr char UIO_PDEC_IRQ[] = "/dev/uio_pdec_irq";
static constexpr int MAP_ID_PTME_CONFIG = 3; static constexpr int MAP_ID_PTME_CONFIG = 3;
namespace uiomapids { namespace uiomapids {

View File

@ -773,8 +773,13 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
Levels::LOW); Levels::LOW);
gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio);
gpioChecker(gpioComIF->addGpios(gpioCookiePdec), "PDEC"); gpioChecker(gpioComIF->addGpios(gpioCookiePdec), "PDEC");
struct UioNames uioNames {};
uioNames.configMemory = q7s::UIO_PDEC_CONFIG_MEMORY;
uioNames.ramMemory = q7s::UIO_PDEC_RAM;
uioNames.registers = q7s::UIO_PDEC_REGISTERS;
uioNames.irq = q7s::UIO_PDEC_IRQ;
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET, new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET,
q7s::UIO_PDEC_CONFIG_MEMORY, q7s::UIO_PDEC_RAM, q7s::UIO_PDEC_REGISTERS); uioNames);
GpioCookie* gpioRS485Chip = new GpioCookie; GpioCookie* gpioRS485Chip = new GpioCookie;
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
Direction::OUT, Levels::LOW); Direction::OUT, Levels::LOW);

View File

@ -1,7 +1,9 @@
#include "PdecHandler.h" #include "PdecHandler.h"
#include <fcntl.h> #include <fcntl.h>
#include <poll.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <unistd.h>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
@ -12,18 +14,21 @@
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw/tmtcservices/TmTcMessage.h"
#include "fsfw_hal/linux/uio/UioMapper.h" #include "fsfw_hal/linux/uio/UioMapper.h"
#include "pdec.h"
using namespace pdec;
// If this is ever shared, protect it with a mutex!
uint32_t PdecHandler::CURRENT_FAR = 0;
PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId,
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory, LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names)
std::string uioRamMemory, std::string uioRegisters)
: SystemObject(objectId), : SystemObject(objectId),
tcDestinationId(tcDestinationId), tcDestinationId(tcDestinationId),
gpioComIF(gpioComIF), gpioComIF(gpioComIF),
pdecReset(pdecReset), pdecReset(pdecReset),
uioConfigMemory(uioConfigMemory), actionHelper(this, nullptr),
uioRamMemory(uioRamMemory), uioNames(names) {
uioRegisters(uioRegisters),
actionHelper(this, nullptr) {
auto mqArgs = MqArgs(objectId, static_cast<void*>(this)); auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
commandQueue = QueueFactory::instance()->createMessageQueue( commandQueue = QueueFactory::instance()->createMessageQueue(
QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
@ -47,22 +52,27 @@ ReturnValue_t PdecHandler::initialize() {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
UioMapper regMapper(uioRegisters); UioMapper regMapper(uioNames.registers);
result = regMapper.getMappedAdress(&registerBaseAddress, UioMapper::Permissions::READ_WRITE); result = regMapper.getMappedAdress(&registerBaseAddress, UioMapper::Permissions::READ_WRITE);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
UioMapper configMemMapper(uioConfigMemory); UioMapper configMemMapper(uioNames.configMemory);
result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE); result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
UioMapper ramMapper(uioRamMemory); UioMapper ramMapper(uioNames.ramMemory);
result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE); result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
if (OP_MODE == Modes::IRQ and uioNames.irq == nullptr) {
sif::error << "Can not use IRQ mode if IRQ UIO name is invalid" << std::endl;
return returnvalue::FAILED;
}
writePdecConfig(); writePdecConfig();
result = releasePdec(); result = releasePdec();
@ -110,7 +120,7 @@ ReturnValue_t PdecHandler::polledOperation() {
case State::WAIT_FOR_RECOVERY: case State::WAIT_FOR_RECOVERY:
break; break;
default: default:
sif::debug << "PdecHandler::performOperation: Invalid state" << std::endl; sif::error << "PdecHandler::performOperation: Invalid state" << std::endl;
break; break;
} }
@ -118,8 +128,76 @@ ReturnValue_t PdecHandler::polledOperation() {
} }
ReturnValue_t PdecHandler::irqOperation() { ReturnValue_t PdecHandler::irqOperation() {
ReturnValue_t result = returnvalue::OK;
int fd = open(uioNames.irq, O_RDWR);
if (fd < 0) {
sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed"
<< std::endl;
return returnvalue::FAILED;
}
struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0};
// Used to unmask IRQ
uint32_t info = 1;
ssize_t nb = 0;
int ret = 0;
while (true) { while (true) {
readCommandQueue(); readCommandQueue();
switch (state) {
case State::INIT:
resetFarStatFlag();
if (result != returnvalue::OK) {
// Requires reconfiguration and reinitialization of PDEC
triggerEvent(INVALID_FAR);
state = State::WAIT_FOR_RECOVERY;
return result;
}
state = State::RUNNING;
break;
case State::RUNNING: {
// TODO: Add poll() based IRQ handling
nb = write(fd, &info, sizeof(info));
if (nb != static_cast<ssize_t>(sizeof(info))) {
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
close(fd);
}
ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
if (ret == 0) {
// No TCs for timeout period
checkLocks();
} else if (ret >= 1) {
nb = read(fd, &info, sizeof(info));
if (nb == static_cast<ssize_t>(sizeof(info))) {
uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET);
if ((pisr & TC_NEW_MASK) == TC_NEW_MASK) {
// handle TC
handleNewTc();
}
if ((pisr & TC_ABORT_MASK) == TC_ABORT_MASK) {
tcAbortCounter += 1;
}
if ((pisr & NEW_FAR_MASK) == NEW_FAR_MASK) {
// Read FAR here
CURRENT_FAR = readFar();
}
// Clear interrupts with dummy read
ret = *(registerBaseAddress + PDEC_PIR_OFFSET);
}
} else {
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
<< strerror(errno) << std::endl;
triggerEvent(POLL_ERROR_PDEC, errno);
}
break;
}
case State::WAIT_FOR_RECOVERY:
break;
default:
sif::error << "PdecHandler::performOperation: Invalid state" << std::endl;
break;
}
} }
return returnvalue::OK; return returnvalue::OK;
} }
@ -151,7 +229,7 @@ void PdecHandler::writePdecConfig() {
if (OP_MODE == Modes::IRQ) { if (OP_MODE == Modes::IRQ) {
// Configure interrupt mask register to enable interrupts // Configure interrupt mask register to enable interrupts
*(memoryBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); *(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg();
} }
// Configure all MAP IDs as invalid // Configure all MAP IDs as invalid
@ -173,17 +251,19 @@ void PdecHandler::writePdecConfig() {
} }
ReturnValue_t PdecHandler::resetFarStatFlag() { ReturnValue_t PdecHandler::resetFarStatFlag() {
uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); uint32_t pdecFar = readFar();
if (pdecFar != FAR_RESET) { if (pdecFar != FAR_RESET) {
sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value." sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value."
<< " Read value: 0x" << std::hex << static_cast<unsigned int>(pdecFar) << " Read value: 0x" << std::hex << static_cast<unsigned int>(pdecFar)
<< std::endl; << std::endl;
CURRENT_FAR = pdecFar;
return returnvalue::FAILED; return returnvalue::FAILED;
} }
#if OBSW_DEBUG_PDEC_HANDLER == 1 #if OBSW_DEBUG_PDEC_HANDLER == 1
sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar
<< std::endl; << std::endl;
#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ #endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */
CURRENT_FAR = pdecFar;
return returnvalue::OK; return returnvalue::OK;
} }
@ -197,12 +277,14 @@ ReturnValue_t PdecHandler::releasePdec() {
} }
bool PdecHandler::newTcReceived() { bool PdecHandler::newTcReceived() {
uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); uint32_t pdecFar = readFar();
if (pdecFar >> STAT_POSITION != NEW_FAR_RECEIVED) { if (pdecFar >> STAT_POSITION != NEW_FAR_RECEIVED) {
CURRENT_FAR = pdecFar;
return false; return false;
} }
if (!checkFrameAna(pdecFar)) { if (!checkFrameAna(pdecFar)) {
CURRENT_FAR = pdecFar;
return false; return false;
} }
return true; return true;
@ -519,6 +601,8 @@ void PdecHandler::printPdecMon() {
sif::info << std::setw(30) << std::left << "Start sequence lock: " << lock << std::endl; sif::info << std::setw(30) << std::left << "Start sequence lock: " << lock << std::endl;
} }
uint32_t PdecHandler::readFar() { return *(registerBaseAddress + PDEC_FAR_OFFSET); }
std::string PdecHandler::getMonStatusString(uint32_t status) { std::string PdecHandler::getMonStatusString(uint32_t status) {
switch (status) { switch (status) {
case TC_CHANNEL_INACTIVE: case TC_CHANNEL_INACTIVE:

View File

@ -13,6 +13,13 @@
#include "fsfw_hal/common/gpio/gpioDefinitions.h" #include "fsfw_hal/common/gpio/gpioDefinitions.h"
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" #include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
struct UioNames {
const char* configMemory;
const char* ramMemory;
const char* registers;
const char* irq;
};
/** /**
* @brief This class controls the PDEC IP Core implemented in the programmable logic of the * @brief This class controls the PDEC IP Core implemented in the programmable logic of the
* Zynq-7020. All registers and memories of the PDEC IP Core are accessed via UIO * Zynq-7020. All registers and memories of the PDEC IP Core are accessed via UIO
@ -33,6 +40,8 @@
*/ */
class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF { class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF {
public: public:
static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500;
enum class Modes { POLLED, IRQ }; enum class Modes { POLLED, IRQ };
/** /**
@ -45,8 +54,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
* @param uioregsiters String of uio device file same mapped to the PDEC register space * @param uioregsiters String of uio device file same mapped to the PDEC register space
*/ */
PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF,
gpioId_t pdecReset, std::string uioConfigMemory, std::string uioRamMemory, gpioId_t pdecReset, UioNames names);
std::string uioRegisters);
virtual ~PdecHandler(); virtual ~PdecHandler();
@ -76,6 +84,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO); static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO);
//! [EXPORT] : [COMMENT] Lost bit lock //! [EXPORT] : [COMMENT] Lost bit lock
static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO); static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO);
static constexpr Event POLL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 7, severity::MEDIUM);
private: private:
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
@ -116,50 +125,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
// Print PDEC monitor register // Print PDEC monitor register
static const ActionId_t PRINT_PDEC_MON = 1; static const ActionId_t PRINT_PDEC_MON = 1;
static const uint8_t STAT_POSITION = 31;
static const uint8_t FRAME_ANA_POSITION = 28;
static const uint8_t IREASON_POSITION = 25;
static const uint8_t NEW_FAR_RECEIVED = 0;
static const uint32_t FRAME_ANA_MASK = 0x70000000;
static const uint32_t IREASON_MASK = 0x0E000000;
static const uint32_t TC_CHANNEL_INACTIVE = 0x0;
static const uint32_t TC_CHANNEL_ACTIVE = 0x1;
static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2;
static const uint32_t TC0_STATUS_MASK = 0x3;
static const uint32_t TC1_STATUS_MASK = 0xC;
static const uint32_t TC2_STATUS_MASK = 0x300;
static const uint32_t TC3_STATUS_MASK = 0xC00;
static const uint32_t TC4_STATUS_MASK = 0x30000;
static const uint32_t TC5_STATUS_MASK = 0xc00000;
// Lock register set to 1 when start sequence has been found (CLTU is beeing processed)
static const uint32_t LOCK_MASK = 0xc00000;
static const uint32_t TC0_STATUS_POS = 0;
static const uint32_t TC1_STATUS_POS = 2;
static const uint32_t TC2_STATUS_POS = 4;
static const uint32_t TC3_STATUS_POS = 6;
static const uint32_t TC4_STATUS_POS = 8;
static const uint32_t TC5_STATUS_POS = 10;
// Lock register set to 1 when start sequence has been found (CLTU is beeing processed)
static const uint32_t LOCK_POS = 12;
/**
* UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4
* Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10
*/
static constexpr uint32_t PDEC_PIR_OFFSET = 0xA03;
static constexpr uint32_t PDEC_IMR_OFFSET = 0xA04;
static const uint32_t PDEC_FAR_OFFSET = 0xA10;
static const uint32_t PDEC_CLCW_OFFSET = 0xA12;
static const uint32_t PDEC_BFREE_OFFSET = 0xA24;
static const uint32_t PDEC_BPTR_OFFSET = 0xA25;
static const uint32_t PDEC_SLEN_OFFSET = 0xA26;
static const uint32_t PDEC_MON_OFFSET = 0xA27;
#ifdef TE0720_1CFA #ifdef TE0720_1CFA
static const int CONFIG_MEMORY_MAP_SIZE = 0x400; static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
static const int RAM_MAP_SIZE = 0x4000; static const int RAM_MAP_SIZE = 0x4000;
@ -233,6 +198,53 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
enum class State : uint8_t { INIT, RUNNING, WAIT_FOR_RECOVERY }; enum class State : uint8_t { INIT, RUNNING, WAIT_FOR_RECOVERY };
static uint32_t CURRENT_FAR;
object_id_t tcDestinationId;
AcceptsTelecommandsIF* tcDestination = nullptr;
LinuxLibgpioIF* gpioComIF = nullptr;
/**
* Reset signal is required to hold PDEC in reset state until the configuration has been
* written to the appropriate memory space.
* Can also be used to reboot PDEC in case of erros.
*/
gpioId_t pdecReset = gpio::NO_GPIO;
uint32_t tcAbortCounter = 0;
ActionHelper actionHelper;
StorageManagerIF* tcStore = nullptr;
MessageQueueIF* commandQueue = nullptr;
State state = State::INIT;
/**
* Pointer pointing to base address of the PDEC memory space.
* This address is equivalent with the base address of the section named configuration area in
* the PDEC datasheet.
*/
uint32_t* memoryBaseAddress = nullptr;
uint32_t* ramBaseAddress = nullptr;
// Pointer pointing to base address of register space
uint32_t* registerBaseAddress = nullptr;
uint8_t tcSegment[TC_SEGMENT_LEN];
// Used to check carrier and bit lock changes (default set to no rf and no bitlock)
uint32_t lastClcw = 0xC000;
bool carrierLock = false;
bool bitLock = false;
UioNames uioNames;
/** /**
* @brief Reads and handles messages stored in the commandQueue * @brief Reads and handles messages stored in the commandQueue
*/ */
@ -241,6 +253,8 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
ReturnValue_t polledOperation(); ReturnValue_t polledOperation();
ReturnValue_t irqOperation(); ReturnValue_t irqOperation();
uint32_t readFar();
/** /**
* @brief This functions writes the configuration parameters to the configuration * @brief This functions writes the configuration parameters to the configuration
* section of the PDEC. * section of the PDEC.
@ -352,58 +366,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
void printPdecMon(); void printPdecMon();
std::string getMonStatusString(uint32_t status); std::string getMonStatusString(uint32_t status);
object_id_t tcDestinationId;
AcceptsTelecommandsIF* tcDestination = nullptr;
LinuxLibgpioIF* gpioComIF = nullptr;
/**
* Reset signal is required to hold PDEC in reset state until the configuration has been
* written to the appropriate memory space.
* Can also be used to reboot PDEC in case of erros.
*/
gpioId_t pdecReset = gpio::NO_GPIO;
// UIO device file giving access to the PDEC configuration memory section
std::string uioConfigMemory;
// UIO device file giving access to the PDEC RAM section
std::string uioRamMemory;
// UIO device file giving access to the PDEC register space
std::string uioRegisters;
ActionHelper actionHelper;
StorageManagerIF* tcStore = nullptr;
MessageQueueIF* commandQueue = nullptr;
State state = State::INIT;
/**
* Pointer pointing to base address of the PDEC memory space.
* This address is equivalent with the base address of the section named configuration area in
* the PDEC datasheet.
*/
uint32_t* memoryBaseAddress = nullptr;
uint32_t* ramBaseAddress = nullptr;
// Pointer pointing to base address of register space
uint32_t* registerBaseAddress = nullptr;
uint32_t pdecFar = 0;
uint8_t tcSegment[TC_SEGMENT_LEN];
// Used to check carrier and bit lock changes (default set to no rf and no bitlock)
uint32_t lastClcw = 0xC000;
bool carrierLock = false;
bool bitLock = false;
}; };
#endif /* LINUX_OBC_PDECHANDLER_H_ */ #endif /* LINUX_OBC_PDECHANDLER_H_ */

59
linux/obc/pdec.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef LINUX_OBC_PDEC_H_
#define LINUX_OBC_PDEC_H_
#include <cstdint>
namespace pdec {
static const uint8_t STAT_POSITION = 31;
static const uint8_t FRAME_ANA_POSITION = 28;
static const uint8_t IREASON_POSITION = 25;
static const uint8_t NEW_FAR_RECEIVED = 0;
static constexpr uint32_t NEW_FAR_MASK = 1 << 2;
static constexpr uint32_t TC_ABORT_MASK = 1 << 1;
static constexpr uint32_t TC_NEW_MASK = 1 << 0;
static const uint32_t FRAME_ANA_MASK = 0x70000000;
static const uint32_t IREASON_MASK = 0x0E000000;
static const uint32_t TC_CHANNEL_INACTIVE = 0x0;
static const uint32_t TC_CHANNEL_ACTIVE = 0x1;
static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2;
static const uint32_t TC0_STATUS_MASK = 0x3;
static const uint32_t TC1_STATUS_MASK = 0xC;
static const uint32_t TC2_STATUS_MASK = 0x300;
static const uint32_t TC3_STATUS_MASK = 0xC00;
static const uint32_t TC4_STATUS_MASK = 0x30000;
static const uint32_t TC5_STATUS_MASK = 0xc00000;
// Lock register set to 1 when start sequence has been found (CLTU is beeing processed)
static const uint32_t LOCK_MASK = 0xc00000;
static const uint32_t TC0_STATUS_POS = 0;
static const uint32_t TC1_STATUS_POS = 2;
static const uint32_t TC2_STATUS_POS = 4;
static const uint32_t TC3_STATUS_POS = 6;
static const uint32_t TC4_STATUS_POS = 8;
static const uint32_t TC5_STATUS_POS = 10;
// Lock register set to 1 when start sequence has been found (CLTU is beeing processed)
static const uint32_t LOCK_POS = 12;
/**
* UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4
* Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10
*/
static constexpr uint32_t PDEC_PISR_OFFSET = 0xA02;
static constexpr uint32_t PDEC_PIR_OFFSET = 0xA03;
static constexpr uint32_t PDEC_IMR_OFFSET = 0xA04;
static const uint32_t PDEC_FAR_OFFSET = 0xA10;
static const uint32_t PDEC_CLCW_OFFSET = 0xA12;
static const uint32_t PDEC_BFREE_OFFSET = 0xA24;
static const uint32_t PDEC_BPTR_OFFSET = 0xA25;
static const uint32_t PDEC_SLEN_OFFSET = 0xA26;
static const uint32_t PDEC_MON_OFFSET = 0xA27;
} // namespace pdec
#endif /* LINUX_OBC_PDEC_H_ */