99 */
1010// ----------------------------------------------------------------------------
1111
12- #include < atomic>
1312#include < cstdint>
1413#include < modm/board.hpp>
1514#include < modm/driver/inertial/bmi270.hpp>
15+ #include < modm/processing/timer.hpp>
1616
1717using namespace Board ;
1818
@@ -26,71 +26,7 @@ using Int2 = GpioF3; // D9
2626using Transport = modm::Bmi270I2cTransport<I2c>;
2727using Imu = modm::Bmi270<Transport>;
2828
29- Imu imu{static_cast <uint8_t >(0x68 )};
30-
31- std::atomic<uint32_t > accInterruptCount{0 };
32- std::atomic<uint32_t > gyroInterruptCount{0 };
33-
34- std::atomic<int32_t > accX{0 };
35- std::atomic<int32_t > accY{0 };
36- std::atomic<int32_t > accZ{0 };
37-
38- std::atomic<int32_t > gyroX{0 };
39- std::atomic<int32_t > gyroY{0 };
40- std::atomic<int32_t > gyroZ{0 };
41-
42- std::atomic_flag imuBusLock = ATOMIC_FLAG_INIT;
43-
44- bool
45- tryLockImuBus ()
46- {
47- return !imuBusLock.test_and_set (std::memory_order_acquire);
48- }
49-
50- void
51- unlockImuBus ()
52- {
53- imuBusLock.clear (std::memory_order_release);
54- }
55-
56- void
57- onDataReadyInterrupt ()
58- {
59- if (!tryLockImuBus ()) { return ; }
60-
61- const auto status = imu.getStatus ();
62- if (!status)
63- {
64- unlockImuBus ();
65- return ;
66- }
67-
68- if (status->accDataReady )
69- {
70- const auto data = imu.readAccData ();
71- if (data)
72- {
73- accInterruptCount.fetch_add (1 , std::memory_order_relaxed);
74- accX.store (data->raw [0 ], std::memory_order_relaxed);
75- accY.store (data->raw [1 ], std::memory_order_relaxed);
76- accZ.store (data->raw [2 ], std::memory_order_relaxed);
77- }
78- }
79-
80- if (status->gyroDataReady )
81- {
82- const auto data = imu.readGyroData ();
83- if (data)
84- {
85- gyroInterruptCount.fetch_add (1 , std::memory_order_relaxed);
86- gyroX.store (data->raw [0 ], std::memory_order_relaxed);
87- gyroY.store (data->raw [1 ], std::memory_order_relaxed);
88- gyroZ.store (data->raw [2 ], std::memory_order_relaxed);
89- }
90- }
91-
92- unlockImuBus ();
93- }
29+ Imu imu{Transport::I2cAddress::SdoLow};
9430
9531bool
9632configureDriver ()
@@ -117,15 +53,15 @@ configureDriver()
11753 Imu::InterruptIoControl int2{};
11854 int2.level = Imu::InterruptOutputLevel::ActiveHigh;
11955 int2.outputType = Imu::InterruptOutputType::PushPull;
120- int2.outputEnable = false ;
56+ int2.outputEnable = true ;
12157 int2.inputEnable = false ;
12258 ok &= imu.setInt2IoControl (int2);
12359
12460 ok &= imu.setInterruptLatch (Imu::InterruptLatch::None);
12561
12662 Imu::InterruptMapData intMap{};
12763 intMap.int1DataReady = true ;
128- intMap.int2DataReady = false ;
64+ intMap.int2DataReady = true ;
12965 ok &= imu.setInterruptMapData (intMap);
13066
13167 ok &= imu.setPowerControl (Imu::PowerControl::Accelerometer | Imu::PowerControl::Gyroscope |
@@ -138,75 +74,99 @@ main()
13874{
13975 Board::initialize ();
14076 Leds::setOutput ();
141- I2c::connect<Scl::Scl, Sda::Sda>(I2c::PullUps::Internal );
77+ I2c::connect<Scl::Scl, Sda::Sda>(I2c::PullUps::External );
14278 I2c::initialize<Board::SystemClock, 1_MHz, 10_pct>();
14379 Int1::setInput (Int1::InputType::PullDown);
14480 Int2::setInput (Int2::InputType::PullDown);
14581
146- MODM_LOG_INFO << " BMI270 I2C interrupt example" << modm::endl;
82+ MODM_LOG_INFO << " BMI270 I2C polling example" << modm::endl;
14783
14884 if (!configureDriver ()) { MODM_LOG_ERROR << " Configuration failed!" << modm::endl; }
14985
150- Exti::connect<Int1>(Exti::Trigger::RisingEdge, [](auto ) { onDataReadyInterrupt (); });
86+ uint32_t accSampleCount{0 };
87+ uint32_t gyroSampleCount{0 };
88+ modm::PeriodicTimer printTimer{1s};
89+
90+ Imu::AccData latestAccData{};
91+ latestAccData.raw = modm::Vector3i (0 , 0 , 0 );
92+ latestAccData.range = Imu::AccRange::Range2g;
93+
94+ Imu::GyroData latestGyroData{};
95+ latestGyroData.raw = modm::Vector3i (0 , 0 , 0 );
96+ latestGyroData.range = Imu::GyroRange::Range2000dps;
97+
98+ std::optional<Imu::SensorStatus> latestStatus;
15199
152100 while (true )
153101 {
154- modm::this_fiber::sleep_for (1s);
155-
156- const uint32_t accCount = accInterruptCount.exchange (0 , std::memory_order_relaxed);
157- const uint32_t gyroCount = gyroInterruptCount.exchange (0 , std::memory_order_relaxed);
158-
159- Imu::AccData accData{};
160- accData.raw = modm::Vector3i (accX.load (std::memory_order_relaxed),
161- accY.load (std::memory_order_relaxed),
162- accZ.load (std::memory_order_relaxed));
163- accData.range = Imu::AccRange::Range2g;
164-
165- Imu::GyroData gyroData{};
166- gyroData.raw = modm::Vector3i (gyroX.load (std::memory_order_relaxed),
167- gyroY.load (std::memory_order_relaxed),
168- gyroZ.load (std::memory_order_relaxed));
169- gyroData.range = Imu::GyroRange::Range2000dps;
170-
171- const modm::Vector3f acc = accData.getFloat ();
172- const modm::Vector3f gyro = gyroData.getFloat ();
173-
174- std::optional<Imu::Temperature> temperature;
175- std::optional<Imu::SensorStatus> status;
176- while (!tryLockImuBus ()) { modm::this_fiber::sleep_for (50us); }
177- temperature = imu.getTemperature ();
178- status = imu.getStatus ();
179- unlockImuBus ();
180-
181- MODM_LOG_INFO << " Interrupts in last 1s: acc=" << accCount << " gyro=" << gyroCount
182- << modm::endl;
183-
184- MODM_LOG_INFO << " Latest Values Acc [mg] x: " << acc[0 ] << " y: " << acc[1 ]
185- << " z: " << acc[2 ] << modm::endl;
186- MODM_LOG_INFO << " Latest Values Gyro [deg/s] x: " << gyro[0 ] << " y: " << gyro[1 ]
187- << " z: " << gyro[2 ] << modm::endl;
188-
189- if (temperature and temperature->valid )
102+ if (Int1::read ())
190103 {
191- MODM_LOG_INFO << " Current Temperature [C]: " << temperature->celsius << modm::endl;
192- } else
193- {
194- MODM_LOG_INFO << " Temperature: invalid" << modm::endl;
104+ if (const auto status = imu.getStatus ())
105+ {
106+ latestStatus = status;
107+
108+ if (status->accDataReady )
109+ {
110+ if (const auto accData = imu.readAccData ())
111+ {
112+ latestAccData = *accData;
113+ ++accSampleCount;
114+ }
115+ }
116+
117+ if (status->gyroDataReady )
118+ {
119+ if (const auto gyroData = imu.readGyroData ())
120+ {
121+ latestGyroData = *gyroData;
122+ ++gyroSampleCount;
123+ }
124+ }
125+ }
195126 }
196127
197- if (status)
198- {
199- MODM_LOG_INFO << " Current Status: acc=" << status->accDataReady
200- << " gyro=" << status->gyroDataReady << " aux=" << status->auxDataReady
201- << " cmd=" << status->commandReady << " auxBusy=" << status->auxBusy
202- << modm::endl;
203- } else
128+ if (printTimer.execute ())
204129 {
205- MODM_LOG_INFO << " Status: unavailable" << modm::endl;
130+ const modm::Vector3f acc = latestAccData.getFloat ();
131+ const modm::Vector3f gyro = latestGyroData.getFloat ();
132+ const std::optional<Imu::Temperature> temperature = imu.getTemperature ();
133+
134+ MODM_LOG_INFO << " Data-ready events in last 1s: acc=" << accSampleCount
135+ << " gyro=" << gyroSampleCount << modm::endl;
136+
137+ accSampleCount = 0 ;
138+ gyroSampleCount = 0 ;
139+
140+ MODM_LOG_INFO << " Latest Values Acc [mg] x: " << acc[0 ] << " y: " << acc[1 ]
141+ << " z: " << acc[2 ] << modm::endl;
142+ MODM_LOG_INFO << " Latest Values Gyro [deg/s] x: " << gyro[0 ] << " y: " << gyro[1 ]
143+ << " z: " << gyro[2 ] << modm::endl;
144+
145+ if (temperature and temperature->valid )
146+ {
147+ MODM_LOG_INFO << " Current Temperature [C]: " << temperature->celsius << modm::endl;
148+ } else
149+ {
150+ MODM_LOG_INFO << " Temperature: invalid" << modm::endl;
151+ }
152+
153+ if (latestStatus)
154+ {
155+ MODM_LOG_INFO << " Current Status: acc=" << latestStatus->accDataReady
156+ << " gyro=" << latestStatus->gyroDataReady
157+ << " aux=" << latestStatus->auxDataReady
158+ << " cmd=" << latestStatus->commandReady
159+ << " auxBusy=" << latestStatus->auxBusy << modm::endl;
160+ } else
161+ {
162+ MODM_LOG_INFO << " Status: unavailable" << modm::endl;
163+ }
164+ MODM_LOG_INFO << modm::endl;
165+
166+ Board::LedGreen::toggle ();
206167 }
207- MODM_LOG_INFO << modm::endl;
208168
209- Board::LedGreen::toggle ();
169+ modm::this_fiber::yield ();
210170 }
211171
212172 return 0 ;
0 commit comments