Jacky Tseng
/
imu_driver
handle master side communication of openIMU300ZI module
imu_driver.hpp@24:275e886bd61c, 2019-12-19 (annotated)
- Committer:
- Arithemetica
- Date:
- Thu Dec 19 14:41:25 2019 +0000
- Revision:
- 24:275e886bd61c
- Parent:
- 23:3626c7d73505
- Child:
- 25:3dfd686ae315
wait more time for robustness
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Arithemetica | 7:224ffdacb240 | 1 | /** |
Arithemetica | 7:224ffdacb240 | 2 | * @file imu_driver.hpp |
Arithemetica | 10:d8223969c541 | 3 | * @brief ImuDriver class and other data storage struct definition. The C language version |
Arithemetica | 10:d8223969c541 | 4 | * can be found at <A HREF="https://github.com/osjacky430/imu_driver">this github website</A> |
Arithemetica | 7:224ffdacb240 | 5 | */ |
Arithemetica | 7:224ffdacb240 | 6 | |
Arithemetica | 1:8e31413068af | 7 | #ifndef IMU_DRIVER_HPP_ |
Arithemetica | 1:8e31413068af | 8 | #define IMU_DRIVER_HPP_ |
Arithemetica | 1:8e31413068af | 9 | |
Arithemetica | 0:8c01a98a2812 | 10 | #include <mbed.h> |
Arithemetica | 0:8c01a98a2812 | 11 | #include <cstdint> |
Arithemetica | 0:8c01a98a2812 | 12 | |
Arithemetica | 14:6c31a7ab45f0 | 13 | typedef enum ImuExtiConfig { |
Arithemetica | 14:6c31a7ab45f0 | 14 | ImuExtiRcvNotUsed = 0b00, |
Arithemetica | 14:6c31a7ab45f0 | 15 | ImuExtiRcvNormalMsg = 0b01, |
Arithemetica | 23:3626c7d73505 | 16 | ImuExtiRcvAhrsMsg = 0b10, |
Arithemetica | 23:3626c7d73505 | 17 | ImuExtiRcvBothMsg = 0b11 |
Arithemetica | 14:6c31a7ab45f0 | 18 | } ImuExtiConfig; |
Arithemetica | 14:6c31a7ab45f0 | 19 | |
Arithemetica | 20:19f5c94f8660 | 20 | /* this needs to be extended (IMO) */ |
Arithemetica | 19:3ee54f9a56f3 | 21 | inline ImuExtiConfig operator |(ImuExtiConfig const& left, ImuExtiConfig const& right) |
Arithemetica | 19:3ee54f9a56f3 | 22 | { |
Arithemetica | 19:3ee54f9a56f3 | 23 | return ImuExtiConfig(left | right); |
Arithemetica | 19:3ee54f9a56f3 | 24 | } |
Arithemetica | 19:3ee54f9a56f3 | 25 | |
Arithemetica | 17:629b2f317d0a | 26 | /** |
Arithemetica | 17:629b2f317d0a | 27 | * @brief ImuDriverStatus |
Arithemetica | 17:629b2f317d0a | 28 | */ |
Arithemetica | 12:bb490978e153 | 29 | typedef enum ImuDriverStatus { |
Arithemetica | 14:6c31a7ab45f0 | 30 | ImuDriverStatusOK, |
Arithemetica | 14:6c31a7ab45f0 | 31 | ImuDriverStatusDataNotReady, |
Arithemetica | 14:6c31a7ab45f0 | 32 | ImuDriverStatusInvalidCall |
Arithemetica | 14:6c31a7ab45f0 | 33 | } ImuDriverStatus; |
Arithemetica | 12:bb490978e153 | 34 | |
Arithemetica | 0:8c01a98a2812 | 35 | typedef enum ImuDriverRegister { |
Arithemetica | 0:8c01a98a2812 | 36 | ReadAhrsBurstDataRegister = 0x3D, |
Arithemetica | 0:8c01a98a2812 | 37 | ReadBurstDataRegister = 0x3E, |
Arithemetica | 0:8c01a98a2812 | 38 | ReadExtBurstDataRegister = 0x3F |
Arithemetica | 0:8c01a98a2812 | 39 | } ImuDriverRegister; |
Arithemetica | 0:8c01a98a2812 | 40 | |
Arithemetica | 0:8c01a98a2812 | 41 | typedef struct AhrsRawData { |
Arithemetica | 0:8c01a98a2812 | 42 | std::uint16_t status; |
Arithemetica | 0:8c01a98a2812 | 43 | std::int16_t attitude[3]; |
Arithemetica | 0:8c01a98a2812 | 44 | std::int16_t temperature; |
Arithemetica | 0:8c01a98a2812 | 45 | } AhrsRawData; |
Arithemetica | 0:8c01a98a2812 | 46 | |
Arithemetica | 10:d8223969c541 | 47 | /** |
Arithemetica | 12:bb490978e153 | 48 | * @brief AhrsProcessedData is data storage class fpr processed AHRS data |
Arithemetica | 14:6c31a7ab45f0 | 49 | * |
Arithemetica | 11:866dd73e4ab3 | 50 | * The data storage struct consists of: |
Arithemetica | 11:866dd73e4ab3 | 51 | * |
Arithemetica | 10:d8223969c541 | 52 | * - attitude: pitch, roll, yaw in deg, range from -180 ~ +180 deg |
Arithemetica | 10:d8223969c541 | 53 | */ |
Arithemetica | 0:8c01a98a2812 | 54 | typedef struct AhrsProcessedData { |
Arithemetica | 0:8c01a98a2812 | 55 | float attitude[3]; |
Arithemetica | 0:8c01a98a2812 | 56 | } AhrsProcessedData; |
Arithemetica | 0:8c01a98a2812 | 57 | |
Arithemetica | 0:8c01a98a2812 | 58 | typedef struct ImuRawData { |
Arithemetica | 0:8c01a98a2812 | 59 | std::uint16_t status; |
Arithemetica | 0:8c01a98a2812 | 60 | std::int16_t rate[3]; |
Arithemetica | 0:8c01a98a2812 | 61 | std::int16_t accel[3]; |
Arithemetica | 0:8c01a98a2812 | 62 | std::int16_t temperature; |
Arithemetica | 0:8c01a98a2812 | 63 | } ImuRawData; |
Arithemetica | 0:8c01a98a2812 | 64 | |
Arithemetica | 10:d8223969c541 | 65 | /** |
Arithemetica | 11:866dd73e4ab3 | 66 | * @brief ImuProcessedData is data storage class for processed imu data |
Arithemetica | 10:d8223969c541 | 67 | * |
Arithemetica | 11:866dd73e4ab3 | 68 | * This data storage class consists of: |
Arithemetica | 14:6c31a7ab45f0 | 69 | * |
Arithemetica | 10:d8223969c541 | 70 | * - status: if status = 0x0010 (over range error), status = 0 (no error) |
Arithemetica | 10:d8223969c541 | 71 | * - gyroscope: deg/s, range from -300 deg/s ~ 300 deg/s |
Arithemetica | 10:d8223969c541 | 72 | * - accelerometer: g, range from -4.5g ~ 4.5g |
Arithemetica | 10:d8223969c541 | 73 | * - temperature: Celcius |
Arithemetica | 10:d8223969c541 | 74 | */ |
Arithemetica | 0:8c01a98a2812 | 75 | typedef struct ImuProcessedData { |
Arithemetica | 0:8c01a98a2812 | 76 | std::uint16_t status; |
Arithemetica | 0:8c01a98a2812 | 77 | |
Arithemetica | 0:8c01a98a2812 | 78 | float rate[3]; |
Arithemetica | 0:8c01a98a2812 | 79 | float accel[3]; |
Arithemetica | 0:8c01a98a2812 | 80 | |
Arithemetica | 0:8c01a98a2812 | 81 | std::int16_t temperature; |
Arithemetica | 0:8c01a98a2812 | 82 | } ImuProcessedData; |
Arithemetica | 0:8c01a98a2812 | 83 | |
Arithemetica | 0:8c01a98a2812 | 84 | /** |
Arithemetica | 12:bb490978e153 | 85 | * @brief ImuDriver is used to handle the master side of SPI communication of openIMU300ZI module, the |
Arithemetica | 2:f3a7def7a7e1 | 86 | * default setups are: |
Arithemetica | 0:8c01a98a2812 | 87 | * |
Arithemetica | 2:f3a7def7a7e1 | 88 | * - Data frame: 16 bits |
Arithemetica | 2:f3a7def7a7e1 | 89 | * - CPOL: High (1) |
Arithemetica | 2:f3a7def7a7e1 | 90 | * - CPHA: 2 Edge (1) |
Arithemetica | 17:629b2f317d0a | 91 | * - Frequency: 1 MHz (Default frequency of spi) |
Arithemetica | 2:f3a7def7a7e1 | 92 | * - Endian: MSB first (Mbed only support MSB AFAIK) |
Arithemetica | 5:e71931fcae33 | 93 | * |
Arithemetica | 10:d8223969c541 | 94 | * According to <A HREF="https://openimu.readthedocs.io/en/latest/software/SPImessaging.html">openIMU300ZI SPI framework</A>: |
Arithemetica | 5:e71931fcae33 | 95 | * |
Arithemetica | 3:8552e26cd162 | 96 | * - Data transferred in 16-bit word-length and MSB-first |
Arithemetica | 5:e71931fcae33 | 97 | * - fCLK ≤ 2.0 MHz |
Arithemetica | 3:8552e26cd162 | 98 | * - CPOL = 1 (clock polarity) and CPHA = 1 (clock phase) |
Arithemetica | 0:8c01a98a2812 | 99 | * |
Arithemetica | 2:f3a7def7a7e1 | 100 | * @tparam spi SPI comm instance, ImuDriver currently support only SPI framework |
Arithemetica | 2:f3a7def7a7e1 | 101 | * @tparam rst Reset pin name, this is used to reset the openIMU300ZI module |
Arithemetica | 2:f3a7def7a7e1 | 102 | * @tparam drdy Data ready pin name, this is used as indication of data readiness |
Arithemetica | 2:f3a7def7a7e1 | 103 | * @tparam ss Slave select pin name, this is used as slave select, pull low to initiate |
Arithemetica | 2:f3a7def7a7e1 | 104 | * communication process. |
Arithemetica | 5:e71931fcae33 | 105 | * |
Arithemetica | 7:224ffdacb240 | 106 | * @todo Attach to exti in the future, and make user able to choose |
Arithemetica | 7:224ffdacb240 | 107 | * |
Arithemetica | 0:8c01a98a2812 | 108 | * Example of using ImuDriver: |
Arithemetica | 0:8c01a98a2812 | 109 | * |
Arithemetica | 0:8c01a98a2812 | 110 | * @code |
Arithemetica | 0:8c01a98a2812 | 111 | * #include "imu_driver.hpp" |
Arithemetica | 0:8c01a98a2812 | 112 | * |
Arithemetica | 0:8c01a98a2812 | 113 | * SPI spi3(PB_5, PB_6, PB_3); // declare SPI instance globally |
Arithemetica | 0:8c01a98a2812 | 114 | * Serial pc(USBTX, USBRX, 115200); // print debug message |
Arithemetica | 0:8c01a98a2812 | 115 | * |
Arithemetica | 0:8c01a98a2812 | 116 | * int main() |
Arithemetica | 0:8c01a98a2812 | 117 | * { |
Arithemetica | 5:e71931fcae33 | 118 | * // SPI instance, reset, data ready, slave select |
Arithemetica | 17:629b2f317d0a | 119 | * ImuDriver<spi3, PA_10, PA_8, PA_9> imu(ImuExtiRcvNormalMsg); |
Arithemetica | 0:8c01a98a2812 | 120 | * |
Arithemetica | 0:8c01a98a2812 | 121 | * while(true) |
Arithemetica | 0:8c01a98a2812 | 122 | * { |
Arithemetica | 17:629b2f317d0a | 123 | * pc.printf("%.3f, %.3f, %.3f\n\r", imu.imuProcessedData.rate[0], imu.imuProcessedData.rate[1], imu.imuProcessedData.rate[2]); |
Arithemetica | 0:8c01a98a2812 | 124 | * } |
Arithemetica | 0:8c01a98a2812 | 125 | * } |
Arithemetica | 5:e71931fcae33 | 126 | * |
Arithemetica | 0:8c01a98a2812 | 127 | * @endcode |
Arithemetica | 0:8c01a98a2812 | 128 | */ |
Arithemetica | 2:f3a7def7a7e1 | 129 | template <SPI& Spi, PinName rst, PinName drdy, PinName ss> |
Arithemetica | 0:8c01a98a2812 | 130 | class ImuDriver |
Arithemetica | 0:8c01a98a2812 | 131 | { |
Arithemetica | 0:8c01a98a2812 | 132 | private: |
Arithemetica | 14:6c31a7ab45f0 | 133 | ImuExtiConfig m_extiConfig; |
Arithemetica | 14:6c31a7ab45f0 | 134 | |
Arithemetica | 0:8c01a98a2812 | 135 | SPI& m_spi; |
Arithemetica | 0:8c01a98a2812 | 136 | DigitalOut m_rst, m_ss; |
Arithemetica | 0:8c01a98a2812 | 137 | DigitalIn m_drdy; |
Arithemetica | 2:f3a7def7a7e1 | 138 | InterruptIn m_drdyExti; |
Arithemetica | 5:e71931fcae33 | 139 | |
Arithemetica | 0:8c01a98a2812 | 140 | float m_gyroScaler[3]; |
Arithemetica | 0:8c01a98a2812 | 141 | float m_accelScaler[3]; |
Arithemetica | 0:8c01a98a2812 | 142 | float m_ahrsScaler[3]; |
Arithemetica | 23:3626c7d73505 | 143 | |
Arithemetica | 23:3626c7d73505 | 144 | ImuDriver(); // cannot initialize via default constructor |
Arithemetica | 23:3626c7d73505 | 145 | |
Arithemetica | 0:8c01a98a2812 | 146 | std::uint16_t m_imuSpiWrite(const std::uint16_t val) const |
Arithemetica | 0:8c01a98a2812 | 147 | { |
Arithemetica | 0:8c01a98a2812 | 148 | // RAII |
Arithemetica | 0:8c01a98a2812 | 149 | class SpiLock |
Arithemetica | 0:8c01a98a2812 | 150 | { |
Arithemetica | 0:8c01a98a2812 | 151 | private: |
Arithemetica | 0:8c01a98a2812 | 152 | SPI& m_spi; |
Arithemetica | 0:8c01a98a2812 | 153 | public: |
Arithemetica | 0:8c01a98a2812 | 154 | SpiLock(SPI& t_spi) : m_spi(t_spi) |
Arithemetica | 0:8c01a98a2812 | 155 | { |
Arithemetica | 0:8c01a98a2812 | 156 | m_spi.lock(); |
Arithemetica | 0:8c01a98a2812 | 157 | } |
Arithemetica | 0:8c01a98a2812 | 158 | |
Arithemetica | 0:8c01a98a2812 | 159 | ~SpiLock() |
Arithemetica | 0:8c01a98a2812 | 160 | { |
Arithemetica | 0:8c01a98a2812 | 161 | m_spi.unlock(); |
Arithemetica | 0:8c01a98a2812 | 162 | } |
Arithemetica | 0:8c01a98a2812 | 163 | }; |
Arithemetica | 0:8c01a98a2812 | 164 | |
Arithemetica | 0:8c01a98a2812 | 165 | SpiLock lock(m_spi); |
Arithemetica | 0:8c01a98a2812 | 166 | return m_spi.write(val); |
Arithemetica | 0:8c01a98a2812 | 167 | } |
Arithemetica | 0:8c01a98a2812 | 168 | |
Arithemetica | 0:8c01a98a2812 | 169 | inline std::uint16_t m_spiGenerateReadCmd(const std::uint8_t t_val) const |
Arithemetica | 0:8c01a98a2812 | 170 | { |
Arithemetica | 0:8c01a98a2812 | 171 | return t_val << 8U; |
Arithemetica | 0:8c01a98a2812 | 172 | } |
Arithemetica | 0:8c01a98a2812 | 173 | |
Arithemetica | 0:8c01a98a2812 | 174 | inline bool m_spiIsDataReady() |
Arithemetica | 0:8c01a98a2812 | 175 | { |
Arithemetica | 0:8c01a98a2812 | 176 | return m_drdy.read() == 0; |
Arithemetica | 0:8c01a98a2812 | 177 | } |
Arithemetica | 0:8c01a98a2812 | 178 | |
Arithemetica | 0:8c01a98a2812 | 179 | inline void m_processImuRawData() |
Arithemetica | 0:8c01a98a2812 | 180 | { |
Arithemetica | 0:8c01a98a2812 | 181 | for (int i = 0; i < 3; ++i) { |
Arithemetica | 0:8c01a98a2812 | 182 | imuProcessedData.accel[i] = imuRawData.accel[i] / m_accelScaler[i]; |
Arithemetica | 0:8c01a98a2812 | 183 | imuProcessedData.rate[i] = imuRawData.rate[i] / m_gyroScaler[i]; |
Arithemetica | 0:8c01a98a2812 | 184 | } |
Arithemetica | 0:8c01a98a2812 | 185 | } |
Arithemetica | 0:8c01a98a2812 | 186 | |
Arithemetica | 0:8c01a98a2812 | 187 | inline void m_processAhrsRawData() |
Arithemetica | 0:8c01a98a2812 | 188 | { |
Arithemetica | 0:8c01a98a2812 | 189 | for (int i = 0; i < 3; ++i) { |
Arithemetica | 0:8c01a98a2812 | 190 | ahrsProcessedData.attitude[i] = ahrsRawData.attitude[i] / m_ahrsScaler[i]; |
Arithemetica | 0:8c01a98a2812 | 191 | } |
Arithemetica | 0:8c01a98a2812 | 192 | } |
Arithemetica | 5:e71931fcae33 | 193 | |
Arithemetica | 14:6c31a7ab45f0 | 194 | void m_dataReadyExtiCallback() |
Arithemetica | 2:f3a7def7a7e1 | 195 | { |
Arithemetica | 23:3626c7d73505 | 196 | if (m_extiConfig == ImuExtiRcvBothMsg) { |
Arithemetica | 14:6c31a7ab45f0 | 197 | receiveBurstMsgImpl(); |
Arithemetica | 24:275e886bd61c | 198 | wait_us(2); |
Arithemetica | 23:3626c7d73505 | 199 | receiveAhrsMsgImpl(); |
Arithemetica | 23:3626c7d73505 | 200 | } else if (m_extiConfig == ImuExtiRcvNormalMsg) { |
Arithemetica | 23:3626c7d73505 | 201 | receiveBurstMsgImpl(); |
Arithemetica | 23:3626c7d73505 | 202 | } else if (m_extiConfig == ImuExtiRcvAhrsMsg) { |
Arithemetica | 16:6583ad08d0d0 | 203 | receiveAhrsMsgImpl(); |
Arithemetica | 14:6c31a7ab45f0 | 204 | } |
Arithemetica | 2:f3a7def7a7e1 | 205 | } |
Arithemetica | 16:6583ad08d0d0 | 206 | |
Arithemetica | 14:6c31a7ab45f0 | 207 | ImuDriverStatus receiveBurstMsgImpl(bool t_extended = false) |
Arithemetica | 15:ca49fdec90fc | 208 | { |
Arithemetica | 0:8c01a98a2812 | 209 | if (m_spiIsDataReady()) { |
Arithemetica | 0:8c01a98a2812 | 210 | std::uint16_t max_data = 0U; |
Arithemetica | 0:8c01a98a2812 | 211 | std::uint16_t burst_reg = 0U; |
Arithemetica | 23:3626c7d73505 | 212 | std::uint8_t data_rcved = 0U; |
Arithemetica | 0:8c01a98a2812 | 213 | |
Arithemetica | 0:8c01a98a2812 | 214 | if (!t_extended) { |
Arithemetica | 0:8c01a98a2812 | 215 | max_data = 8U; |
Arithemetica | 0:8c01a98a2812 | 216 | burst_reg = m_spiGenerateReadCmd(ReadBurstDataRegister); |
Arithemetica | 0:8c01a98a2812 | 217 | } else { |
Arithemetica | 0:8c01a98a2812 | 218 | max_data = 11U; |
Arithemetica | 0:8c01a98a2812 | 219 | burst_reg = m_spiGenerateReadCmd(ReadExtBurstDataRegister); |
Arithemetica | 0:8c01a98a2812 | 220 | } |
Arithemetica | 0:8c01a98a2812 | 221 | |
Arithemetica | 0:8c01a98a2812 | 222 | m_ss.write(0); // start transfer |
Arithemetica | 0:8c01a98a2812 | 223 | m_imuSpiWrite(burst_reg); |
Arithemetica | 23:3626c7d73505 | 224 | |
Arithemetica | 0:8c01a98a2812 | 225 | while(data_rcved < max_data) { |
Arithemetica | 0:8c01a98a2812 | 226 | const std::uint16_t spi_data = m_imuSpiWrite(0x0000); |
Arithemetica | 0:8c01a98a2812 | 227 | switch(data_rcved) { |
Arithemetica | 0:8c01a98a2812 | 228 | case 0: |
Arithemetica | 0:8c01a98a2812 | 229 | imuRawData.status = spi_data; |
Arithemetica | 0:8c01a98a2812 | 230 | break; |
Arithemetica | 0:8c01a98a2812 | 231 | case 1: |
Arithemetica | 0:8c01a98a2812 | 232 | case 2: |
Arithemetica | 0:8c01a98a2812 | 233 | case 3: |
Arithemetica | 0:8c01a98a2812 | 234 | imuRawData.rate[data_rcved - 1] = spi_data; |
Arithemetica | 0:8c01a98a2812 | 235 | break; |
Arithemetica | 0:8c01a98a2812 | 236 | case 4: |
Arithemetica | 0:8c01a98a2812 | 237 | case 5: |
Arithemetica | 0:8c01a98a2812 | 238 | case 6: |
Arithemetica | 0:8c01a98a2812 | 239 | imuRawData.accel[data_rcved - 4] = spi_data; |
Arithemetica | 0:8c01a98a2812 | 240 | break; |
Arithemetica | 0:8c01a98a2812 | 241 | case 7: |
Arithemetica | 0:8c01a98a2812 | 242 | imuRawData.temperature = spi_data; |
Arithemetica | 0:8c01a98a2812 | 243 | break; |
Arithemetica | 0:8c01a98a2812 | 244 | default: |
Arithemetica | 0:8c01a98a2812 | 245 | break; |
Arithemetica | 0:8c01a98a2812 | 246 | } |
Arithemetica | 0:8c01a98a2812 | 247 | |
Arithemetica | 0:8c01a98a2812 | 248 | ++data_rcved; |
Arithemetica | 0:8c01a98a2812 | 249 | } |
Arithemetica | 0:8c01a98a2812 | 250 | |
Arithemetica | 0:8c01a98a2812 | 251 | m_ss.write(1); |
Arithemetica | 0:8c01a98a2812 | 252 | |
Arithemetica | 0:8c01a98a2812 | 253 | m_processImuRawData(); |
Arithemetica | 0:8c01a98a2812 | 254 | return ImuDriverStatusOK; |
Arithemetica | 0:8c01a98a2812 | 255 | } else { |
Arithemetica | 0:8c01a98a2812 | 256 | return ImuDriverStatusDataNotReady; |
Arithemetica | 0:8c01a98a2812 | 257 | } |
Arithemetica | 0:8c01a98a2812 | 258 | } |
Arithemetica | 15:ca49fdec90fc | 259 | |
Arithemetica | 15:ca49fdec90fc | 260 | ImuDriverStatus receiveAhrsMsgImpl() |
Arithemetica | 15:ca49fdec90fc | 261 | { |
Arithemetica | 15:ca49fdec90fc | 262 | if (m_spiIsDataReady()) { |
Arithemetica | 23:3626c7d73505 | 263 | std::uint8_t data_rcved = 0U; |
Arithemetica | 15:ca49fdec90fc | 264 | const std::uint8_t max_data = 5U; |
Arithemetica | 15:ca49fdec90fc | 265 | const std::uint16_t ahrs_reg = m_spiGenerateReadCmd(ReadAhrsBurstDataRegister); |
Arithemetica | 15:ca49fdec90fc | 266 | |
Arithemetica | 15:ca49fdec90fc | 267 | m_ss.write(0); |
Arithemetica | 15:ca49fdec90fc | 268 | m_imuSpiWrite(ahrs_reg); |
Arithemetica | 15:ca49fdec90fc | 269 | |
Arithemetica | 15:ca49fdec90fc | 270 | while(data_rcved < max_data) { |
Arithemetica | 15:ca49fdec90fc | 271 | const std::uint16_t spi_data = m_imuSpiWrite(0x0000); |
Arithemetica | 15:ca49fdec90fc | 272 | switch(data_rcved) { |
Arithemetica | 15:ca49fdec90fc | 273 | case 0: |
Arithemetica | 15:ca49fdec90fc | 274 | ahrsRawData.status = spi_data; |
Arithemetica | 15:ca49fdec90fc | 275 | break; |
Arithemetica | 15:ca49fdec90fc | 276 | case 1: |
Arithemetica | 15:ca49fdec90fc | 277 | case 2: |
Arithemetica | 15:ca49fdec90fc | 278 | case 3: |
Arithemetica | 15:ca49fdec90fc | 279 | ahrsRawData.attitude[data_rcved - 1] = spi_data; |
Arithemetica | 15:ca49fdec90fc | 280 | break; |
Arithemetica | 15:ca49fdec90fc | 281 | case 4: |
Arithemetica | 15:ca49fdec90fc | 282 | ahrsRawData.temperature = spi_data; |
Arithemetica | 15:ca49fdec90fc | 283 | break; |
Arithemetica | 15:ca49fdec90fc | 284 | default: |
Arithemetica | 15:ca49fdec90fc | 285 | break; |
Arithemetica | 15:ca49fdec90fc | 286 | } |
Arithemetica | 15:ca49fdec90fc | 287 | |
Arithemetica | 15:ca49fdec90fc | 288 | ++data_rcved; |
Arithemetica | 17:629b2f317d0a | 289 | |
Arithemetica | 15:ca49fdec90fc | 290 | } |
Arithemetica | 15:ca49fdec90fc | 291 | |
Arithemetica | 15:ca49fdec90fc | 292 | m_ss.write(1); |
Arithemetica | 15:ca49fdec90fc | 293 | |
Arithemetica | 15:ca49fdec90fc | 294 | m_processAhrsRawData(); |
Arithemetica | 15:ca49fdec90fc | 295 | return ImuDriverStatusOK; |
Arithemetica | 15:ca49fdec90fc | 296 | } else { |
Arithemetica | 15:ca49fdec90fc | 297 | return ImuDriverStatusDataNotReady; |
Arithemetica | 15:ca49fdec90fc | 298 | } |
Arithemetica | 15:ca49fdec90fc | 299 | } |
Arithemetica | 14:6c31a7ab45f0 | 300 | public: |
Arithemetica | 14:6c31a7ab45f0 | 301 | /** |
Arithemetica | 14:6c31a7ab45f0 | 302 | * imuRawData contains raw data received from @ref receiveBurstMsg(bool t_extended) |
Arithemetica | 14:6c31a7ab45f0 | 303 | */ |
Arithemetica | 14:6c31a7ab45f0 | 304 | ImuRawData imuRawData; |
Arithemetica | 14:6c31a7ab45f0 | 305 | |
Arithemetica | 14:6c31a7ab45f0 | 306 | /** |
Arithemetica | 14:6c31a7ab45f0 | 307 | * imuProcessedData contains processed data, which is merely scaling operation |
Arithemetica | 14:6c31a7ab45f0 | 308 | */ |
Arithemetica | 14:6c31a7ab45f0 | 309 | ImuProcessedData imuProcessedData; |
Arithemetica | 14:6c31a7ab45f0 | 310 | |
Arithemetica | 14:6c31a7ab45f0 | 311 | /** |
Arithemetica | 14:6c31a7ab45f0 | 312 | * ahrsRawaData contains raw data received from @ref receiveAhrsMsg() |
Arithemetica | 14:6c31a7ab45f0 | 313 | */ |
Arithemetica | 14:6c31a7ab45f0 | 314 | AhrsRawData ahrsRawData; |
Arithemetica | 14:6c31a7ab45f0 | 315 | |
Arithemetica | 14:6c31a7ab45f0 | 316 | /** |
Arithemetica | 14:6c31a7ab45f0 | 317 | * ahrsProcessedData contains processed data, which is merely scaling operation |
Arithemetica | 14:6c31a7ab45f0 | 318 | */ |
Arithemetica | 14:6c31a7ab45f0 | 319 | AhrsProcessedData ahrsProcessedData; |
Arithemetica | 14:6c31a7ab45f0 | 320 | |
Arithemetica | 14:6c31a7ab45f0 | 321 | static const int DEFAULT_IMU_ACCEL_SCALER = 4000; |
Arithemetica | 14:6c31a7ab45f0 | 322 | static const int DEFAULT_IMU_GYRO_SCALER = 100; |
Arithemetica | 14:6c31a7ab45f0 | 323 | static const int DEFAULT_AHRS_ATTITUDE_SCALER = 90; |
Arithemetica | 23:3626c7d73505 | 324 | |
Arithemetica | 23:3626c7d73505 | 325 | /** |
Arithemetica | 23:3626c7d73505 | 326 | * |
Arithemetica | 23:3626c7d73505 | 327 | */ |
Arithemetica | 14:6c31a7ab45f0 | 328 | explicit ImuDriver(const ImuExtiConfig t_exti_config) : m_extiConfig(t_exti_config), m_spi(Spi), m_rst(rst), m_ss(ss), m_drdy(drdy), m_drdyExti(drdy) |
Arithemetica | 14:6c31a7ab45f0 | 329 | { |
Arithemetica | 14:6c31a7ab45f0 | 330 | for (int i = 0; i < 3; ++i) { |
Arithemetica | 14:6c31a7ab45f0 | 331 | m_gyroScaler[i] = static_cast<float>(DEFAULT_IMU_GYRO_SCALER); // what an idiotic way of initialization LUL |
Arithemetica | 14:6c31a7ab45f0 | 332 | m_accelScaler[i] = static_cast<float>(DEFAULT_IMU_ACCEL_SCALER); // Oh, I forgot that mbed os2 still stucks at c++98, |
Arithemetica | 14:6c31a7ab45f0 | 333 | m_ahrsScaler[i] = static_cast<float>(DEFAULT_AHRS_ATTITUDE_SCALER); // how unfortunate LUL |
Arithemetica | 14:6c31a7ab45f0 | 334 | } |
Arithemetica | 14:6c31a7ab45f0 | 335 | |
Arithemetica | 14:6c31a7ab45f0 | 336 | if (t_exti_config != ImuExtiRcvNotUsed) { |
Arithemetica | 14:6c31a7ab45f0 | 337 | m_drdyExti.fall(this, &ImuDriver<Spi, rst, drdy, ss>::m_dataReadyExtiCallback); |
Arithemetica | 17:629b2f317d0a | 338 | m_drdyExti.enable_irq(); |
Arithemetica | 14:6c31a7ab45f0 | 339 | } |
Arithemetica | 14:6c31a7ab45f0 | 340 | |
Arithemetica | 14:6c31a7ab45f0 | 341 | m_spi.format(16, 3); |
Arithemetica | 17:629b2f317d0a | 342 | m_spi.frequency(); |
Arithemetica | 14:6c31a7ab45f0 | 343 | } |
Arithemetica | 14:6c31a7ab45f0 | 344 | |
Arithemetica | 14:6c31a7ab45f0 | 345 | /** |
Arithemetica | 14:6c31a7ab45f0 | 346 | * @brief This function handles the receiving of burst message function, burst message |
Arithemetica | 14:6c31a7ab45f0 | 347 | * contains accelerometer (g), gyroscope (deg/s), status and temperature data (Celcius) |
Arithemetica | 14:6c31a7ab45f0 | 348 | * |
Arithemetica | 14:6c31a7ab45f0 | 349 | * @param t_extended bool to indicate the message type is extended or not, default false |
Arithemetica | 14:6c31a7ab45f0 | 350 | * |
Arithemetica | 14:6c31a7ab45f0 | 351 | * @return ImuDriverStatus to indicate the result of the receive operation |
Arithemetica | 14:6c31a7ab45f0 | 352 | */ |
Arithemetica | 15:ca49fdec90fc | 353 | ImuDriverStatus receiveBurstMsg(bool t_extended = false) |
Arithemetica | 15:ca49fdec90fc | 354 | { |
Arithemetica | 15:ca49fdec90fc | 355 | return (m_extiConfig & ImuExtiRcvNormalMsg ? ImuDriverStatusInvalidCall : receiveBurstMsgImpl(t_extended)); |
Arithemetica | 14:6c31a7ab45f0 | 356 | } |
Arithemetica | 0:8c01a98a2812 | 357 | |
Arithemetica | 0:8c01a98a2812 | 358 | /** |
Arithemetica | 5:e71931fcae33 | 359 | * @brief This function handles the receiving of AHRS burst message function, AHRS |
Arithemetica | 10:d8223969c541 | 360 | * burst message contains the attitude in euler angle (deg). |
Arithemetica | 0:8c01a98a2812 | 361 | * |
Arithemetica | 0:8c01a98a2812 | 362 | * @return ImuDriverStatus to indicate the result of the receive operation |
Arithemetica | 0:8c01a98a2812 | 363 | * |
Arithemetica | 0:8c01a98a2812 | 364 | * @note This is only suitable for AHRS app, and additional procedure needs to be done |
Arithemetica | 0:8c01a98a2812 | 365 | * in order to make it work |
Arithemetica | 0:8c01a98a2812 | 366 | */ |
Arithemetica | 0:8c01a98a2812 | 367 | ImuDriverStatus receiveAhrsMsg() |
Arithemetica | 0:8c01a98a2812 | 368 | { |
Arithemetica | 15:ca49fdec90fc | 369 | return (m_extiConfig & ImuExtiRcvAhrsMsg ? ImuDriverStatusInvalidCall : receiveAhrsMsgImpl()); |
Arithemetica | 15:ca49fdec90fc | 370 | } |
Arithemetica | 0:8c01a98a2812 | 371 | |
Arithemetica | 17:629b2f317d0a | 372 | /** |
Arithemetica | 17:629b2f317d0a | 373 | * @brief This function handles the external interrupt option, whether receive AHRS |
Arithemetica | 17:629b2f317d0a | 374 | * burst message or normal imu message. |
Arithemetica | 17:629b2f317d0a | 375 | * |
Arithemetica | 17:629b2f317d0a | 376 | * @return ImuDriverStatus to indicate the result of the receive operation |
Arithemetica | 17:629b2f317d0a | 377 | * |
Arithemetica | 17:629b2f317d0a | 378 | * @note Never try receiving two messages at the same time |
Arithemetica | 17:629b2f317d0a | 379 | */ |
Arithemetica | 21:9430046ebd9d | 380 | ImuDriverStatus configExti(ImuExtiConfig const& t_exti_config) |
Arithemetica | 15:ca49fdec90fc | 381 | { |
Arithemetica | 14:6c31a7ab45f0 | 382 | m_extiConfig = t_exti_config; |
Arithemetica | 17:629b2f317d0a | 383 | |
Arithemetica | 17:629b2f317d0a | 384 | if (m_extoConfig == ImuExtiRcvNotUsed) { |
Arithemetica | 17:629b2f317d0a | 385 | m_drdyExti.disable_irq(); |
Arithemetica | 17:629b2f317d0a | 386 | } else { |
Arithemetica | 17:629b2f317d0a | 387 | m_drdyExti.enable_irq(); |
Arithemetica | 17:629b2f317d0a | 388 | } |
Arithemetica | 17:629b2f317d0a | 389 | |
Arithemetica | 17:629b2f317d0a | 390 | return ImuDriverStatusOK; |
Arithemetica | 14:6c31a7ab45f0 | 391 | } |
Arithemetica | 1:8e31413068af | 392 | }; |
Arithemetica | 1:8e31413068af | 393 | |
Arithemetica | 1:8e31413068af | 394 | #endif // IMU_DRIVER_HPP_ |