diff --git a/README.md b/README.md index 6d38fd66..f0c749be 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debu 1. Install the TCF agent plugin in Eclipse from the [releases](https://www.eclipse.org/tcf/downloads.php). Go to Help → Install New Software and use the download page, for example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it. 2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**. - Here, the Q7S should show up if the local port forwarding was set up as explained previously. + Here, the Q7S should show up if the local port forwarding was set up as explained previously. Please note that you have to connect to `localhost` and port `1534` with port forwaring set up. 3. A launch configuration was provided, but it might be necessary to adapt it for your own needs. Alternatively: @@ -244,7 +244,7 @@ To launch application from Xilinx SDK setup port fowarding on the development ma (not on the flatsat!) ```sh -ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 +ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t bash ``` This forwards any requests to localhost:1534 to the port 1534 of the Q7S with the IP address 192.168.133.10. @@ -266,6 +266,16 @@ Then you can copy an `example` file like this scp -P 1535 example root@localhost:/tmp ``` +Copying a file from Q7S to flatsat PC +```` +scp -P 22 root@192.168.133.10:/tmp/kernel-config /tmp +```` + +From a windows machine files can be copied with putty tools +```` +pscp -scp -P 22 eive@192.168.199.227:/example-file +```` + ## Launching an application at start-up Load the root partiton from the flash memory (there are to nor-flash memories and each flash holds two xdi images). diff --git a/bsp_hosted/fsfwconfig/OBSWVersion.h b/bsp_hosted/fsfwconfig/OBSWVersion.h index e1afa204..980b6965 100644 --- a/bsp_hosted/fsfwconfig/OBSWVersion.h +++ b/bsp_hosted/fsfwconfig/OBSWVersion.h @@ -3,8 +3,8 @@ const char* const SW_NAME = "eive"; -#define SW_VERSION 0 -#define SW_SUBVERSION 2 +#define SW_VERSION 1 +#define SW_SUBVERSION 0 #define SW_SUBSUBVERSION 0 diff --git a/bsp_q7s/InitMission.cpp b/bsp_q7s/InitMission.cpp index e55f9ae9..c776ead0 100644 --- a/bsp_q7s/InitMission.cpp +++ b/bsp_q7s/InitMission.cpp @@ -11,8 +11,7 @@ #include #include #include -#include - +#include #include /* This is configured for linux without CR */ @@ -70,6 +69,7 @@ void initmission::initTasks() { initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); } + /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index b0cd289f..054d59c3 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -18,12 +18,9 @@ #include #include #include -#include #include -#include - - #include + #include #include #include @@ -47,6 +44,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #if TEST_LIBGPIOD == 1 #include #endif @@ -207,10 +211,10 @@ void ObjectFactory::produce(){ SpiCookie* spiRtdIc3 = new SpiCookie(addresses::RTD_IC3, gpioIds::RTD_IC3, std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE, - spi::SpiMode::MODE_1, 2000000); + spi::SpiModes::MODE_1, 2000000); SpiCookie* spiRtdIc4 = new SpiCookie(addresses::RTD_IC4, gpioIds::RTD_IC4, std::string("/dev/spidev2.0"), Max31865Definitions::MAX_REPLY_SIZE, - spi::SpiMode::MODE_1, 2000000); + spi::SpiModes::MODE_1, 2000000); new Max31865PT1000Handler(objects::RTD_IC3, objects::SPI_COM_IF, spiRtdIc3, 0); // 0 is switchId new Max31865PT1000Handler(objects::RTD_IC4, objects::SPI_COM_IF, spiRtdIc4, 0); diff --git a/bsp_q7s/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp index ccf5b65c..9a44c57b 100644 --- a/bsp_q7s/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -201,8 +201,8 @@ void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) { heaterMapIter->second.active = false; heaterMapIter->second.waitMainSwitchOn = false; if (heaterMapIter->second.replyQueue != commandQueue->getId()) { - actionHelper.finish(heaterMapIter->second.replyQueue, heaterMapIter->second.action, - MAIN_SWITCH_SET_TIMEOUT ); + actionHelper.finish(false, heaterMapIter->second.replyQueue, + heaterMapIter->second.action, MAIN_SWITCH_SET_TIMEOUT ); } return; } @@ -229,8 +229,15 @@ void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) { /* There is no need to send action finish replies if the sender was the * HeaterHandler itself. */ if (heaterMapIter->second.replyQueue != commandQueue->getId()) { - actionHelper.finish(heaterMapIter->second.replyQueue, - heaterMapIter->second.action, result); + if(result == RETURN_OK) { + actionHelper.finish(true, heaterMapIter->second.replyQueue, + heaterMapIter->second.action, result); + } + else { + actionHelper.finish(false, heaterMapIter->second.replyQueue, + heaterMapIter->second.action, result); + } + } heaterMapIter->second.active = false; heaterMapIter->second.waitMainSwitchOn = false; @@ -250,7 +257,7 @@ void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) { sif::debug << "HeaterHandler::handleActiveCommands: Failed to get state of" << " main line switch" << std::endl; if (heaterMapIter->second.replyQueue != commandQueue->getId()) { - actionHelper.finish(heaterMapIter->second.replyQueue, + actionHelper.finish(false, heaterMapIter->second.replyQueue, heaterMapIter->second.action, mainSwitchState); } heaterMapIter->second.active = false; @@ -282,8 +289,15 @@ void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) { triggerEvent(SWITCH_ALREADY_OFF, switchNr); } if (heaterMapIter->second.replyQueue != NO_COMMANDER) { - actionHelper.finish(heaterMapIter->second.replyQueue, - heaterMapIter->second.action, result); + /* Report back switch command reply if necessary */ + if(result == HasReturnvaluesIF::RETURN_OK) { + actionHelper.finish(true, heaterMapIter->second.replyQueue, + heaterMapIter->second.action, result); + } + else { + actionHelper.finish(false, heaterMapIter->second.replyQueue, + heaterMapIter->second.action, result); + } } heaterMapIter->second.active = false; } diff --git a/bsp_q7s/devices/SolarArrayDeploymentHandler.cpp b/bsp_q7s/devices/SolarArrayDeploymentHandler.cpp index 80d941bf..d307ef15 100644 --- a/bsp_q7s/devices/SolarArrayDeploymentHandler.cpp +++ b/bsp_q7s/devices/SolarArrayDeploymentHandler.cpp @@ -108,7 +108,7 @@ void SolarArrayDeploymentHandler::performWaitOn8VActions() { } else { if (mainSwitchCountdown.hasTimedOut()) { triggerEvent(MAIN_SWITCH_ON_TIMEOUT); - actionHelper.finish(rememberCommanderId, DEPLOY_SOLAR_ARRAYS, + actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, MAIN_SWITCH_TIMEOUT_FAILURE); stateMachine = WAIT_ON_DELOYMENT_COMMAND; } @@ -125,7 +125,7 @@ void SolarArrayDeploymentHandler::switchDeploymentTransistors() { * the deployment sequence. */ stateMachine = WAIT_ON_DELOYMENT_COMMAND; triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); - actionHelper.finish(rememberCommanderId, DEPLOY_SOLAR_ARRAYS, + actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); } @@ -135,7 +135,7 @@ void SolarArrayDeploymentHandler::switchDeploymentTransistors() { " array deployment switch 2 high " << std::endl; stateMachine = WAIT_ON_DELOYMENT_COMMAND; triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); - actionHelper.finish(rememberCommanderId, DEPLOY_SOLAR_ARRAYS, + actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); } @@ -146,7 +146,7 @@ void SolarArrayDeploymentHandler::switchDeploymentTransistors() { void SolarArrayDeploymentHandler::handleDeploymentFinish() { ReturnValue_t result = RETURN_OK; if (deploymentCountdown.hasTimedOut()) { - actionHelper.finish(rememberCommanderId, DEPLOY_SOLAR_ARRAYS, RETURN_OK); + actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, RETURN_OK); result = gpioInterface->pullLow(deplSA1); if (result != RETURN_OK) { sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" diff --git a/bsp_rpi/InitMission.cpp b/bsp_rpi/InitMission.cpp index ce2a5940..091f6bbd 100644 --- a/bsp_rpi/InitMission.cpp +++ b/bsp_rpi/InitMission.cpp @@ -3,8 +3,11 @@ #include #include +<<<<<<< HEAD #include +======= +>>>>>>> develop #include #include @@ -14,6 +17,10 @@ #include #include #include +<<<<<<< HEAD +======= +#include +>>>>>>> develop #include @@ -117,6 +124,8 @@ void initmission::initTasks() { result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); +<<<<<<< HEAD +======= } PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( @@ -126,6 +135,24 @@ void initmission::initTasks() { initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); } +#if RPI_TEST_ACS_BOARD == 1 + FixedTimeslotTaskIF* acsTask = factory->createFixedTimeslotTask( + "ACS_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 1.0, missedDeadlineFunc); + result = pst::pollingSequenceAcsTest(acsTask); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "initmission::initTasks: ACS PST initialization failed!" << std::endl; +>>>>>>> develop + } +#endif /* RPI_TEST_ACS_BOARD == 1 */ + +<<<<<<< HEAD + PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + } + #if RPI_TEST_ACS_BOARD == 1 FixedTimeslotTaskIF* acsTask = factory->createFixedTimeslotTask( "ACS_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc); @@ -161,6 +188,34 @@ void initmission::initTasks() { udpBridgeTask->startTask(); udpPollingTask->startTask(); +======= + PeriodicTaskIF* testTask = factory->createPeriodicTask( + "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); +#if OBSW_ADD_TEST_CODE == 1 + result = testTask->addComponent(objects::TEST_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } +#endif /* OBSW_ADD_TEST_CODE == 1 */ +#if RPI_ADD_SPI_TEST == 1 + result = testTask->addComponent(objects::SPI_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST); + } +#endif /* RPI_ADD_SPI_TEST == 1 */ +#if RPI_ADD_GPIO_TEST == 1 + result = testTask->addComponent(objects::LIBGPIOD_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); + } +#endif /* RPI_ADD_GPIO_TEST == 1 */ + + sif::info << "Starting tasks.." << std::endl; + tmTcDistributor->startTask(); + udpBridgeTask->startTask(); + udpPollingTask->startTask(); + +>>>>>>> develop pusVerification->startTask(); pusEvents->startTask(); pusHighPrio->startTask(); diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 3e6eeaa2..7cbca5f0 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -1,5 +1,6 @@ #include "ObjectFactory.h" #include +<<<<<<< HEAD #include #include @@ -19,6 +20,29 @@ #include #include +======= + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +>>>>>>> develop #include #include #include @@ -26,7 +50,12 @@ #include #include #include +<<<<<<< HEAD #include +======= +#include + +>>>>>>> develop void Factory::setStaticFrameworkObjectIds() { PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; @@ -96,12 +125,34 @@ void ObjectFactory::produce(){ gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_2_L3G_CS, gpio::GYRO_2_BCM_PIN, "GYRO_2_L3G", gpio::Direction::OUT, 1); gpioIF->addGpios(gpioCookieAcsBoard); +<<<<<<< HEAD SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, "/dev/spidev0.0", 24, spi::SpiMode::MODE_3, 3'900'000); auto mgmHandler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie); mgmHandler->setStartUpImmediately(); +======= + + std::string spiDev = "/dev/spidev0.0"; + SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, + MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED); + auto mgmLis3Handler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER, + objects::SPI_COM_IF, spiCookie); + mgmLis3Handler->setStartUpImmediately(); + + spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev, + RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED); + auto mgmRm3100Handler = new MGMHandlerRM3100(objects::MGM_1_RM3100_HANDLER, + objects::SPI_COM_IF, spiCookie); + mgmRm3100Handler->setStartUpImmediately(); + + spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev, + L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED); + auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, + spiCookie); + gyroL3gHandler->setStartUpImmediately(); +>>>>>>> develop #endif /* RPI_TEST_ACS_BOARD == 1 */ } diff --git a/bsp_rpi/boardconfig/rpi_config.h b/bsp_rpi/boardconfig/rpi_config.h index d1acacb6..a9f4fd9f 100644 --- a/bsp_rpi/boardconfig/rpi_config.h +++ b/bsp_rpi/boardconfig/rpi_config.h @@ -8,7 +8,7 @@ /* Only one of those 2 should be enabled! */ #define RPI_ADD_SPI_TEST 0 -#define RPI_TEST_ACS_BOARD 1 +#define RPI_TEST_ACS_BOARD 0 /* Adapt these values accordingly */ namespace gpio { diff --git a/cmake/scripts/Host/create_cmake_release_cfg.sh b/cmake/scripts/Host/create_cmake_release_cfg.sh index 03378e98..19ae5b32 100644 --- a/cmake/scripts/Host/create_cmake_release_cfg.sh +++ b/cmake/scripts/Host/create_cmake_release_cfg.sh @@ -16,7 +16,7 @@ fi build_generator="" os_fsfw="host" -build_dir="Debug-Release" +build_dir="Release-Host" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" # Could be other OS but this works for now. diff --git a/cmake/scripts/Linux/create_cmake_debug_cfg.sh b/cmake/scripts/Linux/create_cmake_debug_cfg.sh index 5dff0fc7..1f75c12a 100755 --- a/cmake/scripts/Linux/create_cmake_debug_cfg.sh +++ b/cmake/scripts/Linux/create_cmake_debug_cfg.sh @@ -16,5 +16,10 @@ fi build_generator="Unix Makefiles" os_fsfw="linux" +builddir="Debug-Linux" -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" +echo "Running command (without the leading +):" +set -x # Print command +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/Linux/create_cmake_release_cfg.sh b/cmake/scripts/Linux/create_cmake_release_cfg.sh index 914c4581..ffd85ae7 100755 --- a/cmake/scripts/Linux/create_cmake_release_cfg.sh +++ b/cmake/scripts/Linux/create_cmake_release_cfg.sh @@ -16,5 +16,10 @@ fi build_generator="Unix Makefiles" os_fsfw="linux" +builddir="Release-Linux" -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" +echo "Running command (without the leading +):" +set -x # Print command +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/Linux/create_cmake_relwithdeb_cfg.sh b/cmake/scripts/Linux/create_cmake_relwithdeb_cfg.sh index 3414d111..31376322 100755 --- a/cmake/scripts/Linux/create_cmake_relwithdeb_cfg.sh +++ b/cmake/scripts/Linux/create_cmake_relwithdeb_cfg.sh @@ -16,5 +16,10 @@ fi build_generator="Unix Makefiles" os_fsfw="linux" +builddir="RelWithDeb-Linux" -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "reldeb" +echo "Running command (without the leading +):" +set -x # Print command +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/Q7S/create_cmake_debug_cfg.sh b/cmake/scripts/Q7S/create_cmake_debug_cfg.sh old mode 100644 new mode 100755 diff --git a/cmake/scripts/Q7S/create_cmake_release_cfg.sh b/cmake/scripts/Q7S/create_cmake_release_cfg.sh old mode 100644 new mode 100755 diff --git a/cmake/scripts/Q7S/create_cmake_relwithdeb_cfg.sh b/cmake/scripts/Q7S/create_cmake_relwithdeb_cfg.sh old mode 100644 new mode 100755 diff --git a/cmake/scripts/RPi/create_cmake_debug_cfg.sh b/cmake/scripts/RPi/create_cmake_debug_cfg.sh old mode 100644 new mode 100755 diff --git a/cmake/scripts/RPi/create_cmake_release_cfg.sh b/cmake/scripts/RPi/create_cmake_release_cfg.sh old mode 100644 new mode 100755 diff --git a/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh b/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh old mode 100644 new mode 100755 diff --git a/cmake/scripts/RPi/create_cmake_size_cfg.sh b/cmake/scripts/RPi/create_cmake_size_cfg.sh old mode 100644 new mode 100755 diff --git a/fsfwconfig/CMakeLists.txt b/fsfwconfig/CMakeLists.txt index 897789ef..87ddea03 100644 --- a/fsfwconfig/CMakeLists.txt +++ b/fsfwconfig/CMakeLists.txt @@ -1,6 +1,6 @@ target_sources(${TARGET_NAME} PRIVATE ipc/MissionMessageTypes.cpp - pollingsequence/PollingSequenceFactory.cpp + pollingsequence/pollingSequenceFactory.cpp ) target_include_directories(${TARGET_NAME} PUBLIC diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 5a9106b5..05ad0fe9 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -25,10 +25,15 @@ debugging. */ #define PDU1_DEBUG 0 #define PDU2_DEBUG 0 #define ACU_DEBUG 0 -#define SYRLINKS_DEBUG 1 +#define SYRLINKS_DEBUG 0 #include "OBSWVersion.h" +/* Can be used to switch device to NORMAL mode immediately */ +#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1 +/* Can be used for low-level debugging of the SPI bus */ +#define FSFW_LINUX_SPI_WIRETAPPING 0 + #ifdef __cplusplus #include "objects/systemObjectList.h" diff --git a/fsfwconfig/devices/spi.h b/fsfwconfig/devices/spi.h new file mode 100644 index 00000000..7085aa4d --- /dev/null +++ b/fsfwconfig/devices/spi.h @@ -0,0 +1,27 @@ +#ifndef FSFWCONFIG_DEVICES_SPI_H_ +#define FSFWCONFIG_DEVICES_SPI_H_ + +#include +#include + +/** + * SPI configuration will be contained here to let the device handlers remain independent + * of SPI specific properties. + */ +namespace spi { + +/* Default values, changing them is not supported for now */ +static constexpr uint32_t DEFAULT_LIS3_SPEED = 3'900'000; +static constexpr spi::SpiModes DEFAULT_LIS3_MODE = spi::SpiModes::MODE_3; + +static constexpr uint32_t DEFAULT_RM3100_SPEED = 976'000; +static constexpr spi::SpiModes DEFAULT_RM3100_MODE = spi::SpiModes::MODE_3; + +static constexpr uint32_t DEFAULT_L3G_SPEED = 3'900'000; +static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3; + +} + + + +#endif /* FSFWCONFIG_DEVICES_SPI_H_ */ diff --git a/fsfwconfig/objects/systemObjectList.h b/fsfwconfig/objects/systemObjectList.h index 8bbd9c2d..9787fc0d 100644 --- a/fsfwconfig/objects/systemObjectList.h +++ b/fsfwconfig/objects/systemObjectList.h @@ -43,7 +43,6 @@ namespace objects { ACU_HANDLER = 0x44000004, TMP1075_HANDLER_1 = 0x44000005, TMP1075_HANDLER_2 = 0x44000006, - MGM_0_LIS3_HANDLER = 0x4400007, MGM_1_RM3100_HANDLER = 0x44000008, MGM_2_LIS3_HANDLER = 0x44000009, diff --git a/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp b/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp similarity index 83% rename from fsfwconfig/pollingsequence/PollingSequenceFactory.cpp rename to fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index abc614c0..04b1367b 100644 --- a/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp +++ b/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -1,9 +1,11 @@ +#include "pollingSequenceFactory.h" + #include #include #include #include #include -#include + ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) { @@ -14,27 +16,21 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::HEATER_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::SOLAR_ARRAY_DEPL_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) { return HasReturnvaluesIF::RETURN_OK; @@ -115,6 +111,28 @@ ReturnValue_t pst::pollingSequenceAcsTest(FixedTimeslotTaskIF *thisSequence) { DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.2, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.4, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.6, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.8, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0.2, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0.4, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0.6, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0.8, + DeviceHandlerIF::GET_READ); if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) { sif::error << "Initialization of ACS Board PST failed" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; diff --git a/fsfwconfig/pollingsequence/PollingSequenceFactory.h b/fsfwconfig/pollingsequence/pollingSequenceFactory.h similarity index 99% rename from fsfwconfig/pollingsequence/PollingSequenceFactory.h rename to fsfwconfig/pollingsequence/pollingSequenceFactory.h index 4003058b..09dd7242 100644 --- a/fsfwconfig/pollingsequence/PollingSequenceFactory.h +++ b/fsfwconfig/pollingsequence/pollingSequenceFactory.h @@ -1,5 +1,6 @@ #ifndef POLLINGSEQUENCEFACTORY_H_ #define POLLINGSEQUENCEFACTORY_H_ + #include class FixedTimeslotTaskIF; diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 2f68bea0..898fc748 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -1,14 +1,19 @@ #include "SpiTestClass.h" #include -#include -#include -#include +#include +#include +#include #include + #include #include #include + +#include +#include + #include #include #include @@ -19,7 +24,7 @@ SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objec if(gpioIF == nullptr) { sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl; } - testMode = TestModes::MGM_LIS3MDL; + testMode = TestModes::GYRO_L3GD20H; spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data()); spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data()); } @@ -38,6 +43,7 @@ ReturnValue_t SpiTestClass::performOneShotAction() { break; } case(TestModes::GYRO_L3GD20H): { + performL3gTest(gyro1L3gd20ChipSelect); break; } } @@ -64,10 +70,10 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { else { currentGpioId = gpioIds::MGM_3_RM3100_CS; } - uint32_t rm3100speed = 3'900'000; + uint32_t rm3100speed = 976'000; uint8_t rm3100revidReg = 0x36; - spi::SpiMode rm3100mode = spi::SpiMode::MODE_3; - //spiTransferStruct.speed_hz = rm3100Speed; + spi::SpiModes rm3100mode = spi::SpiModes::MODE_3; + #ifdef RASPBERRY_PI std::string deviceName = "/dev/spidev0.0"; #else @@ -85,9 +91,67 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { } setSpiSpeedAndMode(fileDescriptor, rm3100mode, rm3100speed); - uint8_t revId = readStmRegister(fileDescriptor, currentGpioId, rm3100revidReg, false); + uint8_t revId = readRegister(fileDescriptor, currentGpioId, rm3100revidReg); sif::info << "SpiTestClass::performRm3100Test: Revision ID 0b" << std::bitset<8>(revId) << std::endl; + + /* Write configuration to CMM register */ + writeRegister(fileDescriptor, currentGpioId, 0x01, 0x75); + uint8_t cmmRegister = readRm3100Register(fileDescriptor , currentGpioId, 0x01); + sif::info << "SpiTestClass::performRm3100Test: CMM register value: " << + std::hex << "0x" << static_cast(cmmRegister) << std::dec << std::endl; + + /* Read the cycle count registers */ + uint8_t cycleCountsRaw[6]; + readMultipleRegisters(fileDescriptor, currentGpioId, 0x04, cycleCountsRaw, 6); + + uint16_t cycleCountX = cycleCountsRaw[0] << 8 | cycleCountsRaw[1]; + uint16_t cycleCountY = cycleCountsRaw[2] << 8 | cycleCountsRaw[3]; + uint16_t cycleCountZ = cycleCountsRaw[4] << 8 | cycleCountsRaw[5]; + + sif::info << "Cycle count X: " << cycleCountX << std::endl; + sif::info << "Cycle count Y: " << cycleCountY << std::endl; + sif::info << "Cycle count z: " << cycleCountZ << std::endl; + + writeRegister(fileDescriptor, currentGpioId, 0x0B, 0x95); + uint8_t tmrcReg = readRm3100Register(fileDescriptor, currentGpioId, 0x0B); + sif::info << "SpiTestClass::performRm3100Test: TMRC register value: " << + std::hex << "0x" << static_cast(tmrcReg) << std::dec << std::endl; + + TaskFactory::delayTask(10); + uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34); + sif::info << "SpiTestClass::performRm3100Test: Status Register 0b" << + std::bitset<8>(statusReg) << std::endl; + /* This means that data is not ready */ + if((statusReg & 0b1000'0000) == 0) { + sif::warning << "SpiTestClass::performRm3100Test: Data not ready!" << std::endl; + TaskFactory::delayTask(10); + uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34); + if((statusReg & 0b1000'0000) == 0) { + return; + } + } + + uint32_t rm3100DefaultCycleCout = 0xC8; + /* Gain scales lineary with cycle count and is 38 for cycle count 100 */ + float rm3100Gain = rm3100DefaultCycleCout / 100.0 * 38.0; + float scaleFactor = 1 / rm3100Gain; + uint8_t rawValues[9]; + readMultipleRegisters(fileDescriptor, currentGpioId, 0x24, rawValues, 9); + + /* The sensor generates 24 bit signed values */ + int32_t rawX = ((rawValues[0] << 24) | (rawValues[1] << 16) | (rawValues[2] << 8)) >> 8; + int32_t rawY = ((rawValues[3] << 24) | (rawValues[4] << 16) | (rawValues[5] << 8)) >> 8; + int32_t rawZ = ((rawValues[6] << 24) | (rawValues[7] << 16) | (rawValues[8] << 8)) >> 8; + + float fieldStrengthX = rawX * scaleFactor; + float fieldStrengthY = rawY * scaleFactor; + float fieldStrengthZ = rawZ * scaleFactor; + + sif::info << "RM3100 measured field strenghts in microtesla:" << std::endl; + sif::info << "Field Strength X: " << fieldStrengthX << " \xC2\xB5T" << std::endl; + sif::info << "Field Strength Y: " << fieldStrengthY << " \xC2\xB5T" << std::endl; + sif::info << "Field Strength Z: " << fieldStrengthZ << " \xC2\xB5T" << std::endl; } void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) { @@ -108,7 +172,7 @@ void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) { currentGpioId = gpioIds::MGM_2_LIS3_CS; } uint32_t spiSpeed = 3'900'000; - spi::SpiMode spiMode = spi::SpiMode::MODE_3; + spi::SpiModes spiMode = spi::SpiModes::MODE_3; #ifdef RASPBERRY_PI std::string deviceName = "/dev/spidev0.0"; #else @@ -126,11 +190,106 @@ void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) { setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false); - sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I Regiter 0b" << + sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b" << std::bitset<8>(whoAmIRegVal) << std::endl; + } +void SpiTestClass::performL3gTest(uint8_t l3gId) { + /* Configure all SPI chip selects and pull them high */ + acsInit(); + + l3gId = gyro2L3gd20ChipSelect; + + /* Adapt accordingly */ + if(l3gId != gyro1L3gd20ChipSelect and l3gId != gyro2L3gd20ChipSelect) { + sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl; + } + gpioId_t currentGpioId = 0; + uint8_t chipSelectPin = l3gId; + uint8_t whoAmIReg = 0b0000'1111; + uint8_t whoAmIRegExpectedVal = 0b1101'0111; + + if(chipSelectPin == gyro1L3gd20ChipSelect) { + currentGpioId = gpioIds::GYRO_1_L3G_CS; + } + else { + currentGpioId = gpioIds::GYRO_2_L3G_CS; + } + uint32_t spiSpeed = 3'900'000; + spi::SpiModes spiMode = spi::SpiModes::MODE_3; +#ifdef RASPBERRY_PI + std::string deviceName = "/dev/spidev0.0"; +#else + std::string deviceName = "placeholder"; +#endif + int fileDescriptor = 0; + + utility::UnixFileHelper fileHelper(deviceName, &fileDescriptor, O_RDWR, + "SpiComIF::initializeInterface: "); + if(fileHelper.getOpenResult()) { + sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!" + << std::endl; + return; + } + setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); + uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false); + sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b" << + std::bitset<8>(whoAmIRegVal) << std::endl; + if(whoAmIRegVal != whoAmIRegExpectedVal) { + sif::warning << "SpiTestClass::performL3gTest: Read WHO AM I register invalid!" << + std::endl; + } + + uint8_t ctrlReg1Addr = 0b0010'0000; + { + uint8_t commandRegs[5]; + commandRegs[0] = 0b0000'1111; + commandRegs[1] = 0x0; + commandRegs[2] = 0x0; + /* Configure big endian data format */ + commandRegs[3] = 0b0100'0000; + commandRegs[4] = 0x0; + writeMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, commandRegs, + sizeof(commandRegs)); + uint8_t readRegs[5]; + readMultipleRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readRegs, + sizeof(readRegs)); + for(uint8_t idx = 0; idx < sizeof(readRegs); idx++) { + if(readRegs[idx] != commandRegs[0]) { + sif::warning << "SpiTestClass::performL3gTest: Read control register" << + static_cast(idx + 1) << "not equal to configured value" << std::endl; + } + } + } + + uint8_t readOutBuffer[14]; + readMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readOutBuffer, + sizeof(readOutBuffer)); + + uint8_t statusReg = readOutBuffer[7]; + sif::info << "SpiTestClass::performL3gTest: Status Register 0b" << + std::bitset<8>(statusReg) << std::endl; + + uint16_t l3gRange = 245; + float scaleFactor = static_cast(l3gRange) / INT16_MAX; + /* The sensor spits out little endian */ + int16_t angVelocRawX = (readOutBuffer[8] << 8) | readOutBuffer[9]; + int16_t angVelocRawY = (readOutBuffer[10] << 8) | readOutBuffer[11]; + int16_t angVelocRawZ = (readOutBuffer[12] << 8) | readOutBuffer[13]; + + float angVelocX = scaleFactor * angVelocRawX; + float angVelocY = scaleFactor * angVelocRawY; + float angVelocZ = scaleFactor * angVelocRawZ; + + sif::info << "Angular velocities for the L3GD20H in degrees per second:" << std::endl; + sif::info << "X: " << angVelocX << std::endl; + sif::info << "Y: " << angVelocY << std::endl; + sif::info << "Z: " << angVelocZ << std::endl; + +} + void SpiTestClass::acsInit() { GpioCookie* gpioCookie = new GpioCookie(); std::string rpiGpioName = "gpiochip0"; @@ -174,29 +333,9 @@ void SpiTestClass::acsInit() { } } -void SpiTestClass::writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value, - bool autoIncrement) { - if(autoIncrement) { - reg |= STM_AUTO_INCR_MASK; - } - spiTransferStruct.len = 2; - sendBuffer[0] = reg; - sendBuffer[1] = value; - - if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { - gpioIF->pullLow(chipSelect); - } - int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); - if(retval != 0) { - utility::handleIoctlError("SpiTestClass::writeStmRegister: Write failed"); - } - if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { - gpioIF->pullHigh(chipSelect); - } -} - -void SpiTestClass::setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t speed) { - int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast(&mode)); +void SpiTestClass::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) { + int mode_test = SPI_MODE_3; + int retval = ioctl(spiFd, SPI_IOC_WR_MODE, &mode_test);//reinterpret_cast(&mode)); if(retval != 0) { utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); } @@ -207,12 +346,114 @@ void SpiTestClass::setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t spe } } +void SpiTestClass::writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value) { + spiTransferStruct.len = 2; + sendBuffer[0] = reg; + sendBuffer[1] = value; + + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullLow(chipSelect); + } + int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); + if(retval < 0) { + utility::handleIoctlError("SpiTestClass::writeRegister: Write failed"); + } + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullHigh(chipSelect); + } +} + +void SpiTestClass::writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value, + bool autoIncrement) { + if(autoIncrement) { + reg |= STM_AUTO_INCR_MASK; + } + writeRegister(fd, chipSelect, reg, value); +} + +void SpiTestClass::writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, + uint8_t *values, size_t len) { + if(values == nullptr) { + return; + } + + reg |= STM_AUTO_INCR_MASK; + /* Clear read mask */ + reg &= ~STM_READ_MASK; + writeMultipleRegisters(fd, chipSelect, reg, values, len); + +} + +void SpiTestClass::writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, + uint8_t *values, size_t len) { + if(values == nullptr) { + return; + } + + sendBuffer[0] = reg; + std::memcpy(sendBuffer.data() + 1, values, len); + spiTransferStruct.len = len + 1; + + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullLow(chipSelect); + } + int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); + if(retval < 0) { + utility::handleIoctlError("SpiTestClass::readRegister: Read failed"); + } + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullHigh(chipSelect); + } +} + +uint8_t SpiTestClass::readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg) { + return readStmRegister(fd, chipSelect, reg, false); +} + + +void SpiTestClass::readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply, + size_t len) { + reg |= STM_AUTO_INCR_MASK; + readMultipleRegisters(fd, chipSelect, reg, reply, len); +} + +void SpiTestClass::readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply, + size_t len) { + if(reply == nullptr) { + return; + } + + spiTransferStruct.len = len + 1; + sendBuffer[0] = reg | STM_READ_MASK; + + for(uint8_t idx = 0; idx < len ; idx ++) { + sendBuffer[idx + 1] = 0; + } + + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullLow(chipSelect); + } + int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); + if(retval < 0) { + utility::handleIoctlError("SpiTestClass::readRegister: Read failed"); + } + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullHigh(chipSelect); + } + std::memcpy(reply, recvBuffer.data() + 1, len); +} + uint8_t SpiTestClass::readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, bool autoIncrement) { reg |= STM_READ_MASK; if(autoIncrement) { reg |= STM_AUTO_INCR_MASK; } + return readRegister(fd, chipSelect, reg); +} + + +uint8_t SpiTestClass::readRegister(int fd, gpioId_t chipSelect, uint8_t reg) { spiTransferStruct.len = 2; sendBuffer[0] = reg; sendBuffer[1] = 0; @@ -222,7 +463,7 @@ uint8_t SpiTestClass::readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, } int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); if(retval < 0) { - utility::handleIoctlError("SpiTestClass::readStmRegiste: Read failed"); + utility::handleIoctlError("SpiTestClass::readRegister: Read failed"); } if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { gpioIF->pullHigh(chipSelect); diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index 61c2d2b2..c567bc45 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -28,10 +28,11 @@ private: std::array recvBuffer; std::array sendBuffer; - struct spi_ioc_transfer spiTransferStruct; + struct spi_ioc_transfer spiTransferStruct = {}; void performRm3100Test(uint8_t mgmId); void performLis3MdlTest(uint8_t lis3Id); + void performL3gTest(uint8_t l3gId); /* ACS board specific code which pulls all GPIOs high */ void acsInit(); @@ -46,12 +47,26 @@ private: uint8_t mgm3Rm3100ChipSelect = 27; static constexpr uint8_t STM_READ_MASK = 0b1000'0000; + static constexpr uint8_t RM3100_READ_MASK = STM_READ_MASK; static constexpr uint8_t STM_AUTO_INCR_MASK = 0b0100'0000; - void setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t speed); + void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed); + void writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value, bool autoIncrement); + void writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* values, + size_t len); + void writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *values, + size_t len); + void writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value); + + uint8_t readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg); uint8_t readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, bool autoIncrement); + uint8_t readRegister(int fd, gpioId_t chipSelect, uint8_t reg); + void readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply, + size_t len); + void readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, + uint8_t* reply, size_t len); }; diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index eef44126..b94e1249 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -1,10 +1,11 @@ #include "SpiComIF.h" +#include #include #include #include -#include +#include #include #include @@ -78,7 +79,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { } size_t spiSpeed = 0; - spi::SpiMode spiMode = spi::SpiMode::MODE_0; + spi::SpiModes spiMode = spi::SpiModes::MODE_0; SpiCookie::UncommonParameters params; spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms); @@ -162,7 +163,7 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return OPENING_FILE_FAILED; } - spi::SpiMode spiMode = spi::SpiMode::MODE_0; + spi::SpiModes spiMode = spi::SpiModes::MODE_0; uint32_t spiSpeed = 0; spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr); setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); @@ -173,7 +174,7 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s gpioId_t gpioId = spiCookie->getChipSelectPin(); /* GPIO access is mutex protected */ - MutexHelper(spiMutex, timeoutType, timeoutMs); + MutexGuard(spiMutex, timeoutType, timeoutMs); /* Pull SPI CS low. For now, no support for active high given */ if(gpioId != gpio::NO_GPIO) { @@ -188,6 +189,18 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); result = FULL_DUPLEX_TRANSFER_FAILED; } +#if FSFW_LINUX_SPI_WIRETAPPING == 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Sent SPI data: " << std::endl; + size_t dataLen = spiCookie->getTransferStructHandle()->len; + uint8_t* dataPtr = reinterpret_cast(spiCookie->getTransferStructHandle()->tx_buf); + arrayprinter::print(dataPtr, dataLen, OutputType::HEX, false); + sif::info << "Received SPI data: " << std::endl; + dataPtr = reinterpret_cast(spiCookie->getTransferStructHandle()->rx_buf); + arrayprinter::print(dataPtr, dataLen, OutputType::HEX, false); +#else +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */ } else { /* We write with a blocking half-duplex transfer here */ @@ -242,7 +255,7 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe } gpioId_t gpioId = spiCookie->getChipSelectPin(); - MutexHelper(spiMutex, timeoutType, timeoutMs); + MutexGuard(spiMutex, timeoutType, timeoutMs); if(gpioId != gpio::NO_GPIO) { gpioComIF->pullLow(gpioId); } @@ -295,7 +308,7 @@ ReturnValue_t SpiComIF::getReadBuffer(address_t spiAddress, uint8_t** buffer) { return HasReturnvaluesIF::RETURN_OK; } -void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t speed) { +void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) { int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast(&mode)); if(retval != 0) { utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h index cbcaa4e0..0e27a595 100644 --- a/linux/spi/SpiComIF.h +++ b/linux/spi/SpiComIF.h @@ -57,7 +57,7 @@ private: ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); - void setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t speed); + void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed); }; #endif /* LINUX_SPI_SPICOMIF_H_ */ diff --git a/linux/spi/SpiCookie.cpp b/linux/spi/SpiCookie.cpp index f0b81f67..91117682 100644 --- a/linux/spi/SpiCookie.cpp +++ b/linux/spi/SpiCookie.cpp @@ -1,17 +1,17 @@ #include "SpiCookie.h" SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, - const size_t maxSize, spi::SpiMode spiMode, uint32_t spiSpeed): spiAddress(spiAddress), + const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed): spiAddress(spiAddress), chipSelectPin(chipSelect), spiDevice(spiDev), maxSize(maxSize), spiMode(spiMode), spiSpeed(spiSpeed) { } SpiCookie::SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxSize, - spi::SpiMode spiMode, uint32_t spiSpeed): + spi::SpiModes spiMode, uint32_t spiSpeed): SpiCookie(spiAddress, gpio::NO_GPIO, spiDev, maxSize, spiMode, spiSpeed) { } -void SpiCookie::getSpiParameters(spi::SpiMode& spiMode, uint32_t& spiSpeed, +void SpiCookie::getSpiParameters(spi::SpiModes& spiMode, uint32_t& spiSpeed, UncommonParameters* parameters) const { spiMode = this->spiMode; spiSpeed = this->spiSpeed; @@ -97,3 +97,11 @@ void SpiCookie::assignTransferSize(size_t transferSize) { size_t SpiCookie::getCurrentTransferSize() const { return spiTransferStruct.len; } + +void SpiCookie::setSpiSpeed(uint32_t newSpeed) { + this->spiSpeed = newSpeed; +} + +void SpiCookie::setSpiMode(spi::SpiModes newMode) { + this->spiMode = newMode; +} diff --git a/linux/spi/SpiCookie.h b/linux/spi/SpiCookie.h index 1efbc0bd..59d0e206 100644 --- a/linux/spi/SpiCookie.h +++ b/linux/spi/SpiCookie.h @@ -17,22 +17,27 @@ public: * @param chipSelect Chip select. gpio::NO_GPIO can be used for hardware slave selects. * @param spiDev * @param maxSize - * @param spieSpeed SPI clock frequency in Hz. */ SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, - const size_t maxReplySize, spi::SpiMode spiMode, uint32_t spiSpeed); + const size_t maxReplySize, spi::SpiModes spiMode, uint32_t spiSpeed); /** * Like constructor above, but without a dedicated GPIO CS. Can be used for hardware * slave select or if CS logic is performed with decoders. */ SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxReplySize, - spi::SpiMode spiMode, uint32_t spiSpeed); + spi::SpiModes spiMode, uint32_t spiSpeed); address_t getSpiAddress() const; std::string getSpiDevice() const; gpioId_t getChipSelectPin() const; size_t getMaxBufferSize() const; + + /** Enables changing SPI speed at run-time */ + void setSpiSpeed(uint32_t newSpeed); + /** Enables changing the SPI mode at run-time */ + void setSpiMode(spi::SpiModes newMode); + /** * True if SPI transfers should be performed in full duplex mode * @return @@ -82,7 +87,7 @@ public: void setCsHigh(bool enable); void setBitsPerWord(uint8_t bitsPerWord); - void getSpiParameters(spi::SpiMode& spiMode, uint32_t& spiSpeed, + void getSpiParameters(spi::SpiModes& spiMode, uint32_t& spiSpeed, UncommonParameters* parameters = nullptr) const; /** @@ -101,7 +106,7 @@ private: std::string spiDevice; const size_t maxSize; - spi::SpiMode spiMode; + spi::SpiModes spiMode; uint32_t spiSpeed; bool halfDuplex = false; diff --git a/linux/spi/spiDefinitions.h b/linux/spi/spiDefinitions.h index 9c278a70..e8c48147 100644 --- a/linux/spi/spiDefinitions.h +++ b/linux/spi/spiDefinitions.h @@ -1,9 +1,11 @@ #ifndef LINUX_SPI_SPIDEFINITONS_H_ #define LINUX_SPI_SPIDEFINITONS_H_ +#include + namespace spi { -enum SpiMode { +enum SpiModes: uint8_t { MODE_0, MODE_1, MODE_2, diff --git a/misc/eclipse/.cproject b/misc/eclipse/.cproject index c8b1c059..6caf4a08 100644 --- a/misc/eclipse/.cproject +++ b/misc/eclipse/.cproject @@ -19,7 +19,7 @@ - + @@ -70,7 +70,7 @@ - + @@ -233,7 +233,7 @@ - + @@ -459,7 +461,7 @@ diff --git a/misc/eclipse/Host/eive-linux-host-debug-cmake.launch b/misc/eclipse/Host/eive-linux-host-debug-cmake.launch index e79e2e8d..268bdf33 100644 --- a/misc/eclipse/Host/eive-linux-host-debug-cmake.launch +++ b/misc/eclipse/Host/eive-linux-host-debug-cmake.launch @@ -18,7 +18,7 @@ - + diff --git a/misc/eclipse/Host/eive-mingw-release-cmake.launch b/misc/eclipse/Host/eive-mingw-release-cmake.launch index 0a5fbd71..75471411 100644 --- a/misc/eclipse/Host/eive-mingw-release-cmake.launch +++ b/misc/eclipse/Host/eive-mingw-release-cmake.launch @@ -18,7 +18,7 @@ - + diff --git a/misc/eclipse/make/Host/eive-linux-host-debug.launch b/misc/eclipse/make/Host/eive-linux-host-debug.launch deleted file mode 100644 index f5ab1ac7..00000000 --- a/misc/eclipse/make/Host/eive-linux-host-debug.launch +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/misc/eclipse/make/Host/eive-linux-host-release-cmake.launch b/misc/eclipse/make/Host/eive-linux-host-release-cmake.launch deleted file mode 100644 index f2647a4f..00000000 --- a/misc/eclipse/make/Host/eive-linux-host-release-cmake.launch +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/misc/eclipse/make/Host/eive-linux-host-release.launch b/misc/eclipse/make/Host/eive-linux-host-release.launch deleted file mode 100644 index 7548f831..00000000 --- a/misc/eclipse/make/Host/eive-linux-host-release.launch +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/misc/eclipse/make/Host/eive-mingw-debug.launch b/misc/eclipse/make/Host/eive-mingw-debug.launch deleted file mode 100644 index 4ab7b736..00000000 --- a/misc/eclipse/make/Host/eive-mingw-debug.launch +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/misc/eclipse/make/Host/eive-mingw-release.launch b/misc/eclipse/make/Host/eive-mingw-release.launch deleted file mode 100644 index da2f47a9..00000000 --- a/misc/eclipse/make/Host/eive-mingw-release.launch +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mission/devices/GyroL3GD20Handler.cpp b/mission/devices/GyroL3GD20Handler.cpp index 28cbdbed..850be83c 100644 --- a/mission/devices/GyroL3GD20Handler.cpp +++ b/mission/devices/GyroL3GD20Handler.cpp @@ -1,38 +1,55 @@ -#include -#include +#include "GyroL3GD20Handler.h" +#include -GyroHandler::GyroHandler(object_id_t objectId, object_id_t deviceCommunication, +#include + +GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication, CookieIF *comCookie): DeviceHandlerBase(objectId, deviceCommunication, comCookie), dataset(this) { +#if OBSW_VERBOSE_LEVEL >= 1 + debugDivider = new PeriodicOperationDivider(5); +#endif } -GyroHandler::~GyroHandler() {} +GyroHandlerL3GD20H::~GyroHandlerL3GD20H() {} -void GyroHandler::doStartUp() { - if(internalState == InternalState::STATE_NONE) { - internalState = InternalState::STATE_CONFIGURE; +void GyroHandlerL3GD20H::doStartUp() { + if(internalState == InternalState::NONE) { + internalState = InternalState::CONFIGURE; } - if(internalState == InternalState::STATE_CONFIGURE) { + if(internalState == InternalState::CONFIGURE) { if(commandExecuted) { - internalState = InternalState::STATE_NORMAL; + internalState = InternalState::CHECK_REGS; commandExecuted = false; } } + + if(internalState == InternalState::CHECK_REGS) { + if(commandExecuted) { + internalState = InternalState::NORMAL; +#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1 + setMode(MODE_NORMAL); +#else + setMode(_MODE_TO_ON); +#endif + commandExecuted = false; + } + } } -void GyroHandler::doShutDown() { +void GyroHandlerL3GD20H::doShutDown() { setMode(_MODE_POWER_DOWN); } -ReturnValue_t GyroHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) { +ReturnValue_t GyroHandlerL3GD20H::buildTransitionDeviceCommand(DeviceCommandId_t *id) { switch(internalState) { - case(InternalState::STATE_NONE): - case(InternalState::STATE_NORMAL): { + case(InternalState::NONE): + case(InternalState::NORMAL): { return HasReturnvaluesIF::RETURN_OK; } - case(InternalState::STATE_CONFIGURE): { + case(InternalState::CONFIGURE): { *id = L3GD20H::CONFIGURE_CTRL_REGS; uint8_t command [5]; command[0] = L3GD20H::CTRL_REG_1_VAL; @@ -41,10 +58,13 @@ ReturnValue_t GyroHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) { command[3] = L3GD20H::CTRL_REG_4_VAL; command[4] = L3GD20H::CTRL_REG_5_VAL; return buildCommandFromCommand(*id, command, 5); - break; + } + case(InternalState::CHECK_REGS): { + *id = L3GD20H::READ_REGS; + return buildCommandFromCommand(*id, nullptr, 0); } default: - // might be a configuration error. + /* Might be a configuration error. */ sif::debug << "GyroHandler::buildTransitionDeviceCommand: Unknown " << "internal state!" << std::endl; return HasReturnvaluesIF::RETURN_OK; @@ -52,12 +72,12 @@ ReturnValue_t GyroHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) { return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t GyroHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) { +ReturnValue_t GyroHandlerL3GD20H::buildNormalDeviceCommand(DeviceCommandId_t *id) { *id = L3GD20H::READ_REGS; return buildCommandFromCommand(*id, nullptr, 0); } -ReturnValue_t GyroHandler::buildCommandFromCommand( +ReturnValue_t GyroHandlerL3GD20H::buildCommandFromCommand( DeviceCommandId_t deviceCommand, const uint8_t *commandData, size_t commandDataLen) { switch(deviceCommand) { @@ -120,24 +140,25 @@ ReturnValue_t GyroHandler::buildCommandFromCommand( return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t GyroHandler::scanForReply(const uint8_t *start, size_t len, +ReturnValue_t GyroHandlerL3GD20H::scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) { - // SPI, ID will always be the one of the last sent command. + /* For SPI, the ID will always be the one of the last sent command. */ *foundId = this->getPendingCommand(); *foundLen = this->rawPacketLen; - // Data with SPI Interface has always this answer + /* Data with SPI Interface has always this answer */ if (start[0] == 0b11111111) { return HasReturnvaluesIF::RETURN_OK; } return DeviceHandlerIF::INVALID_DATA; } -ReturnValue_t GyroHandler::interpretDeviceReply(DeviceCommandId_t id, +ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; switch(id) { case(L3GD20H::CONFIGURE_CTRL_REGS): { + commandExecuted = true; break; } case(L3GD20H::READ_CTRL_REGS): { @@ -147,18 +168,23 @@ ReturnValue_t GyroHandler::interpretDeviceReply(DeviceCommandId_t id, commandExecuted = true; } else { - // Attempt reconfiguration. - internalState = InternalState::STATE_CONFIGURE; + /* Attempt reconfiguration. */ + internalState = InternalState::CONFIGURE; return DeviceHandlerIF::DEVICE_REPLY_INVALID; } break; } - case(L3GD20H::READ_START): { + case(L3GD20H::READ_REGS): { if(packet[1] != ctrlReg1Value and packet[2] != ctrlReg2Value and packet[3] != ctrlReg3Value and packet[4] != ctrlReg4Value and packet[5] != ctrlReg5Value) { return DeviceHandlerIF::DEVICE_REPLY_INVALID; } + else { + if(internalState == InternalState::CHECK_REGS) { + commandExecuted = true; + } + } statusReg = packet[L3GD20H::STATUS_IDX]; @@ -171,8 +197,25 @@ ReturnValue_t GyroHandler::interpretDeviceReply(DeviceCommandId_t id, int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX]; float temperature = 25.0 + temperaturOffset; +#if OBSW_VERBOSE_LEVEL >= 1 + if(debugDivider->checkAndIncrement()) { + /* Set terminal to utf-8 if there is an issue with micro printout. */ +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "GyroHandlerL3GD20H: Angular velocities in degrees per second:" << + std::endl; + sif::info << "X: " << angVelocX << " \xC2\xB0" << std::endl; + sif::info << "Y: " << angVelocY << " \xC2\xB0" << std::endl; + sif::info << "Z: " << angVelocZ << " \xC2\xB0" << std::endl; +#else + sif::printInfo("GyroHandlerL3GD20H: Angular velocities in degrees per second:\n"); + sif::printInfo("X: %f " "\xC2\xB0" "T\n", angVelocX); + sif::printInfo("Y: %f " "\xC2\xB0" "T\n", angVelocY); + sif::printInfo("Z: %f " "\xC2\xB0" "T\n", angVelocZ); +#endif + } +#endif - PoolReadHelper readSet(&dataset); + PoolReadGuard readSet(&dataset); if(readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) { dataset.angVelocX = angVelocX; dataset.angVelocY = angVelocY; @@ -189,11 +232,11 @@ ReturnValue_t GyroHandler::interpretDeviceReply(DeviceCommandId_t id, } -uint32_t GyroHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { - return 5000; +uint32_t GyroHandlerL3GD20H::getTransitionDelayMs(Mode_t from, Mode_t to) { + return 10000; } -ReturnValue_t GyroHandler::initializeLocalDataPool( +ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool( localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { localDataPoolMap.emplace(L3GD20H::ANG_VELOC_X, new PoolEntry({0.0})); @@ -206,12 +249,12 @@ ReturnValue_t GyroHandler::initializeLocalDataPool( return HasReturnvaluesIF::RETURN_OK; } -void GyroHandler::fillCommandAndReplyMap() { +void GyroHandlerL3GD20H::fillCommandAndReplyMap() { insertInCommandAndReplyMap(L3GD20H::READ_REGS, 1, &dataset); insertInCommandAndReplyMap(L3GD20H::CONFIGURE_CTRL_REGS, 1); insertInCommandAndReplyMap(L3GD20H::READ_CTRL_REGS, 1); } -void GyroHandler::modeChanged() { - internalState = InternalState::STATE_NONE; +void GyroHandlerL3GD20H::modeChanged() { + internalState = InternalState::NONE; } diff --git a/mission/devices/GyroL3GD20Handler.h b/mission/devices/GyroL3GD20Handler.h index 20396315..442e28f8 100644 --- a/mission/devices/GyroL3GD20Handler.h +++ b/mission/devices/GyroL3GD20Handler.h @@ -1,8 +1,12 @@ #ifndef MISSION_DEVICES_GYROL3GD20HANDLER_H_ #define MISSION_DEVICES_GYROL3GD20HANDLER_H_ -#include #include "devicedefinitions/GyroL3GD20Definitions.h" +#include + +#include +#include + /** * @brief Device Handler for the L3GD20H gyroscope sensor @@ -10,12 +14,14 @@ * @details * Advanced documentation: * https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/L3GD20H_Gyro + * + * Data is read big endian with the smallest possible range of 245 degrees per second. */ -class GyroHandler: public DeviceHandlerBase { +class GyroHandlerL3GD20H: public DeviceHandlerBase { public: - GyroHandler(object_id_t objectId, object_id_t deviceCommunication, + GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication, CookieIF* comCookie); - virtual ~GyroHandler(); + virtual ~GyroHandlerL3GD20H(); protected: @@ -41,14 +47,15 @@ protected: LocalDataPoolManager &poolManager) override; private: - L3GD20H::GyroPrimaryDataset dataset; + GyroPrimaryDataset dataset; enum class InternalState { - STATE_NONE, - STATE_CONFIGURE, - STATE_NORMAL + NONE, + CONFIGURE, + CHECK_REGS, + NORMAL }; - InternalState internalState = InternalState::STATE_NONE; + InternalState internalState = InternalState::NONE; bool commandExecuted = false; uint8_t statusReg = 0; @@ -62,6 +69,10 @@ private: uint8_t commandBuffer[L3GD20H::READ_LEN + 1]; float scaleFactor = static_cast(L3GD20H::RANGE_DPS_00) / INT16_MAX; + +#if OBSW_VERBOSE_LEVEL >= 1 + PeriodicOperationDivider* debugDivider = nullptr; +#endif }; diff --git a/mission/devices/MGMHandlerLIS3MDL.cpp b/mission/devices/MGMHandlerLIS3MDL.cpp index 6eb7f5d4..17854de7 100644 --- a/mission/devices/MGMHandlerLIS3MDL.cpp +++ b/mission/devices/MGMHandlerLIS3MDL.cpp @@ -1,13 +1,14 @@ -#include +#include #include "MGMHandlerLIS3MDL.h" +#include MGMHandlerLIS3MDL::MGMHandlerLIS3MDL(object_id_t objectId, object_id_t deviceCommunication, CookieIF* comCookie): DeviceHandlerBase(objectId, deviceCommunication, comCookie), dataset(this) { #if OBSW_VERBOSE_LEVEL >= 1 - debugDivider = new PeriodicOperationDivider(10); + debugDivider = new PeriodicOperationDivider(5); #endif /* Set to default values right away. */ registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT; @@ -44,8 +45,11 @@ void MGMHandlerLIS3MDL::doStartUp() { /* Set up cached registers which will be used to configure the MGM. */ if(commandExecuted) { commandExecuted = false; - /* Replace _MODE_TO_ON with MODE_NORMAL to jump to normal mode quickly */ +#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1 + setMode(MODE_NORMAL); +#else setMode(_MODE_TO_ON); +#endif } break; } @@ -299,7 +303,7 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, #endif } #endif - PoolReadHelper readHelper(&dataset); + PoolReadGuard readHelper(&dataset); if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) { dataset.fieldStrengthX = mgmX; dataset.fieldStrengthY = mgmY; @@ -459,7 +463,7 @@ void MGMHandlerLIS3MDL::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { } uint32_t MGMHandlerLIS3MDL::getTransitionDelayMs(Mode_t from, Mode_t to) { - return 30000; + return 10000; } void MGMHandlerLIS3MDL::modeChanged(void) { diff --git a/mission/devices/MGMHandlerRM3100.cpp b/mission/devices/MGMHandlerRM3100.cpp index 76d3dd70..4fd654d3 100644 --- a/mission/devices/MGMHandlerRM3100.cpp +++ b/mission/devices/MGMHandlerRM3100.cpp @@ -1,5 +1,7 @@ +#include #include "MGMHandlerRM3100.h" +#include #include #include #include @@ -7,345 +9,355 @@ MGMHandlerRM3100::MGMHandlerRM3100(object_id_t objectId, object_id_t deviceCommunication, CookieIF* comCookie): - DeviceHandlerBase(objectId, deviceCommunication, comCookie), - primaryDataset(this) { + DeviceHandlerBase(objectId, deviceCommunication, comCookie), + primaryDataset(this) { #if OBSW_VERBOSE_LEVEL >= 1 - debugDivider = new PeriodicOperationDivider(10); + debugDivider = new PeriodicOperationDivider(5); #endif } MGMHandlerRM3100::~MGMHandlerRM3100() {} void MGMHandlerRM3100::doStartUp() { - if(internalState == InternalState::STATE_NONE) { - internalState = InternalState::STATE_CONFIGURE_CMM; - } - - if(internalState == InternalState::STATE_CONFIGURE_CMM) { - internalState = InternalState::STATE_READ_CMM; - } - else if(internalState == InternalState::STATE_READ_CMM) { - if(commandExecuted) { - internalState = InternalState::STATE_CONFIGURE_TMRC; - } - } - - if(internalState == InternalState::STATE_CONFIGURE_TMRC) { - internalState = InternalState::STATE_READ_TMRC; - } - else if(internalState == InternalState::STATE_READ_TMRC) { - if(commandExecuted) { - internalState = InternalState::STATE_NORMAL; - setMode(_MODE_TO_ON); - } - } + switch(internalState) { + case(InternalState::NONE): { + internalState = InternalState::CONFIGURE_CMM; + break; + } + case(InternalState::CONFIGURE_CMM): { + internalState = InternalState::READ_CMM; + break; + } + case(InternalState::READ_CMM): { + if(commandExecuted) { + internalState = InternalState::STATE_CONFIGURE_TMRC; + } + break; + } + case(InternalState::STATE_CONFIGURE_TMRC): { + if(commandExecuted) { + internalState = InternalState::STATE_READ_TMRC; + } + break; + } + case(InternalState::STATE_READ_TMRC): { + if(commandExecuted) { + internalState = InternalState::NORMAL; +#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1 + setMode(MODE_NORMAL); +#else + setMode(_MODE_TO_ON); +#endif + } + break; + } + default: { + break; + } + } } void MGMHandlerRM3100::doShutDown() { - setMode(_MODE_POWER_DOWN); + setMode(_MODE_POWER_DOWN); } ReturnValue_t MGMHandlerRM3100::buildTransitionDeviceCommand( - DeviceCommandId_t *id) { - switch(internalState) { - case(InternalState::STATE_NONE): - case(InternalState::STATE_NORMAL): { - return HasReturnvaluesIF::RETURN_OK; - } - case(InternalState::STATE_CONFIGURE_CMM): { - *id = RM3100::CONFIGURE_CMM; - break; - } - case(InternalState::STATE_READ_CMM): { - *id = RM3100::READ_CMM; - break; - } - case(InternalState::STATE_CONFIGURE_TMRC): { - *id = RM3100::CONFIGURE_TMRC; - break; - } - case(InternalState::STATE_READ_TMRC): { - *id = RM3100::READ_TMRC; - break; - } - default: - // might be a configuration error. - sif::debug << "GyroHandler::buildTransitionDeviceCommand: Unknown " - << "internal state!" << std::endl; - return HasReturnvaluesIF::RETURN_OK; - } + DeviceCommandId_t *id) { + switch(internalState) { + case(InternalState::NONE): + case(InternalState::NORMAL): { + return HasReturnvaluesIF::RETURN_OK; + } + case(InternalState::CONFIGURE_CMM): { + *id = RM3100::CONFIGURE_CMM; + break; + } + case(InternalState::READ_CMM): { + *id = RM3100::READ_CMM; + break; + } + case(InternalState::STATE_CONFIGURE_TMRC): { + *id = RM3100::CONFIGURE_TMRC; + break; + } + case(InternalState::STATE_READ_TMRC): { + *id = RM3100::READ_TMRC; + break; + } + default: + /* Might be a configuration error. */ + sif::debug << "GyroHandler::buildTransitionDeviceCommand: Unknown internal state!" << + std::endl; + return HasReturnvaluesIF::RETURN_OK; + } - return buildCommandFromCommand(*id, nullptr, 0); + return buildCommandFromCommand(*id, nullptr, 0); } ReturnValue_t MGMHandlerRM3100::buildCommandFromCommand( - DeviceCommandId_t deviceCommand, const uint8_t *commandData, - size_t commandDataLen) { - switch(deviceCommand) { - case(RM3100::CONFIGURE_CMM): { - commandBuffer[0] = RM3100::CMM_REGISTER; - commandBuffer[1] = RM3100::CMM_VALUE; - rawPacket = commandBuffer; - rawPacketLen = 2; - break; - } - case(RM3100::READ_CMM): { - commandBuffer[0] = RM3100::CMM_REGISTER | RM3100::READ_MASK; - commandBuffer[1] = 0; - rawPacket = commandBuffer; - rawPacketLen = 2; - break; - } - case(RM3100::CONFIGURE_TMRC): { - return handleTmrcConfigCommand(deviceCommand, commandData, - commandDataLen); - } - case(RM3100::READ_TMRC): { - commandBuffer[0] = RM3100::TMRC_REGISTER | RM3100::READ_MASK; - commandBuffer[1] = 0; - rawPacket = commandBuffer; - rawPacketLen = 2; - break; - } - case(RM3100::CONFIGURE_CYCLE_COUNT): { - return handleCycleCountConfigCommand(deviceCommand, commandData, - commandDataLen); - } - case(RM3100::READ_CYCLE_COUNT): { - commandBuffer[0] = RM3100::CYCLE_COUNT_START_REGISTER | - RM3100::READ_MASK; - std::memset(commandBuffer + 1, 0, 6); - rawPacket = commandBuffer; - rawPacketLen = 7; - break; - } - case(RM3100::READ_DATA): { - commandBuffer[0] = RM3100::MEASUREMENT_REG_START | RM3100::READ_MASK; - std::memset(commandBuffer + 1, 0, 9); - rawPacketLen = 10; - break; - } - default: - return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; - } - return RETURN_OK; + DeviceCommandId_t deviceCommand, const uint8_t *commandData, + size_t commandDataLen) { + switch(deviceCommand) { + case(RM3100::CONFIGURE_CMM): { + commandBuffer[0] = RM3100::CMM_REGISTER; + commandBuffer[1] = RM3100::CMM_VALUE; + rawPacket = commandBuffer; + rawPacketLen = 2; + break; + } + case(RM3100::READ_CMM): { + commandBuffer[0] = RM3100::CMM_REGISTER | RM3100::READ_MASK; + commandBuffer[1] = 0; + rawPacket = commandBuffer; + rawPacketLen = 2; + break; + } + case(RM3100::CONFIGURE_TMRC): { + return handleTmrcConfigCommand(deviceCommand, commandData, + commandDataLen); + } + case(RM3100::READ_TMRC): { + commandBuffer[0] = RM3100::TMRC_REGISTER | RM3100::READ_MASK; + commandBuffer[1] = 0; + rawPacket = commandBuffer; + rawPacketLen = 2; + break; + } + case(RM3100::CONFIGURE_CYCLE_COUNT): { + return handleCycleCountConfigCommand(deviceCommand, commandData, + commandDataLen); + } + case(RM3100::READ_CYCLE_COUNT): { + commandBuffer[0] = RM3100::CYCLE_COUNT_START_REGISTER | RM3100::READ_MASK; + std::memset(commandBuffer + 1, 0, 6); + rawPacket = commandBuffer; + rawPacketLen = 7; + break; + } + case(RM3100::READ_DATA): { + commandBuffer[0] = RM3100::MEASUREMENT_REG_START | RM3100::READ_MASK; + std::memset(commandBuffer + 1, 0, 9); + rawPacketLen = 10; + break; + } + default: + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; + } + return RETURN_OK; } ReturnValue_t MGMHandlerRM3100::buildNormalDeviceCommand( - DeviceCommandId_t *id) { - *id = RM3100::READ_DATA; - return buildCommandFromCommand(*id, nullptr, 0); + DeviceCommandId_t *id) { + *id = RM3100::READ_DATA; + return buildCommandFromCommand(*id, nullptr, 0); } ReturnValue_t MGMHandlerRM3100::scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, - size_t *foundLen) { + size_t *foundLen) { - // SPI, ID will always be the one of the last sent command. - *foundId = this->getPendingCommand(); - *foundLen = this->rawPacketLen; - - // Data with SPI Interface has always this answer - if (start[0] == 0b11111111) { - return RETURN_OK; - } - return DeviceHandlerIF::INVALID_DATA; + /* For SPI, ID will always be the one of the last sent command. */ + *foundId = this->getPendingCommand(); + *foundLen = len; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t MGMHandlerRM3100::interpretDeviceReply( - DeviceCommandId_t id, const uint8_t *packet) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - switch(id) { - case(RM3100::CONFIGURE_CMM): - case(RM3100::CONFIGURE_CYCLE_COUNT): - case(RM3100::CONFIGURE_TMRC): { - // We can only check whether write was sucessful with read operation. - break; - } - case(RM3100::READ_CMM): { - if(packet[1] == cmmRegValue) { - commandExecuted = true; - } - else { - // Attempt reconfiguration. - internalState = InternalState::STATE_CONFIGURE_CMM; - return DeviceHandlerIF::DEVICE_REPLY_INVALID; - } - break; - } - case(RM3100::READ_TMRC): { - if(packet[1] == tmrcRegValue) { - commandExecuted = true; - // Reading TMRC was commanded. Trigger event to inform ground. - if(mode != _MODE_START_UP) { - triggerEvent(tmrcSet, tmrcRegValue, 0); - } - } - else { - // Attempt reconfiguration. - internalState = InternalState::STATE_CONFIGURE_TMRC; - return DeviceHandlerIF::DEVICE_REPLY_INVALID; - } - break; - } - case(RM3100::READ_CYCLE_COUNT): { - uint16_t cycleCountX = packet[1] << 8 | packet[2]; - uint16_t cycleCountY = packet[3] << 8 | packet[4]; - uint16_t cycleCountZ = packet[5] << 8 | packet[6]; - if(cycleCountX != cycleCountRegValueX or - cycleCountY != cycleCountRegValueY or - cycleCountZ != cycleCountRegValueZ) { - return DeviceHandlerIF::DEVICE_REPLY_INVALID; - } - // Reading TMRC was commanded. Trigger event to inform ground. - if(mode != _MODE_START_UP) { - uint32_t eventParam1 = cycleCountX << 16 | cycleCountY; - triggerEvent(cycleCountersSet, eventParam1, cycleCountZ); - } - break; - } - case(RM3100::READ_DATA): { - result = handleDataReadout(packet); - break; - } - default: - return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; - } + DeviceCommandId_t id, const uint8_t *packet) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + switch(id) { + case(RM3100::CONFIGURE_CMM): + case(RM3100::CONFIGURE_CYCLE_COUNT): + case(RM3100::CONFIGURE_TMRC): { + /* We can only check whether write was successful with read operation. */ + if(mode == _MODE_START_UP) { + commandExecuted = true; + } + break; + } + case(RM3100::READ_CMM): { + uint8_t cmmValue = packet[1]; + /* We clear the seventh bit in any case + * because this one is zero sometimes for some reason */ + bitutil::bitClear(&cmmValue, 6); + if(cmmValue == cmmRegValue and internalState == InternalState::READ_CMM) { + commandExecuted = true; + } + else { + /* Attempt reconfiguration. */ + internalState = InternalState::CONFIGURE_CMM; + return DeviceHandlerIF::DEVICE_REPLY_INVALID; + } + break; + } + case(RM3100::READ_TMRC): { + if(packet[1] == tmrcRegValue) { + commandExecuted = true; + /* Reading TMRC was commanded. Trigger event to inform ground. */ + if(mode != _MODE_START_UP) { + triggerEvent(tmrcSet, tmrcRegValue, 0); + } + } + else { + /* Attempt reconfiguration. */ + internalState = InternalState::STATE_CONFIGURE_TMRC; + return DeviceHandlerIF::DEVICE_REPLY_INVALID; + } + break; + } + case(RM3100::READ_CYCLE_COUNT): { + uint16_t cycleCountX = packet[1] << 8 | packet[2]; + uint16_t cycleCountY = packet[3] << 8 | packet[4]; + uint16_t cycleCountZ = packet[5] << 8 | packet[6]; + if(cycleCountX != cycleCountRegValueX or cycleCountY != cycleCountRegValueY or + cycleCountZ != cycleCountRegValueZ) { + return DeviceHandlerIF::DEVICE_REPLY_INVALID; + } + /* Reading TMRC was commanded. Trigger event to inform ground. */ + if(mode != _MODE_START_UP) { + uint32_t eventParam1 = (cycleCountX << 16) | cycleCountY; + triggerEvent(cycleCountersSet, eventParam1, cycleCountZ); + } + break; + } + case(RM3100::READ_DATA): { + result = handleDataReadout(packet); + break; + } + default: + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } - return result; + return result; } -ReturnValue_t MGMHandlerRM3100::handleCycleCountConfigCommand( - DeviceCommandId_t deviceCommand, const uint8_t *commandData, - size_t commandDataLen) { - if(commandData == nullptr) { - return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; - } +ReturnValue_t MGMHandlerRM3100::handleCycleCountConfigCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData, size_t commandDataLen) { + if(commandData == nullptr) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } - // Set cycle count - if(commandDataLen == 2) { - handleCycleCommand(true, commandData, commandDataLen); - } - else if(commandDataLen == 6) { - handleCycleCommand(false, commandData, commandDataLen); - } - else { - return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; - } + // Set cycle count + if(commandDataLen == 2) { + handleCycleCommand(true, commandData, commandDataLen); + } + else if(commandDataLen == 6) { + handleCycleCommand(false, commandData, commandDataLen); + } + else { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } - commandBuffer[0] = RM3100::CYCLE_COUNT_VALUE; - std::memcpy(commandBuffer + 1, &cycleCountRegValueX, 2); - std::memcpy(commandBuffer + 3, &cycleCountRegValueY, 2); - std::memcpy(commandBuffer + 5, &cycleCountRegValueZ, 2); - rawPacketLen = 7; - rawPacket = commandBuffer; - return HasReturnvaluesIF::RETURN_OK; + commandBuffer[0] = RM3100::CYCLE_COUNT_VALUE; + std::memcpy(commandBuffer + 1, &cycleCountRegValueX, 2); + std::memcpy(commandBuffer + 3, &cycleCountRegValueY, 2); + std::memcpy(commandBuffer + 5, &cycleCountRegValueZ, 2); + rawPacketLen = 7; + rawPacket = commandBuffer; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t MGMHandlerRM3100::handleCycleCommand(bool oneCycleValue, - const uint8_t *commandData, size_t commandDataLen) { - RM3100::CycleCountCommand command(oneCycleValue); - ReturnValue_t result = command.deSerialize(&commandData, &commandDataLen, - SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + const uint8_t *commandData, size_t commandDataLen) { + RM3100::CycleCountCommand command(oneCycleValue); + ReturnValue_t result = command.deSerialize(&commandData, &commandDataLen, + SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - // Data sheet p.30 - // "while noise limits the useful upper range to ~400 cycle counts." - if(command.cycleCountX > 450 ) { - return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; - } + /* Data sheet p.30 "while noise limits the useful upper range to ~400 cycle counts." */ + if(command.cycleCountX > 450 ) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } - if(not oneCycleValue and - (command.cycleCountY > 450 or command.cycleCountZ > 450)) { - return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; - } + if(not oneCycleValue and (command.cycleCountY > 450 or command.cycleCountZ > 450)) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } - cycleCountRegValueX = command.cycleCountX; - cycleCountRegValueY = command.cycleCountY; - cycleCountRegValueZ = command.cycleCountZ; - return HasReturnvaluesIF::RETURN_OK; + cycleCountRegValueX = command.cycleCountX; + cycleCountRegValueY = command.cycleCountY; + cycleCountRegValueZ = command.cycleCountZ; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t MGMHandlerRM3100::handleTmrcConfigCommand( - DeviceCommandId_t deviceCommand, const uint8_t *commandData, - size_t commandDataLen) { - if(commandData == nullptr) { - return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; - } + DeviceCommandId_t deviceCommand, const uint8_t *commandData, + size_t commandDataLen) { + if(commandData == nullptr) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } - if(commandDataLen != 1) { - return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; - } + if(commandDataLen != 1) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } - commandBuffer[0] = RM3100::TMRC_REGISTER; - commandBuffer[1] = commandData[1]; - rawPacketLen = 2; - rawPacket = commandBuffer; - return HasReturnvaluesIF::RETURN_OK; + commandBuffer[0] = RM3100::TMRC_REGISTER; + commandBuffer[1] = commandData[1]; + rawPacketLen = 2; + rawPacket = commandBuffer; + return HasReturnvaluesIF::RETURN_OK; } void MGMHandlerRM3100::fillCommandAndReplyMap() { - insertInCommandAndReplyMap(RM3100::CONFIGURE_CMM, 1); - insertInCommandAndReplyMap(RM3100::READ_CMM, 1); + insertInCommandAndReplyMap(RM3100::CONFIGURE_CMM, 1); + insertInCommandAndReplyMap(RM3100::READ_CMM, 1); - insertInCommandAndReplyMap(RM3100::CONFIGURE_TMRC, 1); - insertInCommandAndReplyMap(RM3100::READ_TMRC, 1); + insertInCommandAndReplyMap(RM3100::CONFIGURE_TMRC, 1); + insertInCommandAndReplyMap(RM3100::READ_TMRC, 1); - insertInCommandAndReplyMap(RM3100::CONFIGURE_CYCLE_COUNT, 1); - insertInCommandAndReplyMap(RM3100::READ_CYCLE_COUNT, 1); + insertInCommandAndReplyMap(RM3100::CONFIGURE_CYCLE_COUNT, 1); + insertInCommandAndReplyMap(RM3100::READ_CYCLE_COUNT, 1); - insertInCommandAndReplyMap(RM3100::READ_DATA, 1, &primaryDataset); + insertInCommandAndReplyMap(RM3100::READ_DATA, 1, &primaryDataset); } void MGMHandlerRM3100::modeChanged(void) { - internalState = InternalState::STATE_NONE; + internalState = InternalState::NONE; } ReturnValue_t MGMHandlerRM3100::initializeLocalDataPool( - localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { - localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_X, - new PoolEntry({0.0})); - localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Y, - new PoolEntry({0.0})); - localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Z, - new PoolEntry({0.0})); - return HasReturnvaluesIF::RETURN_OK; + localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_X, new PoolEntry({0.0})); + localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Y, new PoolEntry({0.0})); + localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Z, new PoolEntry({0.0})); + return HasReturnvaluesIF::RETURN_OK; } uint32_t MGMHandlerRM3100::getTransitionDelayMs(Mode_t from, Mode_t to) { - return 5000; + return 10000; } ReturnValue_t MGMHandlerRM3100::handleDataReadout(const uint8_t *packet) { - // analyze data here. - // Field strengths in micro Tesla - int32_t fieldStrengthX = (packet[1] << 16 | packet[2] << 8 | packet[3]) - * scaleFactorX; - int32_t fieldStrengthY = (packet[4] << 16 | packet[5] << 8 | packet[6]) - * scaleFactorY; - int32_t fieldStrengthZ = (packet[7] << 16 | packet[8] << 8 | packet[9]) - * scaleFactorZ; + /* Analyze data here. The sensor generates 24 bit signed values so we need to do some bitshift + * trickery here to calculate the raw values first */ + int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8; + int32_t fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8; + int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8; + + /* Now scale to physical value in microtesla */ + float fieldStrengthX = fieldStrengthRawX * scaleFactorX; + float fieldStrengthY = fieldStrengthRawY * scaleFactorX; + float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX; #if OBSW_VERBOSE_LEVEL >= 1 - if(debugDivider->checkAndIncrement()) { - sif::info << "MGMHandlerLIS3: Magnetic field strength in" - " microtesla:" << std::endl; - // Set terminal to utf-8 if there is an issue with micro printout. - sif::info << "X: " << fieldStrengthX << " \xC2\xB5T" << std::endl; - sif::info << "Y: " << fieldStrengthY << " \xC2\xB5T" << std::endl; - sif::info << "Z: " << fieldStrengthZ << " \xC2\xB5T" << std::endl; - } + if(debugDivider->checkAndIncrement()) { + sif::info << "MGMHandlerRM3100: Magnetic field strength in" + " microtesla:" << std::endl; + /* Set terminal to utf-8 if there is an issue with micro printout. */ + sif::info << "X: " << fieldStrengthX << " \xC2\xB5T" << std::endl; + sif::info << "Y: " << fieldStrengthY << " \xC2\xB5T" << std::endl; + sif::info << "Z: " << fieldStrengthZ << " \xC2\xB5T" << std::endl; + } #endif - ReturnValue_t result = primaryDataset.read(); - if(result == HasReturnvaluesIF::RETURN_OK) { - primaryDataset.fieldStrengthX = fieldStrengthX; - primaryDataset.fieldStrengthY = fieldStrengthY; - primaryDataset.fieldStrengthZ = fieldStrengthZ; - primaryDataset.setValidity(true, true); - result = primaryDataset.commit(); - } - return result; + /* TODO: Sanity check on values */ + PoolReadGuard readGuard(&primaryDataset); + if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) { + primaryDataset.fieldStrengthX = fieldStrengthX; + primaryDataset.fieldStrengthY = fieldStrengthY; + primaryDataset.fieldStrengthZ = fieldStrengthZ; + primaryDataset.setValidity(true, true); + } + return RETURN_OK; } diff --git a/mission/devices/MGMHandlerRM3100.h b/mission/devices/MGMHandlerRM3100.h index 968953bf..ce107637 100644 --- a/mission/devices/MGMHandlerRM3100.h +++ b/mission/devices/MGMHandlerRM3100.h @@ -61,18 +61,18 @@ protected: private: enum class InternalState { - STATE_NONE, - STATE_CONFIGURE_CMM, - STATE_READ_CMM, + NONE, + CONFIGURE_CMM, + READ_CMM, // The cycle count states are propably not going to be used because // the default cycle count will be used. STATE_CONFIGURE_CYCLE_COUNT, STATE_READ_CYCLE_COUNT, STATE_CONFIGURE_TMRC, STATE_READ_TMRC, - STATE_NORMAL + NORMAL }; - InternalState internalState = InternalState::STATE_NONE; + InternalState internalState = InternalState::NONE; bool commandExecuted = false; RM3100::Rm3100PrimaryDataset primaryDataset; diff --git a/mission/devices/PCDUHandler.cpp b/mission/devices/PCDUHandler.cpp index 8e2c1a39..5812c8bf 100644 --- a/mission/devices/PCDUHandler.cpp +++ b/mission/devices/PCDUHandler.cpp @@ -49,7 +49,7 @@ ReturnValue_t PCDUHandler::initialize() { sif::error << "PCDUHandler::initialize: Invalid pdu2Handler" << std::endl; return RETURN_FAILED; } - result = pdu2Handler->getSubscriptionInterface()->subscribeForSetUpdateMessages( + result = pdu2Handler->getSubscriptionInterface()->subscribeForSetUpdateMessage( PDU2::HK_TABLE_DATA_SET_ID, this->getObjectId(), commandQueue->getId(), true); if (result != RETURN_OK) { sif::error << "PCDUHandler::initialize: Failed to subscribe for set update messages from " @@ -63,7 +63,7 @@ ReturnValue_t PCDUHandler::initialize() { sif::error << "PCDUHandler::initialize: Invalid pdu1Handler" << std::endl; return RETURN_FAILED; } - result = pdu1Handler->getSubscriptionInterface()->subscribeForSetUpdateMessages( + result = pdu1Handler->getSubscriptionInterface()->subscribeForSetUpdateMessage( PDU1::HK_TABLE_DATA_SET_ID, this->getObjectId(), commandQueue->getId(), true); if (result != RETURN_OK) { sif::error << "PCDUHandler::initialize: Failed to subscribe for set update messages from " diff --git a/mission/devices/SyrlinksHkHandler.cpp b/mission/devices/SyrlinksHkHandler.cpp index d9b05b18..bab5e551 100644 --- a/mission/devices/SyrlinksHkHandler.cpp +++ b/mission/devices/SyrlinksHkHandler.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include SyrlinksHkHandler::SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : @@ -364,7 +364,7 @@ ReturnValue_t SyrlinksHkHandler::verifyReply(const uint8_t* packet, uint8_t size } void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) { - PoolReadHelper readHelper(&rxDataset); + PoolReadGuard readHelper(&rxDataset); uint16_t offset = SYRLINKS::MESSAGE_HEADER_SIZE; rxDataset.rxStatus = convertHexStringToUint8(reinterpret_cast(packet + offset)); offset += 2; @@ -396,7 +396,7 @@ void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) { } void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) { - PoolReadHelper readHelper(&txDataset); + PoolReadGuard readHelper(&txDataset); uint16_t offset = SYRLINKS::MESSAGE_HEADER_SIZE; txDataset.txStatus = convertHexStringToUint8(reinterpret_cast(packet + offset)); #if OBSW_VERBOSE_LEVEL >= 1 && SYRLINKS_DEBUG == 1 @@ -406,7 +406,7 @@ void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) { } void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) { - PoolReadHelper readHelper(&txDataset); + PoolReadGuard readHelper(&txDataset); uint16_t offset = SYRLINKS::MESSAGE_HEADER_SIZE; txDataset.txWaveform = convertHexStringToUint8(reinterpret_cast(packet + offset)); #if OBSW_VERBOSE_LEVEL >= 1 && SYRLINKS_DEBUG == 1 @@ -416,7 +416,7 @@ void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) { } void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) { - PoolReadHelper readHelper(&txDataset); + PoolReadGuard readHelper(&txDataset); uint16_t offset = SYRLINKS::MESSAGE_HEADER_SIZE; txDataset.txAgcValue = agcValueHighByte << 8 | convertHexStringToUint8(reinterpret_cast(packet + offset)); #if OBSW_VERBOSE_LEVEL >= 1 && SYRLINKS_DEBUG == 1 @@ -425,7 +425,7 @@ void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) { } void SyrlinksHkHandler::parseAgcHighByte(const uint8_t* packet) { - PoolReadHelper readHelper(&txDataset); + PoolReadGuard readHelper(&txDataset); uint16_t offset = SYRLINKS::MESSAGE_HEADER_SIZE; agcValueHighByte = convertHexStringToUint8(reinterpret_cast(packet + offset)); } diff --git a/mission/devices/devicedefinitions/GyroL3GD20Definitions.h b/mission/devices/devicedefinitions/GyroL3GD20Definitions.h index d2fa9903..30669b1d 100644 --- a/mission/devices/devicedefinitions/GyroL3GD20Definitions.h +++ b/mission/devices/devicedefinitions/GyroL3GD20Definitions.h @@ -1,11 +1,15 @@ #ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_ +#include #include #include namespace L3GD20H { +/* Actual size is 15 but we round up a bit */ +static constexpr size_t MAX_BUFFER_SIZE = 16; + static constexpr uint8_t READ_MASK = 0b1000'0000; static constexpr uint8_t AUTO_INCREMENT_MASK = 0b0100'0000; @@ -22,7 +26,7 @@ static constexpr uint8_t CTRL_REG_3 = 0b0010'0010; static constexpr uint8_t CTRL_REG_4 = 0b0010'0011; static constexpr uint8_t CTRL_REG_5 = 0b0010'0100; -// Register 1 +/* Register 1 */ static constexpr uint8_t SET_DR_1 = 1 << 7; static constexpr uint8_t SET_DR_0 = 1 << 6; static constexpr uint8_t SET_BW_1 = 1 << 5; @@ -35,7 +39,7 @@ static constexpr uint8_t SET_Y_ENABLE = 1; static constexpr uint8_t CTRL_REG_1_VAL = SET_POWER_NORMAL_MODE | SET_Z_ENABLE | SET_Y_ENABLE | SET_X_ENABLE; -// Register 2 +/* Register 2 */ static constexpr uint8_t EXTERNAL_EDGE_ENB = 1 << 7; static constexpr uint8_t LEVEL_SENSITIVE_TRIGGER = 1 << 6; static constexpr uint8_t SET_HPM_1 = 1 << 5; @@ -47,10 +51,10 @@ static constexpr uint8_t SET_HPCF_0 = 1; static constexpr uint8_t CTRL_REG_2_VAL = 0b0000'0000; -// Register 3 +/* Register 3 */ static constexpr uint8_t CTRL_REG_3_VAL = 0b0000'0000; -// Register 4 +/* Register 4 */ static constexpr uint8_t SET_BNU = 1 << 7; static constexpr uint8_t SET_BLE = 1 << 6; static constexpr uint8_t SET_FS_1 = 1 << 5; @@ -60,15 +64,16 @@ static constexpr uint8_t SET_SELF_TEST_ENB_1 = 1 << 2; static constexpr uint8_t SET_SELF_TEST_ENB_0 = 1 << 1; static constexpr uint8_t SET_SPI_IF_SELECT = 1; -static constexpr uint8_t CTRL_REG_4_VAL = 0b0000'0000; +/* Enable big endian data format */ +static constexpr uint8_t CTRL_REG_4_VAL = SET_BLE; -// Register 5 +/* Register 5 */ static constexpr uint8_t SET_REBOOT_MEM = 1 << 7; static constexpr uint8_t SET_FIFO_ENB = 1 << 6; static constexpr uint8_t CTRL_REG_5_VAL = 0b0000'0000; -// In degrees per second (DPS) for now. +/* Possible range values in degrees per second (DPS). */ static constexpr uint16_t RANGE_DPS_00 = 245; static constexpr uint16_t RANGE_DPS_01 = 500; static constexpr uint16_t RANGE_DPS_11 = 2000; @@ -76,16 +81,16 @@ static constexpr uint16_t RANGE_DPS_11 = 2000; static constexpr uint8_t READ_START = CTRL_REG_1; static constexpr size_t READ_LEN = 14; -// Indexing +/* Indexing */ static constexpr uint8_t REFERENCE_IDX = 6; static constexpr uint8_t TEMPERATURE_IDX = 7; static constexpr uint8_t STATUS_IDX = 8; -static constexpr uint8_t OUT_X_L = 9; -static constexpr uint8_t OUT_X_H = 10; -static constexpr uint8_t OUT_Y_L = 11; -static constexpr uint8_t OUT_Y_H = 12; -static constexpr uint8_t OUT_Z_L = 13; -static constexpr uint8_t OUT_Z_H = 14; +static constexpr uint8_t OUT_X_H = 9; +static constexpr uint8_t OUT_X_L = 10; +static constexpr uint8_t OUT_Y_H = 11; +static constexpr uint8_t OUT_Y_L = 12; +static constexpr uint8_t OUT_Z_H = 13; +static constexpr uint8_t OUT_Z_L = 14; /*------------------------------------------------------------------------*/ /* Device Handler specific */ @@ -103,27 +108,33 @@ enum GyroPoolIds: lp_id_t { TEMPERATURE }; -class GyroPrimaryDataset: public StaticLocalDataSet<3 * sizeof(float)> { -public: - GyroPrimaryDataset(HasLocalDataPoolIF* hkOwner): - StaticLocalDataSet(hkOwner, GYRO_DATASET_ID) {} - - GyroPrimaryDataset(object_id_t mgmId): - StaticLocalDataSet(sid_t(mgmId, GYRO_DATASET_ID)) {} - - // Angular velocities in degrees per second (DPS) - lp_var_t angVelocX = lp_var_t(sid.objectId, - ANG_VELOC_X, this); - lp_var_t angVelocY = lp_var_t(sid.objectId, - ANG_VELOC_Y, this); - lp_var_t angVelocZ = lp_var_t(sid.objectId, - ANG_VELOC_Z, this); - lp_var_t temperature = lp_var_t(sid.objectId, - TEMPERATURE, this); -}; - } +class GyroPrimaryDataset: public StaticLocalDataSet<3 * sizeof(float)> { +public: + + /** Constructor for data users like controllers */ + GyroPrimaryDataset(object_id_t mgmId): + StaticLocalDataSet(sid_t(mgmId, L3GD20H::GYRO_DATASET_ID)) { + setAllVariablesReadOnly(); + } + + /* Angular velocities in degrees per second (DPS) */ + lp_var_t angVelocX = lp_var_t(sid.objectId, + L3GD20H::ANG_VELOC_X, this); + lp_var_t angVelocY = lp_var_t(sid.objectId, + L3GD20H::ANG_VELOC_Y, this); + lp_var_t angVelocZ = lp_var_t(sid.objectId, + L3GD20H::ANG_VELOC_Z, this); + lp_var_t temperature = lp_var_t(sid.objectId, + L3GD20H::TEMPERATURE, this); +private: + + friend class GyroHandlerL3GD20H; + /** Constructor for the data creator */ + GyroPrimaryDataset(HasLocalDataPoolIF* hkOwner): + StaticLocalDataSet(hkOwner, L3GD20H::GYRO_DATASET_ID) {} +}; #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_ */ diff --git a/mission/devices/devicedefinitions/MGMHandlerLIS3Definitions.h b/mission/devices/devicedefinitions/MGMHandlerLIS3Definitions.h index 0d51cda1..b8b2463d 100644 --- a/mission/devices/devicedefinitions/MGMHandlerLIS3Definitions.h +++ b/mission/devices/devicedefinitions/MGMHandlerLIS3Definitions.h @@ -15,6 +15,9 @@ enum opMode { LOW, MEDIUM, HIGH, ULTRA }; +/* Actually 15, we just round up a bit */ +static constexpr size_t MAX_BUFFER_SIZE = 16; + static constexpr uint8_t GAUSS_TO_MICROTESLA_FACTOR = 100; static const DeviceCommandId_t SETUP_MGM = 0x00; diff --git a/mission/devices/devicedefinitions/MGMHandlerRM3100Definitions.h b/mission/devices/devicedefinitions/MGMHandlerRM3100Definitions.h index 921c9e5f..2856c170 100644 --- a/mission/devices/devicedefinitions/MGMHandlerRM3100Definitions.h +++ b/mission/devices/devicedefinitions/MGMHandlerRM3100Definitions.h @@ -9,6 +9,9 @@ namespace RM3100 { +/* Actually 10, we round up a little bit */ +static constexpr size_t MAX_BUFFER_SIZE = 12; + static constexpr uint8_t READ_MASK = 0b1000'0000; /*----------------------------------------------------------------------------*/ diff --git a/test/testtasks/TestTask.cpp b/test/testtasks/TestTask.cpp index 57abc758..86f4af38 100644 --- a/test/testtasks/TestTask.cpp +++ b/test/testtasks/TestTask.cpp @@ -68,7 +68,7 @@ gps_rx_data[] = "" ReturnValue_t TestTask::performOneShotAction() { #if OBSW_ADD_TEST_CODE == 1 - performLwgpsTest(); + //performLwgpsTest(); #endif return HasReturnvaluesIF::RETURN_OK; }