diff --git a/README.md b/README.md index 6ad16a87..7d27b092 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ 13. [Eclipse](#eclipse) 14. [Running the OBSW on a Raspberry Pi](#rpi) 15. [FSFW](#fsfw) +16. [Coding Style](#coding-style) # General information @@ -1151,3 +1152,15 @@ git merge upstream/master Alternatively, changes from other upstreams (forks) and branches can be merged like that in the same way. + +# 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 \ No newline at end of file diff --git a/apply-clang-format.sh b/apply-clang-format.sh deleted file mode 100755 index 6d77c6e9..00000000 --- a/apply-clang-format.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -if [[ ! -f README.md ]]; then - cd .. -fi - -find ./mission -iname *.h o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./linux -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./bsp_q7s -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./bsp_linux_board -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./bsp_hosted -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./test -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index e41ed093..2083ac6b 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -3,20 +3,30 @@ namespace q7s { -static constexpr char SPI_DEFAULT_DEV[] = "/dev/spidev2.0"; -static constexpr char SPI_RW_DEV[] = "/dev/spidev3.0"; +static constexpr char SPI_DEFAULT_DEV[] = "/dev/spi-main"; +static constexpr char SPI_RW_DEV[] = "/dev/spi-rw"; -static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-1"; +static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-eive"; -static constexpr char UART_GNSS_DEV[] = "/dev/ttyUL0"; -static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ttyUL2"; -static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ttyUL3"; -static constexpr char UART_SYRLINKS_DEV[] = "/dev/ttyUL4"; -static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ttyUL7"; +static constexpr char UART_GNSS_DEV[] = "/dev/ul-gps"; +static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ul-plmpsoc"; +static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ul-plsv"; +static constexpr char UART_SYRLINKS_DEV[] = "/dev/ul-syrlinks"; +static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ul-str"; static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio0"; static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio2"; 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 uiomapids namespace gpioNames { static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select"; @@ -33,6 +43,7 @@ static constexpr char GNSS_0_ENABLE[] = "enable_gnss_0"; static constexpr char GNSS_1_ENABLE[] = "enable_gnss_1"; static constexpr char GYRO_0_ENABLE[] = "enable_gyro_0"; static constexpr char GYRO_2_ENABLE[] = "enable_gyro_2"; +static constexpr char GNSS_SELECT[] = "gnss_mux_select"; static constexpr char HEATER_0[] = "heater0"; static constexpr char HEATER_1[] = "heater1"; static constexpr char HEATER_2[] = "heater2"; @@ -69,7 +80,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_DATA[] = "rx_data_enable_ltc2872"; static constexpr char PDEC_RESET[] = "pdec_reset"; -static constexpr char BIT_RATE_SEL[] = "bit_rate_sel"; } // namespace gpioNames } // namespace q7s diff --git a/bsp_q7s/callbacks/CMakeLists.txt b/bsp_q7s/callbacks/CMakeLists.txt index 8c83e26f..a85bf6fb 100644 --- a/bsp_q7s/callbacks/CMakeLists.txt +++ b/bsp_q7s/callbacks/CMakeLists.txt @@ -1,4 +1,5 @@ target_sources(${TARGET_NAME} PRIVATE rwSpiCallback.cpp gnssCallback.cpp + pcduSwitchCb.cpp ) diff --git a/bsp_q7s/callbacks/pcduSwitchCb.cpp b/bsp_q7s/callbacks/pcduSwitchCb.cpp new file mode 100644 index 00000000..ec5f4dc5 --- /dev/null +++ b/bsp_q7s/callbacks/pcduSwitchCb.cpp @@ -0,0 +1,32 @@ +#include "pcduSwitchCb.h" + +#include + +#include "devices/gpioIds.h" + +void pcdu::switchCallback(GOMSPACE::Pdu pdu, uint8_t channel, bool state, void* args) { + LinuxLibgpioIF* gpioComIF = reinterpret_cast(args); + if (gpioComIF == nullptr) { + return; + } + if (pdu == GOMSPACE::Pdu::PDU1) { + PDU1::SwitchChannels typedChannel = static_cast(channel); + if (typedChannel == PDU1::SwitchChannels::ACS_A_SIDE) { + if (state) { + gpioComIF->pullHigh(gpioIds::GNSS_0_NRESET); + } else { + gpioComIF->pullLow(gpioIds::GNSS_0_NRESET); + } + } + + } else if (pdu == GOMSPACE::Pdu::PDU2) { + PDU2::SwitchChannels typedChannel = static_cast(channel); + if (typedChannel == PDU2::SwitchChannels::ACS_B_SIDE) { + if (state) { + gpioComIF->pullHigh(gpioIds::GNSS_1_NRESET); + } else { + gpioComIF->pullLow(gpioIds::GNSS_1_NRESET); + } + } + } +} diff --git a/bsp_q7s/callbacks/pcduSwitchCb.h b/bsp_q7s/callbacks/pcduSwitchCb.h new file mode 100644 index 00000000..d0f2b748 --- /dev/null +++ b/bsp_q7s/callbacks/pcduSwitchCb.h @@ -0,0 +1,14 @@ +#ifndef BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ +#define BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ + +#include + +#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" + +namespace pcdu { + +void switchCallback(GOMSPACE::Pdu pdu, uint8_t channel, bool state, void* args); + +} + +#endif /* BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ */ diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index a5b2b548..cb01496c 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -115,12 +115,14 @@ void initmission::initTasks() { } #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ +#if OBSW_ADD_ACS_HANDLERS == 1 PeriodicTaskIF* acsCtrl = factory->createPeriodicTask( - "ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); + "ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); result = acsCtrl->addComponent(objects::GPS_CONTROLLER); if (result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER); } +#endif /* OBSW_ADD_ACS_HANDLERS */ #if BOARD_TE0720 == 0 // FS task, task interval does not matter because it runs in permanent loop, priority low @@ -134,10 +136,10 @@ void initmission::initTasks() { #if OBSW_ADD_STAR_TRACKER == 1 PeriodicTaskIF* strImgLoaderTask = factory->createPeriodicTask( - "FILE_SYSTEM_TASK", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + "STR_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = strImgLoaderTask->addComponent(objects::STR_HELPER); if (result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::STR_HELPER); + initmission::printAddObjectError("STR_HELPER", objects::STR_HELPER); } #endif /* OBSW_ADD_STAR_TRACKER == 1 */ @@ -206,7 +208,9 @@ void initmission::initTasks() { #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif - //acsCtrl->startTask(); +#if OBSW_ADD_ACS_HANDLERS == 1 + acsCtrl->startTask(); +#endif sif::info << "Tasks started.." << std::endl; } @@ -250,6 +254,7 @@ void initmission::createPstTasks(TaskFactory& factory, if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; } + taskVec.push_back(i2cPst); FixedTimeslotTaskIF* gomSpacePstTask = factory.createFixedTimeslotTask( "GS_PST_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc); @@ -258,7 +263,7 @@ void initmission::createPstTasks(TaskFactory& factory, sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; } taskVec.push_back(gomSpacePstTask); -#else /* BOARD_TE7020 == 0 */ +#else /* BOARD_TE7020 == 0 */ FixedTimeslotTaskIF* pollingSequenceTaskTE0720 = factory.createFixedTimeslotTask( "PST_TASK_TE0720", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE * 8, 3.0, missedDeadlineFunc); result = pst::pollingSequenceTE0720(pollingSequenceTaskTE0720); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 477976d0..13a1624c 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -5,6 +5,7 @@ #include "OBSWConfig.h" #include "bsp_q7s/boardtest/Q7STestTask.h" #include "bsp_q7s/callbacks/gnssCallback.h" +#include "bsp_q7s/callbacks/pcduSwitchCb.h" #include "bsp_q7s/callbacks/rwSpiCallback.h" #include "bsp_q7s/core/CoreController.h" #include "bsp_q7s/devices/PlocMemoryDumper.h" @@ -44,7 +45,7 @@ #include "linux/devices/devicedefinitions/SusDefinitions.h" #include "mission/core/GenericFactory.h" #include "mission/devices/ACUHandler.h" -#include "mission/devices/GPSHyperionHandler.h" +#include "mission/devices/GPSHyperionLinuxController.h" #include "mission/devices/GyroADIS1650XHandler.h" #include "mission/devices/HeaterHandler.h" #include "mission/devices/IMTQHandler.h" @@ -74,12 +75,11 @@ #include "linux/boardtest/LibgpiodTest.h" #endif +#include #include #include #include #include -#include -#include ResetArgs resetArgsGnss0; ResetArgs resetArgsGnss1; @@ -122,13 +122,14 @@ void ObjectFactory::produce(void* args) { #if BOARD_TE0720 == 0 new CoreController(objects::CORE_CONTROLLER); - createPcduComponents(); + createPcduComponents(gpioComIF); createRadSensorComponent(gpioComIF); createSunSensorComponents(gpioComIF, spiComIF); #if OBSW_ADD_ACS_BOARD == 1 createAcsBoardComponents(gpioComIF, uartComIF); -#endif /* OBSW_ADD_ACS_BOARD == 1 */ +#endif + createHeaterComponents(); createSolarArrayDeploymentComponents(); #if OBSW_ADD_SYRLINKS == 1 @@ -139,9 +140,18 @@ void ObjectFactory::produce(void* args) { createRtdComponents(gpioComIF); #endif /* OBSW_ADD_RTD_DEVICES == 1 */ +#if OBSW_ADD_MGT == 1 I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, IMTQ::MAX_REPLY_SIZE, q7s::I2C_DEFAULT_DEV); - new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie); + auto imtqHandler = new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie); + static_cast(imtqHandler); +#if OBSW_DEBUG_IMTQ == 1 + imtqHandler->setToGoToNormal(true); + imtqHandler->setStartUpImmediately(); +#else + (void)imtqHandler; +#endif +#endif createReactionWheelComponents(gpioComIF); I2cCookie* bpxI2cCookie = new I2cCookie(addresses::BPX_BATTERY, 100, q7s::I2C_DEFAULT_DEV); @@ -236,7 +246,7 @@ void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, Ua #endif } -void ObjectFactory::createPcduComponents() { +void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) { CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK); CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1); CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2); @@ -246,8 +256,10 @@ void ObjectFactory::createPcduComponents() { new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie); PDU1Handler* pdu1handler = new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie); + pdu1handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF); PDU2Handler* pdu2handler = new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie); + pdu2handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF); ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie); new PCDUHandler(objects::PCDU_HANDLER, 50); @@ -472,8 +484,15 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI gpio::LOW); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_ENABLE, gpio); + // Select pin. 0 for GPS side A, 1 for GPS side B + consumer.str(""); + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_SELECT, consumer.str(), gpio::DIR_OUT, + gpio::LOW); + gpioCookieAcsBoard->addGpio(gpioIds::GNSS_SELECT, gpio); gpioComIF->addGpios(gpioCookieAcsBoard); +#if OBSW_ADD_ACS_HANDLERS == 1 std::string spiDev = q7s::SPI_DEFAULT_DEV; SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, @@ -568,8 +587,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI resetArgsGnss0.gnss1 = false; resetArgsGnss0.gpioComIF = gpioComIF; resetArgsGnss0.waitPeriodMs = 100; - auto gpsHandler0 = new GPSHyperionHandler(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); + auto gpsHandler0 = + new GPSHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); +#endif /* OBSW_ADD_ACS_HANDLERS == 1 */ } void ObjectFactory::createHeaterComponents() { @@ -895,49 +916,50 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { GpioCookie* gpioCookiePtmeIp = new GpioCookie; GpiodRegularByLineName* gpio = nullptr; 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()); gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC0; + consumer.str("PAPB VC0"); gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, consumer.str()); gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio); - consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC1; + consumer.str("PAPB VC 1"); gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, consumer.str()); gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio); consumer.str(""); - consumer << "0x" << std::hex << objects::PAPB_VC1; - gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC1, consumer.str()); + consumer.str("PAPB VC 1"); gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio); 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()); gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio); 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()); gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio); 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()); gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio); 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()); gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio); gpioComIF->addGpios(gpioCookiePtmeIp); // Creating virtual channel interfaces - VcInterfaceIF* vc0 = new PapbVcInterface(objects::PAPB_VC0, gpioComIF, gpioIds::VC0_PAPB_BUSY, - gpioIds::VC0_PAPB_EMPTY, PtmeConfig::VC0_OFFSETT); - VcInterfaceIF* vc1 = new PapbVcInterface(objects::PAPB_VC1, gpioComIF, gpioIds::VC1_PAPB_BUSY, - gpioIds::VC1_PAPB_EMPTY, PtmeConfig::VC1_OFFSETT); - VcInterfaceIF* vc2 = new PapbVcInterface(objects::PAPB_VC2, gpioComIF, gpioIds::VC2_PAPB_BUSY, - gpioIds::VC2_PAPB_EMPTY, PtmeConfig::VC2_OFFSETT); - VcInterfaceIF* vc3 = new PapbVcInterface(objects::PAPB_VC3, gpioComIF, gpioIds::VC3_PAPB_BUSY, - gpioIds::VC3_PAPB_EMPTY, PtmeConfig::VC3_OFFSETT); + VcInterfaceIF* vc0 = + new PapbVcInterface(gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY, q7s::UIO_PTME, + q7s::uiomapids::PTME_VC0); + VcInterfaceIF* vc1 = + new PapbVcInterface(gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY, q7s::UIO_PTME, + q7s::uiomapids::PTME_VC1); + VcInterfaceIF* vc2 = + 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 Ptme* ptme = new Ptme(objects::PTME); @@ -946,19 +968,11 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { ptme->addVcInterface(ccsds::VC2, vc2); ptme->addVcInterface(ccsds::VC3, vc3); - GpioCookie* gpioCookieRateSetter = new GpioCookie; - consumer.str(""); - consumer << "ptme rate setter"; - // 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); - + AxiPtmeConfig* axiPtmeConfig = + new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG); + PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig); CCSDSHandler* ccsdsHandler = new CCSDSHandler( - objects::CCSDS_HANDLER, objects::PTME, objects::CCSDS_PACKET_DISTRIBUTOR, txRateSetterIF, + objects::CCSDS_HANDLER, objects::PTME, objects::CCSDS_PACKET_DISTRIBUTOR, ptmeConfig, gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA); VirtualChannel* vc = nullptr; @@ -982,8 +996,7 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { gpioComIF->addGpios(gpioCookiePdec); 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), - std::string(q7s::UIO_PDEC_REGISTERS)); + q7s::UIO_PDEC_CONFIG_MEMORY, q7s::UIO_PDEC_RAM, q7s::UIO_PDEC_REGISTERS); #if BOARD_TE0720 == 0 GpioCookie* gpioRS485Chip = new GpioCookie; diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 47e06e33..8fa4a147 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -13,7 +13,7 @@ void produce(void* args); void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF, SpiComIF** spiComIF); void createTmpComponents(); -void createPcduComponents(); +void createPcduComponents(LinuxLibgpioIF* gpioComIF); void createRadSensorComponent(LinuxLibgpioIF* gpioComIF); void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF); void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF); diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index cd90272d..ab8e06d5 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -24,6 +24,7 @@ enum commonClassIds: uint8_t { PLOC_MEMORY_DUMPER, //PLMEMDUMP PDEC_HANDLER, //PDEC CCSDS_HANDLER, //CCSDS + RATE_SETTER, //RS ARCSEC_JSON_BASE, //JSONBASE NVM_PARAM_BASE, //NVMB COMMON_CLASS_ID_END // [EXPORT] : [END] diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 135259d6..bd364daf 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -12,11 +12,7 @@ enum commonObjects: uint32_t { TMTC_POLLING_TASK = 0x50000400, FILE_SYSTEM_HANDLER = 0x50000500, PTME = 0x50000600, - PAPB_VC0 = 0x50000700, - PAPB_VC1 = 0x50000701, - PAPB_VC2 = 0x50000702, - PAPB_VC3 = 0x50000703, - PDEC_HANDLER = 0x50000704, + PDEC_HANDLER = 0x50000700, CCSDS_HANDLER = 0x50000800, /* 0x43 ('C') for Controllers */ @@ -90,7 +86,9 @@ enum commonObjects: uint32_t { PLOC_UPDATER = 0x44330000, PLOC_MEMORY_DUMPER = 0x44330001, - STR_HELPER = 0x44330002 + STR_HELPER = 0x44330002, + AXI_PTME_CONFIG = 44330003, + PTME_CONFIG = 44330004, }; } diff --git a/fsfw b/fsfw index 9b770602..33386550 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 9b77060295c9c32ebfc2e7cf6517eb2e66216191 +Subproject commit 33386550cf81e47f4a3c95cd063349442dd83d09 diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index ea26425b..324481c5 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -39,35 +39,21 @@ debugging. */ // Set to 1 if telecommands are received via the PDEC IP Core #define OBSW_TC_FROM_PDEC 1 -#define TMTC_TEST_SETUP 1 - #define OBSW_ENABLE_TIMERS 1 +#define OBSW_ADD_MGT 1 #define OBSW_ADD_STAR_TRACKER 0 #define OBSW_ADD_PLOC_SUPERVISOR 0 #define OBSW_ADD_PLOC_MPSOC 0 #define OBSW_ADD_SUN_SENSORS 0 -#define OBSW_ADD_ACS_BOARD 0 -#define OBSW_ADD_RW 0 -#define OBSW_ADD_RTD_DEVICES 0 -#define OBSW_ADD_TMP_DEVICES 0 -#define OBSW_ADD_RAD_SENSORS 0 -#define OBSW_ADD_SYRLINKS 0 - -#elif defined RASPBERRY_PI - -#define OBSW_ENABLE_TIMERS 1 -#define OBSW_ADD_STAR_TRACKER 0 -#define OBSW_ADD_PLOC_SUPERVISOR 0 -#define OBSW_ADD_PLOC_MPSOC 0 -#define OBSW_ADD_SUN_SENSORS 0 -#define OBSW_ADD_ACS_BOARD 0 -#define OBSW_ADD_GPS_0 0 -#define OBSW_ADD_GPS_1 0 +#define OBSW_ADD_ACS_BOARD 1 +#define OBSW_ADD_ACS_HANDLERS 0 #define OBSW_ADD_RW 0 #define OBSW_ADD_RTD_DEVICES 0 #define OBSW_ADD_TMP_DEVICES 0 #define OBSW_ADD_RAD_SENSORS 0 #define OBSW_ADD_SYRLINKS 0 +#define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0 +#define OBSW_SYRLINKS_SIMULATED 1 #endif @@ -78,6 +64,7 @@ debugging. */ //! /* Can be used to switch device to NORMAL mode immediately */ #define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1 #define OBSW_PRINT_MISSED_DEADLINES 1 + // If this is enabled, all other SPI code should be disabled #define OBSW_ADD_TEST_CODE 0 #define OBSW_ADD_SPI_TEST_CODE 0 @@ -99,7 +86,7 @@ debugging. */ #define OBSW_DEBUG_GPS 0 #define OBSW_DEBUG_ACU 0 #define OBSW_DEBUG_SYRLINKS 0 -#define OBSW_DEBUG_IMQT 0 +#define OBSW_DEBUG_IMTQ 0 #define OBSW_DEBUG_RAD_SENSOR 0 #define OBSW_DEBUG_SUS 0 #define OBSW_DEBUG_RTD 0 @@ -109,6 +96,24 @@ debugging. */ #define OBSW_DEBUG_PLOC_SUPERVISOR 0 #define OBSW_DEBUG_PDEC_HANDLER 0 +#ifdef RASPBERRY_PI + +#define OBSW_ENABLE_TIMERS 1 +#define OBSW_ADD_STAR_TRACKER 0 +#define OBSW_ADD_PLOC_SUPERVISOR 0 +#define OBSW_ADD_PLOC_MPSOC 0 +#define OBSW_ADD_SUN_SENSORS 0 +#define OBSW_ADD_ACS_BOARD 0 +#define OBSW_ADD_GPS_0 0 +#define OBSW_ADD_GPS_1 0 +#define OBSW_ADD_RW 0 +#define OBSW_ADD_RTD_DEVICES 0 +#define OBSW_ADD_TMP_DEVICES 0 +#define OBSW_ADD_RAD_SENSORS 0 +#define OBSW_ADD_SYRLINKS 0 + +#endif + /*******************************************************************/ /** Hardcoded */ /*******************************************************************/ diff --git a/linux/fsfwconfig/devices/addresses.h b/linux/fsfwconfig/devices/addresses.h index 3405eb47..a69cdaf9 100644 --- a/linux/fsfwconfig/devices/addresses.h +++ b/linux/fsfwconfig/devices/addresses.h @@ -46,9 +46,9 @@ enum logicalAddresses : address_t { enum i2cAddresses : address_t { BPX_BATTERY = 0x07, - IMTQ = 16, - TMP1075_TCS_1 = 72, - TMP1075_TCS_2 = 73, + IMTQ = 0x10, + TMP1075_TCS_1 = 0x48, + TMP1075_TCS_2 = 0x49, }; enum spiAddresses : address_t { diff --git a/linux/fsfwconfig/devices/gpioIds.h b/linux/fsfwconfig/devices/gpioIds.h index bb753a30..46717569 100644 --- a/linux/fsfwconfig/devices/gpioIds.h +++ b/linux/fsfwconfig/devices/gpioIds.h @@ -29,6 +29,7 @@ enum gpioId_t { GNSS_1_NRESET, GNSS_0_ENABLE, GNSS_1_ENABLE, + GNSS_SELECT, GYRO_0_ENABLE, GYRO_2_ENABLE, diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 814e5c2d..70119272 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -435,7 +435,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::RW4, length * 0.8, DeviceHandlerIF::GET_READ); #endif -#if OBSW_ADD_ACS_BOARD == 1 +#if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 bool enableAside = true; bool enableBside = false; if (enableAside) { @@ -501,7 +501,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); } -#endif /* OBSW_ADD_ACS_BOARD == 1 */ +#endif /* OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 */ ReturnValue_t seqCheck = thisSequence->checkSequence(); if (seqCheck != HasReturnvaluesIF::RETURN_OK) { @@ -519,11 +519,13 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) { // Length of a communication cycle uint32_t length = thisSequence->getPeriodMs(); +#if OBSW_ADD_MGT == 1 thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); +#endif if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) { sif::error << "I2C PST initialization failed" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; diff --git a/linux/obc/AxiPtmeConfig.cpp b/linux/obc/AxiPtmeConfig.cpp new file mode 100644 index 00000000..26830d05 --- /dev/null +++ b/linux/obc/AxiPtmeConfig.cpp @@ -0,0 +1,119 @@ +#include "AxiPtmeConfig.h" + +#include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw_hal/linux/uio/UioMapper.h" + +AxiPtmeConfig::AxiPtmeConfig(object_id_t objectId, std::string axiUio, int mapNum) + : SystemObject(objectId), axiUio(axiUio), mapNum(mapNum) { + mutex = MutexFactory::instance()->createMutex(); + if (mutex == nullptr) { + sif::warning << "Failed to create mutex" << std::endl; + } +} + +AxiPtmeConfig::~AxiPtmeConfig() {} + +ReturnValue_t AxiPtmeConfig::initialize() { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + UioMapper uioMapper(axiUio, mapNum); + result = uioMapper.getMappedAdress(&baseAddress, UioMapper::Permissions::READ_WRITE); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + result = mutex->lockMutex(timeoutType, mutexTimeout); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "AxiPtmeConfig::writeCaduRateReg: Failed to lock mutex" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + *(baseAddress + CADU_BITRATE_REG) = static_cast(rateVal); + result = mutex->unlockMutex(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "AxiPtmeConfig::writeCaduRateReg: Failed to unlock mutex" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AxiPtmeConfig::enableTxclockManipulator() { + ReturnValue_t result = writeBit(COMMON_CONFIG_REG, true, BitPos::EN_TX_CLK_MANIPULATOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AxiPtmeConfig::disableTxclockManipulator() { + ReturnValue_t result = writeBit(COMMON_CONFIG_REG, false, BitPos::EN_TX_CLK_MANIPULATOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AxiPtmeConfig::enableTxclockInversion() { + ReturnValue_t result = writeBit(COMMON_CONFIG_REG, true, BitPos::INVERT_CLOCK); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AxiPtmeConfig::disableTxclockInversion() { + ReturnValue_t result = writeBit(COMMON_CONFIG_REG, false, BitPos::INVERT_CLOCK); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AxiPtmeConfig::writeReg(uint32_t regOffset, uint32_t writeVal) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + result = mutex->lockMutex(timeoutType, mutexTimeout); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "AxiPtmeConfig::readReg: Failed to lock mutex" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + *(baseAddress + regOffset / ADRESS_DIVIDER) = writeVal; + result = mutex->unlockMutex(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "AxiPtmeConfig::readReg: Failed to unlock mutex" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AxiPtmeConfig::readReg(uint32_t regOffset, uint32_t* readVal) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + result = mutex->lockMutex(timeoutType, mutexTimeout); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "AxiPtmeConfig::readReg: Failed to lock mutex" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + *readVal = *(baseAddress + regOffset / ADRESS_DIVIDER); + result = mutex->unlockMutex(); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "AxiPtmeConfig::readReg: Failed to unlock mutex" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t AxiPtmeConfig::writeBit(uint32_t regOffset, bool bitVal, BitPos bitPos) { + uint32_t readVal = 0; + ReturnValue_t result = readReg(regOffset, &readVal); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + uint32_t writeVal = + (readVal & ~(1 << static_cast(bitPos))) | bitVal << static_cast(bitPos); + result = writeReg(regOffset, writeVal); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/obc/AxiPtmeConfig.h b/linux/obc/AxiPtmeConfig.h new file mode 100644 index 00000000..c86bb429 --- /dev/null +++ b/linux/obc/AxiPtmeConfig.h @@ -0,0 +1,99 @@ +#ifndef LINUX_OBC_AXIPTMECONFIG_H_ +#define LINUX_OBC_AXIPTMECONFIG_H_ + +#include + +#include "fsfw/ipc/MutexIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + +/** + * @brief Class providing low level access to the configuration interface of the PTME. + * + * @author J. Meier + */ +class AxiPtmeConfig : public SystemObject { + public: + /** + * @brief Constructor + * @param axiUio Device file of UIO belonging to the AXI configuration interface. + * @param mapNum Number of map belonging to axi configuration interface. + */ + AxiPtmeConfig(object_id_t objectId, std::string axiUio, int mapNum); + virtual ~AxiPtmeConfig(); + + virtual ReturnValue_t initialize() override; + /** + * @brief Will write to the bitrate configuration register. Actual generated rate depends on + * frequency of the clock connected to the bit clock input of PTME. + */ + ReturnValue_t writeCaduRateReg(uint8_t rateVal); + + /** + * @brief Next to functions control the tx clock manipulator component + * + * @details If the tx clock manipulator is enabled the output clock of the PTME is manipulated + * in a way that both high and low periods in the clock signal have equal lengths. + * The default implementation of the PTME generates a clock where the high level is + * only one bit clock period long. This might be too short to match the setup and hold + * times of the S-and transceiver. + */ + ReturnValue_t enableTxclockManipulator(); + ReturnValue_t disableTxclockManipulator(); + + /** + * @brief The next to functions control whether data will be updated on the rising or falling edge + * of the tx clock. + * Enable inversion will update data on falling edge (not the configuration required by the + * syrlinks) + * Disable clock inversion. Data updated on rising edge. + */ + ReturnValue_t enableTxclockInversion(); + ReturnValue_t disableTxclockInversion(); + + private: + // Address of register storing the bitrate configuration parameter + static const uint32_t CADU_BITRATE_REG = 0x0; + // Address to register storing common configuration parameters + static const uint32_t COMMON_CONFIG_REG = 0x4; + static const uint32_t ADRESS_DIVIDER = 4; + + enum class BitPos : uint32_t { EN_TX_CLK_MANIPULATOR, INVERT_CLOCK }; + + std::string axiUio; + std::string uioMap; + int mapNum = 0; + MutexIF* mutex = nullptr; + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t mutexTimeout = 20; + + uint32_t* baseAddress = nullptr; + + /** + * @brief Function to write to configuration registers + * + * @param writeVal Value to write + */ + ReturnValue_t writeReg(uint32_t regOffset, uint32_t writeVal); + + /** + * @brief Reads value from configuration register + * + * @param regOffset Offset of register from base address to read from + * Qparam readVal Pointer to variable where read value will be written to + */ + ReturnValue_t readReg(uint32_t regOffset, uint32_t* readVal); + + /** + * @brief Sets one bit in a register + * + * @param regOffset Offset of the register where to set the bit + * @param bitVal The value of the bit to set (1 or 0) + * @param bitPos The position of the bit within the register to set + * + * @return RETURN_OK if successful, otherwise RETURN_FAILED + */ + ReturnValue_t writeBit(uint32_t regOffset, bool bitVal, BitPos bitPos); +}; + +#endif /* LINUX_OBC_AXIPTMECONFIG_H_ */ diff --git a/linux/obc/CMakeLists.txt b/linux/obc/CMakeLists.txt index 4119624c..79e32a78 100644 --- a/linux/obc/CMakeLists.txt +++ b/linux/obc/CMakeLists.txt @@ -3,7 +3,8 @@ target_sources(${TARGET_NAME} PUBLIC Ptme.cpp PdecHandler.cpp PdecConfig.cpp - PtmeRateSetter.cpp + PtmeConfig.cpp + AxiPtmeConfig.cpp ) diff --git a/linux/obc/PapbVcInterface.cpp b/linux/obc/PapbVcInterface.cpp index f144306c..5636975a 100644 --- a/linux/obc/PapbVcInterface.cpp +++ b/linux/obc/PapbVcInterface.cpp @@ -1,26 +1,27 @@ +#include #include #include "fsfw/serviceinterface/ServiceInterface.h" -PapbVcInterface::PapbVcInterface(object_id_t objectId, LinuxLibgpioIF* gpioComIF, - gpioId_t papbBusyId, gpioId_t papbEmptyId, uint32_t vcOffset) - : SystemObject(objectId), - gpioComIF(gpioComIF), +PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId, + gpioId_t papbEmptyId, std::string uioFile, int mapNum) + : gpioComIF(gpioComIF), papbBusyId(papbBusyId), papbEmptyId(papbEmptyId), - vcOffset(vcOffset) {} + uioFile(uioFile), + mapNum(mapNum) {} PapbVcInterface::~PapbVcInterface() {} -void PapbVcInterface::setRegisterAddress(uint32_t* ptmeBaseAddress) { - vcBaseReg = ptmeBaseAddress + vcOffset; +ReturnValue_t PapbVcInterface::initialize() { + UioMapper uioMapper(uioFile, mapNum); + return uioMapper.getMappedAdress(&vcBaseReg, UioMapper::Permissions::WRITE_ONLY); } ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { if (pollPapbBusySignal() == RETURN_OK) { startPacketTransfer(); } - for (size_t idx = 0; idx < size; idx++) { if (pollPapbBusySignal() == RETURN_OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(*(data + idx)); @@ -30,7 +31,6 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return RETURN_FAILED; } } - if (pollPapbBusySignal() == RETURN_OK) { endPacketTransfer(); } diff --git a/linux/obc/PapbVcInterface.h b/linux/obc/PapbVcInterface.h index e7d03a70..0d6382e3 100644 --- a/linux/obc/PapbVcInterface.h +++ b/linux/obc/PapbVcInterface.h @@ -5,7 +5,6 @@ #include #include "OBSWConfig.h" -#include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" #include "linux/obc/VcInterfaceIF.h" @@ -15,26 +14,27 @@ * * @author J. Meier */ -class PapbVcInterface : public SystemObject, public VcInterfaceIF, public HasReturnvaluesIF { +class PapbVcInterface : public VcInterfaceIF, public HasReturnvaluesIF { public: /** * @brief Constructor * - * @param objectId * @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 * ready to receive more data. * @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 * 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, - gpioId_t papbEmptyId, uint32_t vcOffset); + PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId, gpioId_t papbEmptyId, + std::string uioFile, int mapNum); virtual ~PapbVcInterface(); ReturnValue_t write(const uint8_t* data, size_t size) override; - void setRegisterAddress(uint32_t* ptmeBaseAddress) override; + ReturnValue_t initialize() override; private: static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE; @@ -69,6 +69,9 @@ class PapbVcInterface : public SystemObject, public VcInterfaceIF, public HasRet /** High when external buffer memory of virtual channel is empty */ gpioId_t papbEmptyId = gpio::NO_GPIO; + std::string uioFile; + int mapNum = 0; + uint32_t* vcBaseReg = nullptr; uint32_t vcOffset = 0; diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index a5ee98d6..f97c3965 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -11,6 +11,7 @@ #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/tmtcservices/TmTcMessage.h" +#include "fsfw_hal/linux/uio/UioMapper.h" PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory, @@ -44,17 +45,18 @@ ReturnValue_t PdecHandler::initialize() { ReturnValue_t result = RETURN_OK; - result = getRegisterAddress(); + UioMapper regMapper(uioRegisters); + result = regMapper.getMappedAdress(®isterBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != RETURN_OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - - result = getConfigMemoryBaseAddress(); + UioMapper configMemMapper(uioConfigMemory); + result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != RETURN_OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - - result = getRamBaseAddress(); + UioMapper ramMapper(uioRamMemory); + result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != RETURN_OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -76,55 +78,6 @@ ReturnValue_t PdecHandler::initialize() { 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( - 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( - 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(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() { PdecConfig pdecConfig; diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index 2125800f..16a9abd4 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -231,25 +231,6 @@ class PdecHandler : public SystemObject, */ 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 * section of the PDEC. diff --git a/linux/obc/Ptme.cpp b/linux/obc/Ptme.cpp index 237e66ab..68ba3924 100644 --- a/linux/obc/Ptme.cpp +++ b/linux/obc/Ptme.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "PtmeConfig.h" #include "fsfw/serviceinterface/ServiceInterface.h" @@ -10,28 +11,10 @@ Ptme::Ptme(object_id_t objectId) : SystemObject(objectId) {} Ptme::~Ptme() {} 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(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; for (iter = vcInterfaceMap.begin(); iter != vcInterfaceMap.end(); iter++) { - iter->second->setRegisterAddress(ptmeBaseAddress); + iter->second->initialize(); } - return RETURN_OK; } diff --git a/linux/obc/Ptme.h b/linux/obc/Ptme.h index d85885bc..cdb2d6c6 100644 --- a/linux/obc/Ptme.h +++ b/linux/obc/Ptme.h @@ -44,14 +44,6 @@ class Ptme : public PtmeIF, public SystemObject, public HasReturnvaluesIF { 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: * bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00 diff --git a/linux/obc/PtmeConfig.cpp b/linux/obc/PtmeConfig.cpp new file mode 100644 index 00000000..9cbda7a6 --- /dev/null +++ b/linux/obc/PtmeConfig.cpp @@ -0,0 +1,50 @@ +#include "PtmeConfig.h" + +#include "fsfw/serviceinterface/ServiceInterface.h" + +PtmeConfig::PtmeConfig(object_id_t objectId, AxiPtmeConfig* axiPtmeConfig) + : SystemObject(objectId), axiPtmeConfig(axiPtmeConfig) {} + +PtmeConfig::~PtmeConfig() {} + +ReturnValue_t PtmeConfig::initialize() { + if (axiPtmeConfig == nullptr) { + sif::warning << "PtmeConfig::initialize: Invalid AxiPtmeConfig object" << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t PtmeConfig::setRate(uint32_t bitRate) { + if (bitRate == 0) { + return BAD_BIT_RATE; + } + uint32_t rateVal = BIT_CLK_FREQ / bitRate - 1; + if (rateVal > 0xFF) { + return RATE_NOT_SUPPORTED; + } + return axiPtmeConfig->writeCaduRateReg(static_cast(rateVal)); +} + +ReturnValue_t PtmeConfig::invertTxClock(bool invert) { + ReturnValue_t result = RETURN_OK; + if (invert) { + result = axiPtmeConfig->enableTxclockInversion(); + } else { + result = axiPtmeConfig->disableTxclockInversion(); + } + if (result != RETURN_OK) { + return CLK_INVERSION_FAILED; + } + return result; +} + +ReturnValue_t PtmeConfig::configTxManipulator(bool enable) { + ReturnValue_t result = RETURN_OK; + if (enable) { + result = axiPtmeConfig->enableTxclockManipulator(); + } else { + result = axiPtmeConfig->disableTxclockManipulator(); + } + return result; +} diff --git a/linux/obc/PtmeConfig.h b/linux/obc/PtmeConfig.h index b5b722ac..d6e35b57 100644 --- a/linux/obc/PtmeConfig.h +++ b/linux/obc/PtmeConfig.h @@ -1,31 +1,76 @@ #ifndef LINUX_OBC_PTMECONFIG_H_ #define LINUX_OBC_PTMECONFIG_H_ -#include - -#include "OBSWConfig.h" +#include "AxiPtmeConfig.h" +#include "fsfw/objectmanager/SystemObject.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "linux/obc/PtmeConfig.h" /** - * @brief PTME specific configuration parameters derived from FPGA design and device tree. + * @brief Class to configure donwlink specific parameters in the PTME IP core. * * @author J. Meier */ -namespace PtmeConfig { -/** - * Offset of virtual channels mapped into address space - * 0x10000 = (0x4000 * 4) - */ -static const uint32_t VC0_OFFSETT = 0; -static const uint32_t VC1_OFFSETT = 0x4000; -static const uint32_t VC2_OFFSETT = 0x8000; -static const uint32_t VC3_OFFSETT = 0xC000; -#if BOARD_TE0720 == 0 -static const char UIO_DEVICE_FILE[] = "/dev/uio1"; -#else -static const char UIO_DEVICE_FILE[] = "/dev/uio1"; -#endif +class PtmeConfig : public SystemObject, public HasReturnvaluesIF { + public: + /** + * @brief Constructor + * + * ptmeAxiConfig Pointer to object providing access to PTME configuration registers. + */ + PtmeConfig(object_id_t opbjectId, AxiPtmeConfig* axiPtmeConfig); + virtual ~PtmeConfig(); -}; // namespace PtmeConfig + virtual ReturnValue_t initialize() override; + /** + * @brief Changes the input frequency to the S-Band transceiver and thus the downlink rate + * + * @details This is the bitrate of the CADU clock and not the downlink which has twice the bitrate + * of the CADU clock due to the convolutional code added by the s-Band transceiver. + */ + ReturnValue_t setRate(uint32_t bitRate); + + /** + * @brief Will change the time the tx data signal is updated with respect to the tx clock + * + * @param invert True -> Data signal will be updated on the falling edge (not desired by the + * Syrlinks) + * False -> Data signal updated on rising edge (default configuration and desired + * by the syrlinks) + * + * @return REUTRN_OK if successful, otherwise error return value + */ + ReturnValue_t invertTxClock(bool invert); + + /** + * @brief Controls the tx clock manipulator of the PTME wrapper component + * + * @param enable Manipulator will be enabled (this is also the default configuration) + * @param disable Manipulator will be disabled + * + * @return REUTRN_OK if successful, otherwise error return value + */ + ReturnValue_t configTxManipulator(bool enable); + + private: + 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); + //! [EXPORT] : [COMMENT] Failed to invert clock and thus change the time the data is updated with + //! respect to the tx clock + static const ReturnValue_t CLK_INVERSION_FAILED = MAKE_RETURN_CODE(0xA2); + //! [EXPORT] : [COMMENT] Failed to change configuration bit of tx clock manipulator + static const ReturnValue_t TX_MANIPULATOR_CONFIG_FAILED = MAKE_RETURN_CODE(0xA3); + + // Bitrate register field is only 8 bit wide + static const uint32_t MAX_BITRATE = 0xFF; + // Bit clock frequency of PMTE IP core in Hz + static const uint32_t BIT_CLK_FREQ = 20000000; + + AxiPtmeConfig* axiPtmeConfig = nullptr; +}; #endif /* LINUX_OBC_PTMECONFIG_H_ */ diff --git a/linux/obc/PtmeRateSetter.cpp b/linux/obc/PtmeRateSetter.cpp deleted file mode 100644 index b5a6ee1c..00000000 --- a/linux/obc/PtmeRateSetter.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "PtmeRateSetter.h" - -#include "fsfw/serviceinterface/ServiceInterface.h" - -PtmeRateSetter::PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif) - : bitrateSel(bitrateSel), gpioif(gpioif) {} - -PtmeRateSetter::~PtmeRateSetter() {} - -ReturnValue_t PtmeRateSetter::setRate(BitRates rate) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - switch (rate) { - case RATE_2000KHZ: - 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; -} diff --git a/linux/obc/PtmeRateSetter.h b/linux/obc/PtmeRateSetter.h deleted file mode 100644 index 14dfec4b..00000000 --- a/linux/obc/PtmeRateSetter.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef LINUX_OBC_PTMERATESETTER_H_ -#define LINUX_OBC_PTMERATESETTER_H_ - -#include "TxRateSetterIF.h" -#include "fsfw/returnvalues/HasReturnvaluesIF.h" -#include "fsfw_hal/common/gpio/GpioIF.h" -#include "fsfw_hal/common/gpio/gpioDefinitions.h" - -/** - * @brief Class to set the downlink bit rate by using the cadu_rate_switcher implemented in - * the programmable logic. - * - * @details The cadu_rate_switcher module sets the input rate to the syrlinks transceiver either - * to 2000 kHz (bitrateSel = 1) or 400 kHz (bitrate = 0). - * - * @author J. Meier - */ -class PtmeRateSetter : public TxRateSetterIF { - public: - /** - * @brief Constructor - * - * @param bitrateSel GPIO ID of the GPIO connected to the bitrate_sel input of the - * cadu_rate_switcher. - * @param gpioif GPIO interface to drive the bitrateSel GPIO - */ - PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif); - virtual ~PtmeRateSetter(); - - virtual ReturnValue_t setRate(BitRates rate); - - private: - gpioId_t bitrateSel = gpio::NO_GPIO; - - GpioIF* gpioif = nullptr; -}; - -#endif /* LINUX_OBC_PTMERATESETTER_H_ */ diff --git a/linux/obc/TxRateSetterIF.h b/linux/obc/TxRateSetterIF.h deleted file mode 100644 index 1eaded33..00000000 --- a/linux/obc/TxRateSetterIF.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef LINUX_OBC_TXRATESETTERIF_H_ -#define LINUX_OBC_TXRATESETTERIF_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 - * downlink bit rate. - * - * @author J. Meier - */ -class TxRateSetterIF { - public: - TxRateSetterIF(){}; - virtual ~TxRateSetterIF(){}; - - virtual ReturnValue_t setRate(BitRates bitRate) = 0; -}; - -#endif /* LINUX_OBC_TXRATESETTERIF_H_ */ diff --git a/linux/obc/VcInterfaceIF.h b/linux/obc/VcInterfaceIF.h index 0aa95691..45226e21 100644 --- a/linux/obc/VcInterfaceIF.h +++ b/linux/obc/VcInterfaceIF.h @@ -24,7 +24,7 @@ class VcInterfaceIF { */ 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_ */ diff --git a/misc/eclipse/.cproject b/misc/eclipse/.cproject index 3bab5367..e2984ed8 100644 --- a/misc/eclipse/.cproject +++ b/misc/eclipse/.cproject @@ -19,10 +19,12 @@ - + @@ -31,6 +33,8 @@ @@ -38,6 +42,8 @@ @@ -79,6 +85,8 @@ @@ -87,6 +95,8 @@ @@ -94,6 +104,8 @@ @@ -137,6 +149,8 @@