diff --git a/CMakeLists.txt b/CMakeLists.txt index 109b9ba29f8b07600c8b8464d6aed6da55db9937..197c8e5e501c4239fb7514fc2eb0dfce6743c0f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -404,6 +404,8 @@ sbs_target(test-vn100 stm32f407vg_stm32f4discovery) add_executable(test-lis2mdl src/tests/sensors/test-lis2mdl.cpp) sbs_target(test-lis2mdl stm32f429zi_stm32f4discovery) +add_executable(test-h3lis331dl src/tests/sensors/test-h3lis331dl.cpp) +sbs_target(test-h3lis331dl stm32f407vg_stm32f4discovery) #-----------------------------------------------------------------------------# # Tests - Utils # diff --git a/cmake/boardcore.cmake b/cmake/boardcore.cmake index 5daaab18e1681713b0d138029da8547541920e9c..d600f341f11d7f0700f378598f3363f18c526e2b 100644 --- a/cmake/boardcore.cmake +++ b/cmake/boardcore.cmake @@ -87,6 +87,7 @@ foreach(OPT_BOARD ${BOARDS}) ${SBS_BASE}/src/shared/sensors/BMP280/BMP280I2C.cpp ${SBS_BASE}/src/shared/sensors/BMX160/BMX160.cpp ${SBS_BASE}/src/shared/sensors/BMX160/BMX160WithCorrection.cpp + ${SBS_BASE}/src/shared/sensors/H3LIS331DL/H3LIS331DL.cpp ${SBS_BASE}/src/shared/sensors/HX711/HX711.cpp ${SBS_BASE}/src/shared/sensors/LIS3MDL/LIS3MDL.cpp ${SBS_BASE}/src/shared/sensors/LIS331HH/LIS331HH.cpp diff --git a/src/shared/sensors/H3LIS331DL/H3LIS331DL.cpp b/src/shared/sensors/H3LIS331DL/H3LIS331DL.cpp new file mode 100644 index 0000000000000000000000000000000000000000..634704a747c9482e979a21fcafb888f978f1aa46 --- /dev/null +++ b/src/shared/sensors/H3LIS331DL/H3LIS331DL.cpp @@ -0,0 +1,178 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Radu Raul + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "H3LIS331DL.h" + +namespace Boardcore +{ + +H3LIS331DL::H3LIS331DL(SPIBusInterface& spiBus, miosix::GpioPin cs, + SPIBusConfig cfg, H3LIS331DLDefs::OutputDataRate odr, + H3LIS331DLDefs::BlockDataUpdate bdu, + H3LIS331DLDefs::FullScaleRange fs) + : spi(spiBus, cs, cfg), odr(odr), bdu(bdu), fs(fs), initialized(false) +{ + spi.config.byteOrder = SPI::Order::LSB_FIRST; + spi.config.mode = SPI::Mode::MODE_3; +} + +H3LIS331DL::H3LIS331DL(SPIBusInterface& spiBus, miosix::GpioPin cs, + H3LIS331DLDefs::OutputDataRate odr, + H3LIS331DLDefs::BlockDataUpdate bdu, + H3LIS331DLDefs::FullScaleRange fs) + : H3LIS331DL(spiBus, cs, {}, odr, bdu, fs) +{ +} + +bool H3LIS331DL::init() +{ + if (initialized) + { + lastError = SensorErrors::ALREADY_INIT; + return false; + } + + SPITransaction spiTr(spi); + + uint8_t whoami = + spiTr.readRegister(H3LIS331DLDefs::Registers::REG_WHO_AM_I); + + if (whoami != H3LIS331DLDefs::WHO_AM_I_ID) + { + lastError = SensorErrors::INVALID_WHOAMI; + LOG_ERR(logger, + "Failed init. Cause: INVALID_WHOAMI. Expected Value: " + "{:X}. Actual Value: {:X}\n", + H3LIS331DLDefs::WHO_AM_I_ID, whoami); + return false; + } + + // We assume everything is okay, if there are issues while writing the + // configuration we will set this flag to false + initialized = true; + + // CTRL_REG1 initialization + { + uint8_t ctrlReg1 = 0b0000'0000; // Default: poweroff + + ctrlReg1 = odr | H3LIS331DLDefs::CTRL_REG1_XEN | + H3LIS331DLDefs::CTRL_REG1_YEN | + H3LIS331DLDefs::CTRL_REG1_ZEN; + + spiTr.writeRegister(H3LIS331DLDefs::Registers::REG_CTRL_REG1, ctrlReg1); + + miosix::delayUs(10); + initialized &= + (ctrlReg1 == + spiTr.readRegister(H3LIS331DLDefs::Registers::REG_CTRL_REG1)); + + LOG_DEBUG(logger, + "Control Register 1 After init: {:X}, expected " + "value:{:X}", + spiTr.readRegister(H3LIS331DLDefs::Registers::REG_CTRL_REG1), + ctrlReg1); + } + + { + // CTRL_REG4 initialization + // CTRL_REG4 controls the BDU (@see H3LIS331DL::BlockDataUpdate) and + // the FSR (@see H3LIS331DL::FullScaleRange). + uint8_t ctrlReg4 = 0b0000'0000; + + ctrlReg4 = bdu | fs; + + spiTr.writeRegister(H3LIS331DLDefs::Registers::REG_CTRL_REG4, ctrlReg4); + + miosix::delayUs(10); + initialized &= + (ctrlReg4 == + spiTr.readRegister(H3LIS331DLDefs::Registers::REG_CTRL_REG4)); + LOG_DEBUG(logger, + "Control Register 4 After init: {:X}, expected " + "value: {:X}", + spiTr.readRegister(H3LIS331DLDefs::Registers::REG_CTRL_REG4), + ctrlReg4); + } + + return initialized; +} + +bool H3LIS331DL::selfTest() { return true; } + +H3LIS331DLData H3LIS331DL::sampleImpl() +{ + if (!initialized) + { + lastError = SensorErrors::NOT_INIT; + return lastSample; + } + + // Timestamp of the last sample + uint64_t lastSampleTimestamp = TimestampTimer::getTimestamp(); + + float x = 0; + float y = 0; + float z = 0; + + // Read output data registers (X, Y, Z) + { + SPITransaction spiTr(spi); + uint8_t buff[7]; + + spiTr.readRegisters(H3LIS331DLDefs::Registers::REG_STATUS_REG | + H3LIS331DLDefs::AUTOINC_ADDR, + buff, 7); + + // The status register that tells if new data is available is the first + // byte that was read from the 7 byte read. + uint8_t status = buff[0]; + uint16_t regX = buff[2] << 8 | buff[1]; + uint16_t regY = buff[4] << 8 | buff[3]; + uint16_t regZ = buff[6] << 8 | buff[5]; + + if (!(status & H3LIS331DLDefs::STATUS_REG_XYZDR)) + { + lastError = SensorErrors::NO_NEW_DATA; + LOG_DEBUG(logger, "No new data available."); + return lastSample; + } + + // Here we get the sensitivity based on the FullScaleRange + float sensitivity = H3LIS331DLDefs::SENSITIVITY_VALUES[fs >> 4]; + + int16_t xInt = static_cast<int16_t>(regX); + float xFloat = static_cast<float>(xInt >> 4); + x = xFloat * sensitivity; + + int16_t yInt = static_cast<int16_t>(regY); + float yFloat = static_cast<float>(yInt >> 4); + y = yFloat * sensitivity; + + int16_t zInt = static_cast<int16_t>(regZ); + float zFloat = static_cast<float>(zInt >> 4); + z = zFloat * sensitivity; + } + + return H3LIS331DLData(lastSampleTimestamp, x, y, z); +} + +} // namespace Boardcore diff --git a/src/shared/sensors/H3LIS331DL/H3LIS331DL.h b/src/shared/sensors/H3LIS331DL/H3LIS331DL.h new file mode 100644 index 0000000000000000000000000000000000000000..b8d0c11b847fd08db923f5d083c84b84fc9ae966 --- /dev/null +++ b/src/shared/sensors/H3LIS331DL/H3LIS331DL.h @@ -0,0 +1,150 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Radu Raul + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include <diagnostic/PrintLogger.h> +#include <drivers/spi/SPIDriver.h> +#include <drivers/timer/TimestampTimer.h> +#include <miosix.h> +#include <sensors/Sensor.h> + +#include "H3LIS331DLData.h" +#include "H3LIS331DLDefs.h" + +namespace Boardcore +{ + +/** + * Driver for H3LIS331DL, a 3-Axis, high g Accelerometer Sensor made by + * STMicroelectronics. + */ +class H3LIS331DL : public Sensor<H3LIS331DLData> +{ + +public: + /** + * @brief Creates an instance of an H3LIS331DL sensor + * + * @param spiBus The SPI bus the sensor is connected to + * @param cs The Chip Select GPIO + * @param odr Sensor's Output Data Rate (See datasheet) + * @param bdu Sensor's Block Data Update (See datasheet) + * @param fs Sensor's Full Scale Range (See datasheet) + */ + H3LIS331DL(SPIBusInterface& spiBus, miosix::GpioPin cs, + H3LIS331DLDefs::OutputDataRate odr, + H3LIS331DLDefs::BlockDataUpdate bdu, + H3LIS331DLDefs::FullScaleRange fs); + + /** + * @brief Creates an instance of an H3LIS331DL sensor + * + * @param spiBus The SPI bus the sensor is connected to + * @param cs The Chip Select GPIO + * @param cfg SPI Bus Configuration + * @param odr Sensor's Output Data Rate (See datasheet) + * @param bdu Sensor's Block Data Update (See datasheet) + * @param fs Sensor's Full Scale Range (See datasheet) + */ + H3LIS331DL(SPIBusInterface& spiBus, miosix::GpioPin cs, SPIBusConfig cfg, + H3LIS331DLDefs::OutputDataRate odr, + H3LIS331DLDefs::BlockDataUpdate bdu, + H3LIS331DLDefs::FullScaleRange fs); + + /** + * @brief Initializes the H3LIS331DL + * + * The init function writes the configuration to the configuration + * registers so no further writes are needed. + * + * @returns True if the initialization was OK. Returns False otherwise (use + * getLastError()) method to get information about the last error. + */ + bool init(); + + /** + * @brief Samples data from the register. + * + * This method reads the data from the 3 pairs (one pair for each axis) of + * 8bit registers and convert it to floating point value based on the Full + * Scale Range specified at construction time. + * The data is returned in the H3LIS331DLData struct correlated to a + * timestamp of when the data was sampled. + * + * @returns A copy of an instance of H3LIS331DLData. + */ + H3LIS331DLData sampleImpl() override; + + /** + * @brief This method does nothing as no self test is implemented in the + * sensor + * + * @returns True always. + */ + bool selfTest(); + +private: + /** + * @brief The SPI driver used to create SPI Transactions + */ + SPISlave spi; + + /** + * @brief The OutputDataRate that is set to the sensor. + * + * Default: 50 HZ (@see OutputDataRate::ODR_50) + * + * Note: setting the ODR also sets the PowerMode. + * If the ODR is less than ODR_50 low PowerMode is set. + * Otherwise normal PowerMode is set. + */ + H3LIS331DLDefs::OutputDataRate odr; + + /** + * @brief The BlockDataUpdate that is set to the sensor. + * + * Default: Continuos Update (@see + * H3LIS331DL::BlockDataUpdate::BDU_CONTINUOS_UPDATE) + */ + H3LIS331DLDefs::BlockDataUpdate bdu; + + /** + * @brief The Full Scale Range set to the sensor. + * + * Default: +-100 (@see H3LIS331DL::FullScaleRange::FS_100) + * + * Note: setting the FSR also changes the sensitivity of the sensor. + */ + H3LIS331DLDefs::FullScaleRange fs; + + /** + * @brief True if the sensor is already initialized, False otherwise. + * + * Note: This is only changed by init, read by init and sampleImpl. + */ + bool initialized; + + PrintLogger logger = Logging::getLogger("h3lis331dl"); +}; + +} // namespace Boardcore diff --git a/src/shared/sensors/H3LIS331DL/H3LIS331DLData.h b/src/shared/sensors/H3LIS331DL/H3LIS331DLData.h new file mode 100644 index 0000000000000000000000000000000000000000..054ef30c44965a34f08c18cc27bcc8680d48f3fa --- /dev/null +++ b/src/shared/sensors/H3LIS331DL/H3LIS331DLData.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Radu Raul + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include <sensors/SensorData.h> + +namespace Boardcore +{ + +struct H3LIS331DLData : public AccelerometerData +{ + + H3LIS331DLData() : AccelerometerData(0, 0, 0, 0){}; + + H3LIS331DLData(uint64_t ts, float aX, float aY, float aZ) + : AccelerometerData(ts, aX, aY, aZ){}; + + explicit H3LIS331DLData(AccelerometerData acc) : AccelerometerData(acc){}; + + static std::string header() + { + return "timestamp,accelerationX,accelerationY,accelerationZ\n"; + } + + void print(std::ostream& os) const + { + os << accelerationTimestamp << "," << accelerationX << "," + << accelerationY << "," << accelerationZ << "\n"; + } +}; + +} // namespace Boardcore diff --git a/src/shared/sensors/H3LIS331DL/H3LIS331DLDefs.h b/src/shared/sensors/H3LIS331DL/H3LIS331DLDefs.h new file mode 100644 index 0000000000000000000000000000000000000000..57394833eefa852446e519a2c99dae95796c421a --- /dev/null +++ b/src/shared/sensors/H3LIS331DL/H3LIS331DLDefs.h @@ -0,0 +1,128 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Radu Raul + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +namespace Boardcore +{ + +namespace H3LIS331DLDefs +{ + +/** + * @brief Constants for the FullScale Range. + * + * Note: it also changes the sensitivity [mg/digit] (see datasheet). + */ +enum FullScaleRange +{ + FS_100 = 0 << 4, ///< +-100 g, sensitivity: 0.049 mg/digit + FS_200 = 1 << 4, ///< +-200 g, sensitivity: 0.098 mg/digit + FS_400 = 3 << 4 ///< +-400 g, sensitivity: 0.195 mg/digit +}; + +/** + * @brief Constants for Output Data Rate configuration. + * + * Note: The ODR also sets the Sensor's Power Mode as it is strictly + * dependant on the ODR (See datasheet). + * As the ODR is set differently based on the Power Mode the ODRs including + * and after ODR_50 will be offsetted to 0 by subtracting ODR_50. + */ +enum OutputDataRate +{ + ODR_LP_0_5 = 0b010 << 5, ///< 0.5 Hz low power mode + ODR_LP_1 = 0b011 << 5, ///< 1 Hz low power mode + ODR_LP_2 = 0b100 << 5, ///< 2 Hz low power mode + ODR_LP_5 = 0b101 << 5, ///< 5 Hz low power mode + ODR_LP_10 = 0b110 << 5, ///< 10 Hz low power mode + ODR_50 = 0b001 << 5 | 0b00 << 3, ///< 50 Hz normal power mode + ODR_100 = 0b001 << 5 | 0b01 << 3, ///< 100 Hz normal power mode + ODR_400 = 0b001 << 5 | 0b10 << 3, ///< 400 Hz normal power mode + ODR_1000 = 0b001 << 5 | 0b11 << 3 ///< 1000 Hz normal power mode +}; + +/** + * @brief Constants for Block Data Update + */ +enum BlockDataUpdate +{ + BDU_CONTINUOS_UPDATE = 0 << 7, + BDU_WAIT_UNTIL_READ = 1 << 7 +}; + +/** + * @brief Constants for the Registers + */ +enum Registers +{ + REG_WHO_AM_I = 0x0F, + REG_CTRL_REG1 = 0x20, + REG_CTRL_REG2 = 0x21, + REG_CTRL_REG3 = 0x22, + REG_CTRL_REG4 = 0x23, + REG_CTRL_REG5 = 0x24, + REG_STATUS_REG = 0x27, + REG_OUT_X_L = 0x28, + REG_OUT_X_H = 0x29, + REG_OUT_Y_L = 0x2a, + REG_OUT_Y_H = 0x2b, + REG_OUT_Z_L = 0x2c, + REG_OUT_Z_H = 0x2d +}; + +/** + * @brief magic numbers for the Status Register + */ +enum Statuses : uint8_t +{ + STATUS_REG_XDR = 0b0000'0001, ///< Data Ready on X-Axis + STATUS_REG_YDR = 0b0000'0010, ///< Data Ready on Y-Axis + STATUS_REG_ZDR = 0b0000'0100, ///< Data Ready on Z-Axis + STATUS_REG_XYZDR = 0b0000'1000, ///< Data Ready on All Axis + STATUS_REG_XOR = 0b0001'0000, ///< Data Overrun on X-Axis + STATUS_REG_YOR = 0b0010'0000, ///< Data Overrun on Y-Axis + STATUS_REG_ZOR = 0b0100'0000, ///< Data Overrun on Z-Axis + STATUS_REG_XYZOR = 0b1000'0000 ///< Data Overrun on All Axis +}; + +constexpr uint8_t CTRL_REG1_XEN = 0b001; +constexpr uint8_t CTRL_REG1_YEN = 0b010; +constexpr uint8_t CTRL_REG1_ZEN = 0b100; + +/** + * @brief make the driver automatically increase the register address when + * reading multiple bytes with SPI. + */ +constexpr uint8_t AUTOINC_ADDR = 0b0100'0000; + +const uint8_t WHO_AM_I_ID = 0x32; + +/** + * @brief Constants for the sensitivity values based on the Full Scale Range. + * + * Note: as there is no 0b10 configuration for the FSR the third value is + * set to 0. + */ +constexpr float SENSITIVITY_VALUES[] = {0.049, 0.098, 0.0, 0.195}; + +} // namespace H3LIS331DLDefs + +} // namespace Boardcore diff --git a/src/tests/sensors/test-h3lis331dl.cpp b/src/tests/sensors/test-h3lis331dl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..042f56645d047096c0315f8ddcf26290c4cd72ca --- /dev/null +++ b/src/tests/sensors/test-h3lis331dl.cpp @@ -0,0 +1,102 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Radu Raul + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <drivers/spi/SPIDriver.h> +#include <drivers/timer/TimestampTimer.h> +#include <sensors/H3LIS331DL/H3LIS331DL.h> +#include <utils/Debug.h> + +#include "miosix.h" + +using namespace Boardcore; +using namespace miosix; + +SPIBus bus(SPI1); + +GpioPin spiSck(GPIOA_BASE, 5); +GpioPin spiMiso(GPIOA_BASE, 6); +GpioPin spiMosi(GPIOA_BASE, 7); +GpioPin cs(GPIOE_BASE, 4); + +int main() +{ + Thread::sleep(1000); + + /** + * I need to set the pin speed to Speed::_100MHz to solve a bug with + * stm32f407vg boards that prevented a correct reading from SPI (in this + * scenario) + */ + spiSck.mode(miosix::Mode::ALTERNATE); + spiSck.alternateFunction(5); + spiSck.speed(Speed::_100MHz); + + spiMiso.mode(miosix::Mode::ALTERNATE); + spiMiso.alternateFunction(5); + spiMiso.speed(Speed::_100MHz); + + spiMosi.mode(miosix::Mode::ALTERNATE); + spiMosi.alternateFunction(5); + spiMosi.speed(Speed::_100MHz); + + cs.mode(miosix::Mode::OUTPUT); + cs.high(); + + H3LIS331DL sensor(bus, cs, H3LIS331DLDefs::OutputDataRate::ODR_50, + H3LIS331DLDefs::BlockDataUpdate::BDU_CONTINUOS_UPDATE, + H3LIS331DLDefs::FullScaleRange::FS_100); + + if (!sensor.init()) + { + printf("Failed init!\n"); + if (sensor.getLastError() == SensorErrors::INVALID_WHOAMI) + { + printf("Invalid WHOAMI\n"); + } + return -1; + } + + H3LIS331DLData data; + + // Print out the CSV header + printf(H3LIS331DLData::header().c_str()); + // sample some data from the sensor + for (int i = 0; i < 255; i++) + { + // sensor intitialized, should return error if no new data exist + sensor.sample(); + + // if (sensor.getLastError() == SensorErrors::NO_NEW_DATA) + // { + // printf("\nWarning: no new data to be read \n"); + // } + + data = sensor.getLastSample(); + + printf("%llu,%f,%f,%f\n", data.accelerationTimestamp, + data.accelerationX, data.accelerationY, data.accelerationZ); + + Thread::sleep(100); + } + + return 0; +}