diff --git a/src/shared/sensors/VN100/VN100Spi.cpp b/src/shared/sensors/VN100/VN100Spi.cpp index a2089312b5cdec008daf22f664edfe11dd2c1a5f..21e1315f70de8290c4bbefd755e548e3d77dd29b 100644 --- a/src/shared/sensors/VN100/VN100Spi.cpp +++ b/src/shared/sensors/VN100/VN100Spi.cpp @@ -32,8 +32,9 @@ namespace Boardcore { VN100Spi::VN100Spi(SPIBus& bus, miosix::GpioPin csPin, - SPIBusConfig busConfiguration) - : spiSlave(bus, csPin, busConfiguration) + SPIBusConfig busConfiguration, uint16_t syncOutSkipFactor) + : spiSlave(bus, csPin, busConfiguration), + syncOutSkipFactor(syncOutSkipFactor) { } @@ -50,13 +51,20 @@ bool VN100Spi::init() // Send dummy data to clean up sendDummyPacket(); - if (checkModelNumber() == false) + if (!checkModelNumber()) { LOG_ERR(logger, "Got bad CHIPID"); lastError = SensorErrors::INVALID_WHOAMI; return false; } + if (!setInterrupt()) + { + LOG_ERR(logger, "Unable to set data ready interrupt"); + lastError = SensorErrors::INIT_FAIL; + return false; + } + isInit = true; lastError = SensorErrors::NO_ERRORS; return true; @@ -102,6 +110,46 @@ void VN100Spi::sendDummyPacket() transaction.write32(0); } +bool VN100Spi::setInterrupt() +{ + /** + * The data ready interrupt is set via the synchronization control register, + * by setting the SyncOut mode. + * + * Imu data is sampled at 800Hz, while Attitude data (quaternion) is sampled + * at 400 Hz. Considering that attitude data has a lower rate we set the + * data ready to trigger on attitude data. + * + * We can set the SyncOutSkipFactor, that defines how many times the sync + * out event should be skipped before actually triggering the SyncOut pin. + * This way we can control the rate at which the data ready interrupt is + * triggered. + * + * The values not needed for the data ready of the register will be set to + * default. + */ + + // Init struct and set default values + VN100SpiDefs::SynchronizationData sData; + sData.syncInMode = 3; // Set to: count number of trigger events on SYNC_IN. + sData.syncInEdge = 0; // Trigger on rising edge + sData.syncInSkipFactor = 0; // Don't skip + + // Set needed values + sData.syncOutMode = 3; // Trigger when attitude measurements are available + sData.syncOutPolarity = 1; // Positive output pulse on the SyncOut pin + sData.syncOutSkipFactor = syncOutSkipFactor; + sData.syncOutPulseWidth = + 1000000; // Width of the SyncOut pulse in nanoseconds. Now is set to 1 + // millisecond + // TODO: is 1ms fine for syncOutPulseWidth? Too long? Too short? + + uint8_t err = writeRegister(VN100SpiDefs::REG_SYNC, (uint8_t*)&sData, + sizeof(VN100SpiDefs::SynchronizationData)); + + return err == 0; +} + bool VN100Spi::selfTest() { D(assert(isInit && "init() was not called")); diff --git a/src/shared/sensors/VN100/VN100Spi.h b/src/shared/sensors/VN100/VN100Spi.h index 0e42910850f919a3cbd7f60884a189666a220b46..5c95de59486885f14f8531a23edb1aeb996290b6 100644 --- a/src/shared/sensors/VN100/VN100Spi.h +++ b/src/shared/sensors/VN100/VN100Spi.h @@ -43,8 +43,12 @@ public: * @param bus SPI bus. * @param csPin SPI chip select pin. * @param busConfiguration SPI bus configuration. + * @param syncOutSkipFactor The SyncOutSkipFactor defines how many times the + * data ready event should be skipped before actually triggering the + * interrupt pin. */ - VN100Spi(SPIBus& bus, miosix::GpioPin csPin, SPIBusConfig busConfiguration); + VN100Spi(SPIBus& bus, miosix::GpioPin csPin, SPIBusConfig busConfiguration, + uint16_t syncOutSkipFactor); /** * @brief Initialize the sensor. @@ -79,6 +83,13 @@ private: void sendDummyPacket(); // TODO: check if really needed and if there is a better solution + /** + * @brief Set the data ready interrupt. + * + * @return True if the operation is successful, false otherwise. + */ + bool setInterrupt(); + /** * @brief Get accelerometer, gyroscope, magnetometer, pressure and * temperature measurements from the sensor. @@ -139,6 +150,13 @@ private: SPISlave spiSlave; + /** + * @brief The SyncOutSkipFactor defines how many times the sync out event + * should be skipped before actually triggering the SyncOut pin (data + * ready). + */ + const uint16_t syncOutSkipFactor = 0; + PrintLogger logger = Logging::getLogger("vn100-spi"); // TODO: is it fine? Should it be // changed to the exact model number? diff --git a/src/shared/sensors/VN100/VN100SpiDefs.h b/src/shared/sensors/VN100/VN100SpiDefs.h index 64e8c86027811ec6870aa37a34fad96e8591b51b..c60936bfdf82d5fc6c38c0515f2769df5b6f336f 100644 --- a/src/shared/sensors/VN100/VN100SpiDefs.h +++ b/src/shared/sensors/VN100/VN100SpiDefs.h @@ -33,9 +33,10 @@ namespace VN100SpiDefs */ enum Registers { - REG_MODEL_NUMBER = 1, - REG_QUATERNION_DATA = 9, - REG_IMU_DATA = 54, + REG_MODEL_NUMBER = 1, ///< WhoAmI register + REG_QUATERNION_DATA = 9, ///< Quaternion data register + REG_SYNC = 32, ///< Used to set data ready interrupt + REG_IMU_DATA = 54, ///< Imu data register }; /** @@ -47,6 +48,29 @@ enum Commands WRITE_REG = 2, }; +/** + * @brief Data format of the synchronization control register, used for reading + * and writing operations. + */ +struct __attribute__((packed)) SynchronizationData +{ + uint8_t syncInMode; ///< Behaviour of the syncIn event + uint8_t syncInEdge; ///< Trigger syncIn on rising or falling edge + uint16_t syncInSkipFactor; ///< How many times trigger edges defined by + ///< SyncInEdge should occur prior to triggering + ///< a SyncIn event + const uint32_t RESERVED = 0; ///< Reserved, do not use + uint8_t syncOutMode; ///< Behavior of the SyncOut event + uint8_t syncOutPolarity; ///< The polarity of the output pulse on the + ///< SyncOut pin (positive or negative) + uint16_t syncOutSkipFactor; ///< how many times the sync out event should + ///< be skipped before actually triggering the + ///< SyncOut pin + uint32_t + syncOutPulseWidth; ///< Controls the desired width of the SyncOut pulse + const uint32_t RESERVED2 = 0; ///< Reserved, do not use +}; + /** * @brief The expected model number to be red from the sensor. */ diff --git a/src/tests/sensors/test-vn100-spi.cpp b/src/tests/sensors/test-vn100-spi.cpp index c94d91c2999bbb3389a5bf328f28dad791766262..9bdbc30c7109c703edabb9719183f108d1b035d4 100644 --- a/src/tests/sensors/test-vn100-spi.cpp +++ b/src/tests/sensors/test-vn100-spi.cpp @@ -43,12 +43,15 @@ int main() mosiPin.alternateFunction(6); mosiPin.mode(Mode::ALTERNATE); + GpioPin intPin(GPIOC_BASE, 15); // PC15 interrupt pin + intPin.mode(Mode::INPUT); + SPIBusConfig busConfiguration; // Bus configuration for the sensor busConfiguration.clockDivider = SPI::ClockDivider::DIV_256; busConfiguration.mode = SPI::Mode::MODE_3; // Set clock polarity to 0 and phase to 1 - VN100Spi sensor(bus, csPin, busConfiguration); + VN100Spi sensor(bus, csPin, busConfiguration, 200); // Let the sensor start up Thread::sleep(1000);