meier/ptme #129
13
README.md
13
README.md
@ -20,6 +20,7 @@
|
|||||||
13. [Eclipse](#eclipse)
|
13. [Eclipse](#eclipse)
|
||||||
14. [Running the OBSW on a Raspberry Pi](#rpi)
|
14. [Running the OBSW on a Raspberry Pi](#rpi)
|
||||||
15. [FSFW](#fsfw)
|
15. [FSFW](#fsfw)
|
||||||
|
16. [Coding Style](#coding-style)
|
||||||
|
|
||||||
# <a id="general"></a> General information
|
# <a id="general"></a> General information
|
||||||
|
|
||||||
@ -1151,3 +1152,15 @@ git merge upstream/master
|
|||||||
|
|
||||||
Alternatively, changes from other upstreams (forks) and branches can be merged like that
|
Alternatively, changes from other upstreams (forks) and branches can be merged like that
|
||||||
in the same way.
|
in the same way.
|
||||||
|
|
||||||
|
# <a id="coding-style"></a> Coding Style
|
||||||
|
* the formatting is based on the clang-format tools
|
||||||
|
## Setting up eclipse auto-fromatter with clang-format
|
||||||
|
1. Help → Install New Software → Add
|
||||||
|
2. In location insert the link http://www.cppstyle.com/luna
|
||||||
|
3. The software package CppStyle should now be available for installation
|
||||||
|
4. On windows download the clang-formatting tools from https://llvm.org/builds/. On linux clang-format can be installed with the package manager.
|
||||||
|
5. Navigate to Preferences → C/C++ → CppStyle
|
||||||
|
6. Insert the path to the clang-format executable
|
||||||
|
7. Under C/C++ → Code Style → Formatter, change the formatter to CppStyle (clang-format)
|
||||||
|
8. Code can now be formatted with the clang tool by using the key combination Ctrl + Shift + f
|
@ -17,6 +17,16 @@ static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ttyUL7";
|
|||||||
static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio0";
|
static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio0";
|
||||||
static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio2";
|
static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio2";
|
||||||
static constexpr char UIO_PDEC_RAM[] = "/dev/uio3";
|
static constexpr char UIO_PDEC_RAM[] = "/dev/uio3";
|
||||||
|
static constexpr char UIO_PTME[] = "/dev/uio1";
|
||||||
|
static constexpr int MAP_ID_PTME_CONFIG = 3;
|
||||||
|
|
||||||
|
namespace uiomapids {
|
||||||
|
static const int PTME_VC0 = 0;
|
||||||
|
static const int PTME_VC1 = 1;
|
||||||
|
static const int PTME_VC2 = 2;
|
||||||
|
static const int PTME_VC3 = 3;
|
||||||
|
static const int PTME_CONFIG = 4;
|
||||||
|
}
|
||||||
|
|
||||||
namespace gpioNames {
|
namespace gpioNames {
|
||||||
static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select";
|
static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select";
|
||||||
@ -69,7 +79,6 @@ static constexpr char RS485_EN_TX_DATA[] = "tx_data_enable_ltc2872";
|
|||||||
static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872";
|
static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872";
|
||||||
static constexpr char RS485_EN_RX_DATA[] = "rx_data_enable_ltc2872";
|
static constexpr char RS485_EN_RX_DATA[] = "rx_data_enable_ltc2872";
|
||||||
static constexpr char PDEC_RESET[] = "pdec_reset";
|
static constexpr char PDEC_RESET[] = "pdec_reset";
|
||||||
static constexpr char BIT_RATE_SEL[] = "bit_rate_sel";
|
|
||||||
} // namespace gpioNames
|
} // namespace gpioNames
|
||||||
} // namespace q7s
|
} // namespace q7s
|
||||||
|
|
||||||
|
@ -115,12 +115,14 @@ void initmission::initTasks() {
|
|||||||
}
|
}
|
||||||
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
|
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
|
||||||
|
|
||||||
|
#if OBSW_ADD_ACS_HANDLERS == 1
|
||||||
PeriodicTaskIF* acsCtrl = factory->createPeriodicTask(
|
PeriodicTaskIF* acsCtrl = factory->createPeriodicTask(
|
||||||
"ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
"ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
||||||
result = acsCtrl->addComponent(objects::GPS_CONTROLLER);
|
result = acsCtrl->addComponent(objects::GPS_CONTROLLER);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER);
|
initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER);
|
||||||
}
|
}
|
||||||
|
#endif /* OBSW_ADD_ACS_HANDLERS */
|
||||||
|
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
// FS task, task interval does not matter because it runs in permanent loop, priority low
|
// FS task, task interval does not matter because it runs in permanent loop, priority low
|
||||||
|
@ -81,6 +81,7 @@
|
|||||||
#include <linux/obc/PtmeConfig.h>
|
#include <linux/obc/PtmeConfig.h>
|
||||||
#include <linux/obc/PtmeRateSetter.h>
|
#include <linux/obc/PtmeRateSetter.h>
|
||||||
#include <linux/obc/TxRateSetterIF.h>
|
#include <linux/obc/TxRateSetterIF.h>
|
||||||
|
#include <linux/obc/PtmeAxiConfig.h>
|
||||||
|
|
||||||
ResetArgs resetArgsGnss0;
|
ResetArgs resetArgsGnss0;
|
||||||
ResetArgs resetArgsGnss1;
|
ResetArgs resetArgsGnss1;
|
||||||
@ -892,49 +893,50 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
|
|||||||
GpioCookie* gpioCookiePtmeIp = new GpioCookie;
|
GpioCookie* gpioCookiePtmeIp = new GpioCookie;
|
||||||
GpiodRegularByLineName* gpio = nullptr;
|
GpiodRegularByLineName* gpio = nullptr;
|
||||||
std::stringstream consumer;
|
std::stringstream consumer;
|
||||||
consumer << "0x" << std::hex << objects::PAPB_VC0;
|
consumer.str("PAPB VC0");
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, consumer.str());
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, consumer.str());
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio);
|
||||||
consumer.str("");
|
consumer.str("PAPB VC0");
|
||||||
consumer << "0x" << std::hex << objects::PAPB_VC0;
|
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, consumer.str());
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, consumer.str());
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio);
|
||||||
consumer.str("");
|
consumer.str("PAPB VC 1");
|
||||||
consumer << "0x" << std::hex << objects::PAPB_VC1;
|
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, consumer.str());
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, consumer.str());
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio);
|
||||||
consumer.str("");
|
consumer.str("");
|
||||||
consumer << "0x" << std::hex << objects::PAPB_VC1;
|
consumer.str("PAPB VC 1");
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC1, consumer.str());
|
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio);
|
||||||
consumer.str("");
|
consumer.str("");
|
||||||
consumer << "0x" << std::hex << objects::PAPB_VC2;
|
consumer.str("PAPB VC 2");
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, consumer.str());
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, consumer.str());
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio);
|
||||||
consumer.str("");
|
consumer.str("");
|
||||||
consumer << "0x" << std::hex << objects::PAPB_VC2;
|
consumer.str("PAPB VC 2");
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, consumer.str());
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, consumer.str());
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio);
|
||||||
consumer.str("");
|
consumer.str("");
|
||||||
consumer << "0x" << std::hex << objects::PAPB_VC3;
|
consumer.str("PAPB VC 3");
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, consumer.str());
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, consumer.str());
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio);
|
||||||
consumer.str("");
|
consumer.str("");
|
||||||
consumer << "0x" << std::hex << objects::PAPB_VC3;
|
consumer.str("PAPB VC 3");
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, consumer.str());
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, consumer.str());
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio);
|
||||||
|
|
||||||
gpioComIF->addGpios(gpioCookiePtmeIp);
|
gpioComIF->addGpios(gpioCookiePtmeIp);
|
||||||
|
|
||||||
// Creating virtual channel interfaces
|
// Creating virtual channel interfaces
|
||||||
VcInterfaceIF* vc0 = new PapbVcInterface(objects::PAPB_VC0, gpioComIF, gpioIds::VC0_PAPB_BUSY,
|
VcInterfaceIF* vc0 =
|
||||||
gpioIds::VC0_PAPB_EMPTY, PtmeConfig::VC0_OFFSETT);
|
new PapbVcInterface(gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY, q7s::UIO_PTME,
|
||||||
VcInterfaceIF* vc1 = new PapbVcInterface(objects::PAPB_VC1, gpioComIF, gpioIds::VC1_PAPB_BUSY,
|
q7s::uiomapids::PTME_VC0);
|
||||||
gpioIds::VC1_PAPB_EMPTY, PtmeConfig::VC1_OFFSETT);
|
VcInterfaceIF* vc1 =
|
||||||
VcInterfaceIF* vc2 = new PapbVcInterface(objects::PAPB_VC2, gpioComIF, gpioIds::VC2_PAPB_BUSY,
|
new PapbVcInterface(gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY, q7s::UIO_PTME,
|
||||||
gpioIds::VC2_PAPB_EMPTY, PtmeConfig::VC2_OFFSETT);
|
q7s::uiomapids::PTME_VC1);
|
||||||
VcInterfaceIF* vc3 = new PapbVcInterface(objects::PAPB_VC3, gpioComIF, gpioIds::VC3_PAPB_BUSY,
|
VcInterfaceIF* vc2 =
|
||||||
gpioIds::VC3_PAPB_EMPTY, PtmeConfig::VC3_OFFSETT);
|
new PapbVcInterface(gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY, q7s::UIO_PTME,
|
||||||
|
q7s::uiomapids::PTME_VC2);
|
||||||
|
VcInterfaceIF* vc3 =
|
||||||
|
new PapbVcInterface(gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY, q7s::UIO_PTME,
|
||||||
|
q7s::uiomapids::PTME_VC3);
|
||||||
|
|
||||||
// Creating ptme object and adding virtual channel interfaces
|
// Creating ptme object and adding virtual channel interfaces
|
||||||
Ptme* ptme = new Ptme(objects::PTME);
|
Ptme* ptme = new Ptme(objects::PTME);
|
||||||
@ -943,17 +945,9 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
|
|||||||
ptme->addVcInterface(ccsds::VC2, vc2);
|
ptme->addVcInterface(ccsds::VC2, vc2);
|
||||||
ptme->addVcInterface(ccsds::VC3, vc3);
|
ptme->addVcInterface(ccsds::VC3, vc3);
|
||||||
|
|
||||||
GpioCookie* gpioCookieRateSetter = new GpioCookie;
|
PtmeAxiConfig* ptmeAxiConfig =
|
||||||
consumer.str("");
|
new PtmeAxiConfig(objects::PTME_AXI_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG);
|
||||||
consumer << "ptme rate setter";
|
TxRateSetterIF* txRateSetterIF = new PtmeRateSetter(objects::TX_RATE_SETTER, ptmeAxiConfig);
|
||||||
// Init to low -> default bit rate is low bit rate (200 kbps in downlink with syrlinks)
|
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::BIT_RATE_SEL, consumer.str(), gpio::DIR_OUT,
|
|
||||||
gpio::LOW);
|
|
||||||
gpioCookieRateSetter->addGpio(gpioIds::BIT_RATE_SEL, gpio);
|
|
||||||
gpioComIF->addGpios(gpioCookieRateSetter);
|
|
||||||
|
|
||||||
TxRateSetterIF* txRateSetterIF = new PtmeRateSetter(gpioIds::BIT_RATE_SEL, gpioComIF);
|
|
||||||
|
|
||||||
CCSDSHandler* ccsdsHandler = new CCSDSHandler(
|
CCSDSHandler* ccsdsHandler = new CCSDSHandler(
|
||||||
objects::CCSDS_HANDLER, objects::PTME, objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF,
|
objects::CCSDS_HANDLER, objects::PTME, objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF,
|
||||||
gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
||||||
@ -979,8 +973,7 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
|
|||||||
gpioComIF->addGpios(gpioCookiePdec);
|
gpioComIF->addGpios(gpioCookiePdec);
|
||||||
|
|
||||||
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET,
|
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET,
|
||||||
std::string(q7s::UIO_PDEC_CONFIG_MEMORY), std::string(q7s::UIO_PDEC_RAM),
|
q7s::UIO_PDEC_CONFIG_MEMORY, q7s::UIO_PDEC_RAM, q7s::UIO_PDEC_REGISTERS);
|
||||||
std::string(q7s::UIO_PDEC_REGISTERS));
|
|
||||||
|
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
GpioCookie* gpioRS485Chip = new GpioCookie;
|
GpioCookie* gpioRS485Chip = new GpioCookie;
|
||||||
|
@ -24,6 +24,7 @@ enum commonClassIds: uint8_t {
|
|||||||
PLOC_MEMORY_DUMPER, //PLMEMDUMP
|
PLOC_MEMORY_DUMPER, //PLMEMDUMP
|
||||||
PDEC_HANDLER, //PDEC
|
PDEC_HANDLER, //PDEC
|
||||||
CCSDS_HANDLER, //CCSDS
|
CCSDS_HANDLER, //CCSDS
|
||||||
|
RATE_SETTER, //RS
|
||||||
ARCSEC_JSON_BASE, //JSONBASE
|
ARCSEC_JSON_BASE, //JSONBASE
|
||||||
NVM_PARAM_BASE, //NVMB
|
NVM_PARAM_BASE, //NVMB
|
||||||
COMMON_CLASS_ID_END // [EXPORT] : [END]
|
COMMON_CLASS_ID_END // [EXPORT] : [END]
|
||||||
|
@ -12,11 +12,7 @@ enum commonObjects: uint32_t {
|
|||||||
TMTC_POLLING_TASK = 0x50000400,
|
TMTC_POLLING_TASK = 0x50000400,
|
||||||
FILE_SYSTEM_HANDLER = 0x50000500,
|
FILE_SYSTEM_HANDLER = 0x50000500,
|
||||||
PTME = 0x50000600,
|
PTME = 0x50000600,
|
||||||
PAPB_VC0 = 0x50000700,
|
PDEC_HANDLER = 0x50000700,
|
||||||
PAPB_VC1 = 0x50000701,
|
|
||||||
PAPB_VC2 = 0x50000702,
|
|
||||||
PAPB_VC3 = 0x50000703,
|
|
||||||
PDEC_HANDLER = 0x50000704,
|
|
||||||
CCSDS_HANDLER = 0x50000800,
|
CCSDS_HANDLER = 0x50000800,
|
||||||
|
|
||||||
/* 0x43 ('C') for Controllers */
|
/* 0x43 ('C') for Controllers */
|
||||||
@ -90,7 +86,9 @@ enum commonObjects: uint32_t {
|
|||||||
|
|
||||||
PLOC_UPDATER = 0x44330000,
|
PLOC_UPDATER = 0x44330000,
|
||||||
PLOC_MEMORY_DUMPER = 0x44330001,
|
PLOC_MEMORY_DUMPER = 0x44330001,
|
||||||
STR_HELPER = 0x44330002
|
STR_HELPER = 0x44330002,
|
||||||
|
PTME_AXI_CONFIG = 44330003,
|
||||||
|
TX_RATE_SETTER = 44330004
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
fsfw
2
fsfw
@ -1 +1 @@
|
|||||||
Subproject commit 9b77060295c9c32ebfc2e7cf6517eb2e66216191
|
Subproject commit faf7da2743dcd30d83c3ab2f7b4d85277878e636
|
@ -4,6 +4,7 @@ target_sources(${TARGET_NAME} PUBLIC
|
|||||||
PdecHandler.cpp
|
PdecHandler.cpp
|
||||||
PdecConfig.cpp
|
PdecConfig.cpp
|
||||||
PtmeRateSetter.cpp
|
PtmeRateSetter.cpp
|
||||||
|
PtmeAxiConfig.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
|
#include <fsfw_hal/linux/uio/UioMapper.h>
|
||||||
#include <linux/obc/PapbVcInterface.h>
|
#include <linux/obc/PapbVcInterface.h>
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
PapbVcInterface::PapbVcInterface(object_id_t objectId, LinuxLibgpioIF* gpioComIF,
|
PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId,
|
||||||
gpioId_t papbBusyId, gpioId_t papbEmptyId, uint32_t vcOffset)
|
gpioId_t papbEmptyId, std::string uioFile, int mapNum)
|
||||||
: SystemObject(objectId),
|
: gpioComIF(gpioComIF),
|
||||||
gpioComIF(gpioComIF),
|
|
||||||
papbBusyId(papbBusyId),
|
papbBusyId(papbBusyId),
|
||||||
papbEmptyId(papbEmptyId),
|
papbEmptyId(papbEmptyId),
|
||||||
vcOffset(vcOffset) {}
|
uioFile(uioFile),
|
||||||
|
mapNum(mapNum) {}
|
||||||
|
|
||||||
PapbVcInterface::~PapbVcInterface() {}
|
PapbVcInterface::~PapbVcInterface() {}
|
||||||
|
|
||||||
void PapbVcInterface::setRegisterAddress(uint32_t* ptmeBaseAddress) {
|
ReturnValue_t PapbVcInterface::initialize() {
|
||||||
vcBaseReg = ptmeBaseAddress + vcOffset;
|
UioMapper uioMapper(uioFile, mapNum);
|
||||||
|
return uioMapper.getMappedAdress(&vcBaseReg, UioMapper::Permissions::WRITE_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
||||||
if (pollPapbBusySignal() == RETURN_OK) {
|
if (pollPapbBusySignal() == RETURN_OK) {
|
||||||
startPacketTransfer();
|
startPacketTransfer();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t idx = 0; idx < size; idx++) {
|
for (size_t idx = 0; idx < size; idx++) {
|
||||||
if (pollPapbBusySignal() == RETURN_OK) {
|
if (pollPapbBusySignal() == RETURN_OK) {
|
||||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
||||||
@ -30,7 +30,6 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
|||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pollPapbBusySignal() == RETURN_OK) {
|
if (pollPapbBusySignal() == RETURN_OK) {
|
||||||
endPacketTransfer();
|
endPacketTransfer();
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
#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>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "linux/obc/VcInterfaceIF.h"
|
#include "linux/obc/VcInterfaceIF.h"
|
||||||
|
|
||||||
@ -15,26 +13,27 @@
|
|||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class PapbVcInterface : public SystemObject, public VcInterfaceIF, public HasReturnvaluesIF {
|
class PapbVcInterface : public VcInterfaceIF, public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
*
|
*
|
||||||
* @param objectId
|
|
||||||
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
|
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
|
||||||
* VcInterface IP Core. A low logic level indicates the VcInterface is not
|
* VcInterface IP Core. A low logic level indicates the VcInterface is not
|
||||||
* ready to receive more data.
|
* ready to receive more data.
|
||||||
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
|
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
|
||||||
* VcInterface IP Core. The signal is high when there are no packets in the
|
* VcInterface IP Core. The signal is high when there are no packets in the
|
||||||
* external buffer memory (BRAM).
|
* external buffer memory (BRAM).
|
||||||
|
* @param uioFile UIO file providing access to the PAPB bus
|
||||||
|
* @param mapNum Map number of UIO map associated with this virtual channel
|
||||||
*/
|
*/
|
||||||
PapbVcInterface(object_id_t objectId, LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId,
|
PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId, gpioId_t papbEmptyId,
|
||||||
gpioId_t papbEmptyId, uint32_t vcOffset);
|
std::string uioFile, int mapNum);
|
||||||
virtual ~PapbVcInterface();
|
virtual ~PapbVcInterface();
|
||||||
|
|
||||||
ReturnValue_t write(const uint8_t* data, size_t size) override;
|
ReturnValue_t write(const uint8_t* data, size_t size) override;
|
||||||
|
|
||||||
void setRegisterAddress(uint32_t* ptmeBaseAddress) override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
|
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
|
||||||
@ -69,6 +68,9 @@ class PapbVcInterface : public SystemObject, public VcInterfaceIF, public HasRet
|
|||||||
/** High when external buffer memory of virtual channel is empty */
|
/** High when external buffer memory of virtual channel is empty */
|
||||||
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
||||||
|
|
||||||
|
std::string uioFile;
|
||||||
|
int mapNum = 0;
|
||||||
|
|
||||||
uint32_t* vcBaseReg = nullptr;
|
uint32_t* vcBaseReg = nullptr;
|
||||||
|
|
||||||
uint32_t vcOffset = 0;
|
uint32_t vcOffset = 0;
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
#include "PdecHandler.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
|
#include "PdecHandler.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#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"
|
||||||
|
|
||||||
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, std::string uioConfigMemory,
|
||||||
@ -44,17 +42,18 @@ ReturnValue_t PdecHandler::initialize() {
|
|||||||
|
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
|
||||||
result = getRegisterAddress();
|
UioMapper regMapper(uioRegisters);
|
||||||
|
result = regMapper.getMappedAdress(®isterBaseAddress, UioMapper::Permissions::READ_WRITE);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
UioMapper configMemMapper(uioConfigMemory);
|
||||||
result = getConfigMemoryBaseAddress();
|
result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
UioMapper ramMapper(uioRamMemory);
|
||||||
result = getRamBaseAddress();
|
result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
@ -76,55 +75,6 @@ ReturnValue_t PdecHandler::initialize() {
|
|||||||
|
|
||||||
MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); }
|
MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); }
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::getRegisterAddress() {
|
|
||||||
int fd = open(uioRegisters.c_str(), O_RDWR);
|
|
||||||
if (fd < 1) {
|
|
||||||
sif::warning << "PdecHandler::getRegisterAddress: Invalid UIO device file" << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
registerBaseAddress = static_cast<uint32_t*>(
|
|
||||||
mmap(NULL, REGISTER_MAP_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0));
|
|
||||||
|
|
||||||
if (registerBaseAddress == MAP_FAILED) {
|
|
||||||
sif::error << "PdecHandler::getRegisterAddress: Failed to map uio address" << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::getConfigMemoryBaseAddress() {
|
|
||||||
int fd = open(uioConfigMemory.c_str(), O_RDWR);
|
|
||||||
if (fd < 1) {
|
|
||||||
sif::warning << "PdecHandler::getConfigMemoryBaseAddress: Invalid UIO device file" << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
memoryBaseAddress = static_cast<uint32_t*>(
|
|
||||||
mmap(NULL, CONFIG_MEMORY_MAP_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0));
|
|
||||||
|
|
||||||
if (memoryBaseAddress == MAP_FAILED) {
|
|
||||||
sif::error << "PdecHandler::getConfigMemoryBaseAddress: Failed to map uio address" << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::getRamBaseAddress() {
|
|
||||||
int fd = open(uioRamMemory.c_str(), O_RDWR);
|
|
||||||
|
|
||||||
ramBaseAddress =
|
|
||||||
static_cast<uint32_t*>(mmap(NULL, RAM_MAP_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0));
|
|
||||||
|
|
||||||
if (ramBaseAddress == MAP_FAILED) {
|
|
||||||
sif::error << "PdecHandler::getRamBaseAddress: Failed to map RAM base address" << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdecHandler::writePdecConfig() {
|
void PdecHandler::writePdecConfig() {
|
||||||
PdecConfig pdecConfig;
|
PdecConfig pdecConfig;
|
||||||
|
|
||||||
|
@ -231,25 +231,6 @@ class PdecHandler : public SystemObject,
|
|||||||
*/
|
*/
|
||||||
void readCommandQueue(void);
|
void readCommandQueue(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Opens UIO device assigned to AXI to AHB converter giving access to the PDEC
|
|
||||||
* registers. The register base address will be mapped into the virtual address space.
|
|
||||||
*/
|
|
||||||
ReturnValue_t getRegisterAddress();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Opens UIO device assigned to the base address of the PDEC memory space and maps the
|
|
||||||
* physical address into the virtual address space.
|
|
||||||
*/
|
|
||||||
ReturnValue_t getConfigMemoryBaseAddress();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Opens UIO device assigned to the RAM section of the PDEC IP core memory map.
|
|
||||||
*
|
|
||||||
* @details A received TC segment will be written to this memory area.
|
|
||||||
*/
|
|
||||||
ReturnValue_t getRamBaseAddress();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/obc/Ptme.h>
|
#include <linux/obc/Ptme.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "PtmeConfig.h"
|
#include "PtmeConfig.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
@ -10,28 +10,10 @@ Ptme::Ptme(object_id_t objectId) : SystemObject(objectId) {}
|
|||||||
Ptme::~Ptme() {}
|
Ptme::~Ptme() {}
|
||||||
|
|
||||||
ReturnValue_t Ptme::initialize() {
|
ReturnValue_t Ptme::initialize() {
|
||||||
int fd = open(PtmeConfig::UIO_DEVICE_FILE, O_RDWR);
|
|
||||||
if (fd < 1) {
|
|
||||||
sif::warning << "Ptme::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 << "Ptme::initialize: Failed to map uio address" << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
VcInterfaceMapIter iter;
|
VcInterfaceMapIter iter;
|
||||||
for (iter = vcInterfaceMap.begin(); iter != vcInterfaceMap.end(); iter++) {
|
for (iter = vcInterfaceMap.begin(); iter != vcInterfaceMap.end(); iter++) {
|
||||||
iter->second->setRegisterAddress(ptmeBaseAddress);
|
iter->second->initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,14 +44,6 @@ class Ptme : public PtmeIF, public SystemObject, public HasReturnvaluesIF {
|
|||||||
|
|
||||||
static const ReturnValue_t UNKNOWN_VC_ID = MAKE_RETURN_CODE(0xA0);
|
static const ReturnValue_t UNKNOWN_VC_ID = MAKE_RETURN_CODE(0xA0);
|
||||||
|
|
||||||
#if BOARD_TE0720 == 1
|
|
||||||
/** Size of mapped address space */
|
|
||||||
static const int MAP_SIZE = 0x40000;
|
|
||||||
#else
|
|
||||||
/** Size of mapped address space */
|
|
||||||
static const int MAP_SIZE = 0x40000;
|
|
||||||
#endif /* BOARD_TE0720 == 1 */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration bits:
|
* Configuration bits:
|
||||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||||
|
41
linux/obc/PtmeAxiConfig.cpp
Normal file
41
linux/obc/PtmeAxiConfig.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "PtmeAxiConfig.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
#include "fsfw_hal/linux/uio/UioMapper.h"
|
||||||
|
|
||||||
|
PtmeAxiConfig::PtmeAxiConfig(object_id_t objectId, std::string configAxiUio, int mapNum) :
|
||||||
|
SystemObject(objectId), configAxiUio(configAxiUio), mapNum(mapNum) {
|
||||||
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
|
if (mutex == nullptr) {
|
||||||
|
sif::warning << "Failed to create mutex" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PtmeAxiConfig::~PtmeAxiConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PtmeAxiConfig::initialize() {
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
UioMapper uioMapper(configAxiUio, mapNum);
|
||||||
|
result = uioMapper.getMappedAdress(&baseAddress, UioMapper::Permissions::READ_WRITE);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PtmeAxiConfig::writeCaduRateReg(uint8_t rateVal) {
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
result = mutex->lockMutex(timeoutType, mutexTimeout);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::warning << "PtmeAxiConfig::writeCaduRateReg: Failed to lock mutex" << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
*(baseAddress + CADU_BITRATE_REG) = static_cast<uint32_t>(rateVal);
|
||||||
|
result = mutex->unlockMutex();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::warning << "PtmeAxiConfig::writeCaduRateReg: Failed to unlock mutex" << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
42
linux/obc/PtmeAxiConfig.h
Normal file
42
linux/obc/PtmeAxiConfig.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef LINUX_OBC_PTMEAXICONFIG_H_
|
||||||
|
#define LINUX_OBC_PTMEAXICONFIG_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Class providing low level access to the configuration interface of the PTME.
|
||||||
|
*
|
||||||
|
* @author J. Meier
|
||||||
|
*/
|
||||||
|
class PtmeAxiConfig : public SystemObject {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param configAxiUio Device file of UIO belonging to the AXI configuration interface.
|
||||||
|
* @param mapNum Number of map belonging to axi configuration interface.
|
||||||
|
*/
|
||||||
|
PtmeAxiConfig(object_id_t objectId, std::string configAxiUio, int mapNum);
|
||||||
|
virtual ~PtmeAxiConfig();
|
||||||
|
|
||||||
|
virtual ReturnValue_t initialize() override;
|
||||||
|
ReturnValue_t writeCaduRateReg(uint8_t rateVal);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Address of register storing the bitrate configuration parameter
|
||||||
|
static const uint32_t CADU_BITRATE_REG = 0x0;
|
||||||
|
|
||||||
|
std::string configAxiUio;
|
||||||
|
std::string uioMap;
|
||||||
|
int mapNum = 0;
|
||||||
|
MutexIF* mutex = nullptr;
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
|
uint32_t mutexTimeout = 20;
|
||||||
|
|
||||||
|
uint32_t* baseAddress = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LINUX_OBC_PTMEAXICONFIG_H_ */
|
@ -25,7 +25,8 @@ static const char UIO_DEVICE_FILE[] = "/dev/uio1";
|
|||||||
#else
|
#else
|
||||||
static const char UIO_DEVICE_FILE[] = "/dev/uio1";
|
static const char UIO_DEVICE_FILE[] = "/dev/uio1";
|
||||||
#endif
|
#endif
|
||||||
|
// Bit clock frequency of PMTE IP core in Hz
|
||||||
|
static const uint32_t BIT_CLK_FREQ = 20000000;
|
||||||
}; // namespace PtmeConfig
|
}; // namespace PtmeConfig
|
||||||
|
|
||||||
#endif /* LINUX_OBC_PTMECONFIG_H_ */
|
#endif /* LINUX_OBC_PTMECONFIG_H_ */
|
||||||
|
@ -2,24 +2,26 @@
|
|||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
PtmeRateSetter::PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif)
|
PtmeRateSetter::PtmeRateSetter(object_id_t objectId, PtmeAxiConfig* ptmeAxiConfig)
|
||||||
: bitrateSel(bitrateSel), gpioif(gpioif) {}
|
: SystemObject(objectId), ptmeAxiConfig(ptmeAxiConfig) {}
|
||||||
|
|
||||||
PtmeRateSetter::~PtmeRateSetter() {}
|
PtmeRateSetter::~PtmeRateSetter() {}
|
||||||
|
|
||||||
ReturnValue_t PtmeRateSetter::setRate(BitRates rate) {
|
ReturnValue_t PtmeRateSetter::initialize() {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
if (ptmeAxiConfig == nullptr) {
|
||||||
switch (rate) {
|
sif::warning << "PtmeRateSetter::initialize: Invalid PtmeAxiConfig object" << std::endl;
|
||||||
case RATE_2000KHZ:
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
result = gpioif->pullHigh(bitrateSel);
|
|
||||||
break;
|
|
||||||
case RATE_400KHZ:
|
|
||||||
result = gpioif->pullLow(bitrateSel);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sif::debug << "PtmeRateSetter::setRate: Invalid rate" << std::endl;
|
|
||||||
result = HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return result;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PtmeRateSetter::setRate(uint32_t bitRate) {
|
||||||
|
if (bitRate == 0) {
|
||||||
|
return BAD_BIT_RATE;
|
||||||
|
}
|
||||||
|
uint32_t rateVal = PtmeConfig::BIT_CLK_FREQ / bitRate - 1;
|
||||||
|
if (rateVal > 0xFF) {
|
||||||
|
return RATE_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ptmeAxiConfig->writeCaduRateReg(static_cast<uint8_t>(rateVal));
|
||||||
}
|
}
|
||||||
|
@ -3,36 +3,46 @@
|
|||||||
|
|
||||||
#include "TxRateSetterIF.h"
|
#include "TxRateSetterIF.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
#include "linux/obc/PtmeAxiConfig.h"
|
||||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
#include "linux/obc/PtmeConfig.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class to set the downlink bit rate by using the cadu_rate_switcher implemented in
|
* @brief Class to set the downlink bit rate by writing to the AXI configuration interface of the
|
||||||
* the programmable logic.
|
* PTME IP core.
|
||||||
*
|
*
|
||||||
* @details The cadu_rate_switcher module sets the input rate to the syrlinks transceiver either
|
* @details This is the bitrate of the CADU clock and not the downlink which has twice the bitrate
|
||||||
* to 2000 kHz (bitrateSel = 1) or 400 kHz (bitrate = 0).
|
* of the CADU clock due to the convolutional code added by the s-Band transceiver.
|
||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class PtmeRateSetter : public TxRateSetterIF {
|
class PtmeRateSetter : public TxRateSetterIF, public SystemObject, public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
*
|
*
|
||||||
* @param bitrateSel GPIO ID of the GPIO connected to the bitrate_sel input of the
|
* objectId Object id of system object
|
||||||
* cadu_rate_switcher.
|
* ptmeAxiConfig Pointer to object providing access to PTME configuration registers.
|
||||||
* @param gpioif GPIO interface to drive the bitrateSel GPIO
|
|
||||||
*/
|
*/
|
||||||
PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif);
|
PtmeRateSetter(object_id_t objectId, PtmeAxiConfig* ptmeAxiConfig);
|
||||||
virtual ~PtmeRateSetter();
|
virtual ~PtmeRateSetter();
|
||||||
|
|
||||||
virtual ReturnValue_t setRate(BitRates rate);
|
virtual ReturnValue_t initialize() override;
|
||||||
|
virtual ReturnValue_t setRate(uint32_t bitRate);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gpioId_t bitrateSel = gpio::NO_GPIO;
|
|
||||||
|
|
||||||
GpioIF* gpioif = nullptr;
|
static const uint8_t INTERFACE_ID = CLASS_ID::RATE_SETTER;
|
||||||
|
|
||||||
|
//! [EXPORT] : [COMMENT] The commanded rate is not supported by the current FPGA design
|
||||||
|
static const ReturnValue_t RATE_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA0);
|
||||||
|
//! [EXPORT] : [COMMENT] Bad bitrate has been commanded (e.g. 0)
|
||||||
|
static const ReturnValue_t BAD_BIT_RATE = MAKE_RETURN_CODE(0xA1);
|
||||||
|
|
||||||
|
// Bitrate register field is only 8 bit wide
|
||||||
|
static const uint32_t MAX_BITRATE = 0xFF;
|
||||||
|
|
||||||
|
PtmeAxiConfig* ptmeAxiConfig = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_OBC_PTMERATESETTER_H_ */
|
#endif /* LINUX_OBC_PTMERATESETTER_H_ */
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
enum BitRates : uint32_t { RATE_2000KHZ, RATE_400KHZ };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Abstract class for objects implementing the functionality to switch the
|
* @brief Abstract class for objects implementing the functionality to switch the
|
||||||
* downlink bit rate.
|
* downlink bit rate.
|
||||||
@ -16,7 +14,7 @@ class TxRateSetterIF {
|
|||||||
TxRateSetterIF(){};
|
TxRateSetterIF(){};
|
||||||
virtual ~TxRateSetterIF(){};
|
virtual ~TxRateSetterIF(){};
|
||||||
|
|
||||||
virtual ReturnValue_t setRate(BitRates bitRate) = 0;
|
virtual ReturnValue_t setRate(uint32_t bitRate) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_OBC_TXRATESETTERIF_H_ */
|
#endif /* LINUX_OBC_TXRATESETTERIF_H_ */
|
||||||
|
@ -24,7 +24,7 @@ class VcInterfaceIF {
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t write(const uint8_t* data, size_t size) = 0;
|
virtual ReturnValue_t write(const uint8_t* data, size_t size) = 0;
|
||||||
|
|
||||||
virtual void setRegisterAddress(uint32_t* ptmeBaseAddress) = 0;
|
virtual ReturnValue_t initialize() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_OBC_VCINTERFACEIF_H_ */
|
#endif /* LINUX_OBC_VCINTERFACEIF_H_ */
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "fsfw/events/EventManagerIF.h"
|
#include "fsfw/events/EventManagerIF.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||||
|
|
||||||
@ -189,14 +190,21 @@ MessageQueueId_t CCSDSHandler::getRequestQueue() {
|
|||||||
|
|
||||||
ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size) {
|
const uint8_t* data, size_t size) {
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case SET_LOW_RATE: {
|
case SET_LOW_RATE: {
|
||||||
txRateSetterIF->setRate(BitRates::RATE_400KHZ);
|
result = txRateSetterIF->setRate(RATE_100KBPS);
|
||||||
return EXECUTION_FINISHED;
|
break;
|
||||||
}
|
}
|
||||||
case SET_HIGH_RATE: {
|
case SET_HIGH_RATE: {
|
||||||
txRateSetterIF->setRate(BitRates::RATE_2000KHZ);
|
result = txRateSetterIF->setRate(RATE_500KBPS);
|
||||||
return EXECUTION_FINISHED;
|
break;
|
||||||
|
}
|
||||||
|
case ARBITRARY_RATE: {
|
||||||
|
uint32_t bitrate = 0;
|
||||||
|
SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
|
||||||
|
result = txRateSetterIF->setRate(bitrate);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case EN_TRANSMITTER: {
|
case EN_TRANSMITTER: {
|
||||||
enableTransmit();
|
enableTransmit();
|
||||||
@ -209,6 +217,10 @@ ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, MessageQueueId_t
|
|||||||
default:
|
default:
|
||||||
return COMMAND_NOT_IMPLEMENTED;
|
return COMMAND_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCSDSHandler::checkEvents() {
|
void CCSDSHandler::checkEvents() {
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
* @brief This class handles the data exchange with the CCSDS IP cores implemented in the
|
* @brief This class handles the data exchange with the CCSDS IP cores implemented in the
|
||||||
* programmable logic of the Q7S.
|
* programmable logic of the Q7S.
|
||||||
*
|
*
|
||||||
|
* @details After reboot default CADU bitrate is always set to 100 kbps (results in downlink rate
|
||||||
|
* of 200 kbps due to convolutional code added by syrlinks transceiver)
|
||||||
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class CCSDSHandler : public SystemObject,
|
class CCSDSHandler : public SystemObject,
|
||||||
@ -85,6 +88,13 @@ class CCSDSHandler : public SystemObject,
|
|||||||
static const ActionId_t SET_HIGH_RATE = 1;
|
static const ActionId_t SET_HIGH_RATE = 1;
|
||||||
static const ActionId_t EN_TRANSMITTER = 2;
|
static const ActionId_t EN_TRANSMITTER = 2;
|
||||||
static const ActionId_t DIS_TRANSMITTER = 3;
|
static const ActionId_t DIS_TRANSMITTER = 3;
|
||||||
|
static const ActionId_t ARBITRARY_RATE = 4;
|
||||||
|
|
||||||
|
// Syrlinks supports two bitrates (200 kbps and 1000 kbps)
|
||||||
|
// Due to convolutional code added by the syrlinks the input frequency must be half the
|
||||||
|
// target frequency
|
||||||
|
static const uint32_t RATE_100KBPS = 100000;
|
||||||
|
static const uint32_t RATE_500KBPS = 500000;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
|
||||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
|||||||
Subproject commit 6f24d6a83995ca7a895c17a77a00bceac4d7f141
|
Subproject commit 598635ee4fb1eb246980564ae9f3a0feb1f4da30
|
Loading…
Reference in New Issue
Block a user