Skip to content

Commit eb0192b

Browse files
committed
✨ (imu): Add wake up interrupt
1 parent d80edbc commit eb0192b

5 files changed

Lines changed: 125 additions & 0 deletions

File tree

drivers/CoreIMU/include/CoreIMU.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class CoreIMU : public interface::IMU, public interface::DeepSleepEnabled
2626
void enableOnDataReadyInterrupt() final;
2727
void disableOnDataReadyInterrupt() final;
2828

29+
void registerOnWakeUpCallback(std::function<void()> const &callback) final;
30+
void enableOnWakeUpInterrupt() final;
31+
2932
void setPowerMode(PowerMode mode) final;
3033

3134
void enableDeepSleep() final;
@@ -58,6 +61,8 @@ class CoreIMU : public interface::IMU, public interface::DeepSleepEnabled
5861

5962
static constexpr uint8_t kMaxBufferLength = 32;
6063
std::array<uint8_t, kMaxBufferLength> _rx_buffer {};
64+
65+
std::function<void()> _on_wake_up_callback {};
6166
};
6267

6368
} // namespace leka

drivers/CoreIMU/source/CoreIMU.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,45 @@ void CoreIMU::disableDeepSleep()
137137
setPowerMode(interface::IMU::PowerMode::Normal);
138138
}
139139

140+
void CoreIMU::registerOnWakeUpCallback(std::function<void()> const &callback)
141+
{
142+
_on_wake_up_callback = callback;
143+
}
144+
145+
void CoreIMU::enableOnWakeUpInterrupt()
146+
{
147+
// ? Set filter and disable user offset
148+
lsm6dsox_xl_hp_path_internal_set(&_register_io_function, LSM6DSOX_USE_SLOPE);
149+
lsm6dsox_xl_usr_offset_on_wkup_set(&_register_io_function, 0);
150+
151+
// ? Set Wakeup config
152+
lsm6dsox_wkup_threshold_set(&_register_io_function, 2);
153+
lsm6dsox_wkup_ths_weight_set(&_register_io_function, LSM6DSOX_LSb_FS_DIV_64);
154+
lsm6dsox_wkup_dur_set(&_register_io_function, 0x02);
155+
156+
// ? Set Activity config
157+
lsm6dsox_act_sleep_dur_set(&_register_io_function, 0x02);
158+
lsm6dsox_act_mode_set(&_register_io_function, LSM6DSOX_XL_AND_GY_NOT_AFFECTED);
159+
160+
lsm6dsox_pin_int1_route_t lsm6dsox_int1 {
161+
.sleep_change = PROPERTY_ENABLE,
162+
};
163+
lsm6dsox_pin_int1_route_set(&_register_io_function, lsm6dsox_int1);
164+
165+
auto on_wake_up_wrapper_callback = [this] {
166+
_event_queue.call([this] {
167+
lsm6dsox_all_sources_t all_source;
168+
lsm6dsox_all_sources_get(&_register_io_function, &all_source);
169+
170+
if (all_source.sleep_change && all_source.sleep_state == 0 && _on_wake_up_callback != nullptr) {
171+
_on_wake_up_callback();
172+
}
173+
});
174+
};
175+
176+
setDataReadyInterruptCallback(on_wake_up_wrapper_callback);
177+
}
178+
140179
auto CoreIMU::read(uint8_t register_address, uint16_t number_bytes_to_read, uint8_t *p_buffer) -> int32_t
141180
{
142181
// Send component address, without STOP condition
@@ -177,6 +216,8 @@ void CoreIMU::setDataReadyInterruptCallback(std::function<void()> const &callbac
177216
{
178217
if (callback) {
179218
_irq.onRise(callback);
219+
} else {
220+
_irq.onRise([] {});
180221
}
181222
}
182223

drivers/CoreIMU/tests/CoreIMU_test.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using namespace leka;
1414

1515
using testing::_;
16+
using testing::AnyNumber;
1617
using testing::AtLeast;
1718
using testing::MockFunction;
1819

@@ -120,3 +121,73 @@ TEST_F(CoreIMUTest, disableDeepSleep)
120121

121122
coreimu.disableDeepSleep();
122123
}
124+
125+
TEST_F(CoreIMUTest, onWakeUpCallback)
126+
{
127+
MockFunction<void()> mock_callback;
128+
129+
EXPECT_CALL(mocki2c, write).Times(AtLeast(1));
130+
EXPECT_CALL(mocki2c, read).Times(AtLeast(1));
131+
EXPECT_CALL(mock_callback, Call).Times(AnyNumber());
132+
133+
coreimu.registerOnWakeUpCallback(mock_callback.AsStdFunction());
134+
135+
auto on_rise_callback = spy_InterruptIn_getRiseCallback();
136+
on_rise_callback();
137+
}
138+
139+
TEST_F(CoreIMUTest, emptyOnWakeUpCallback)
140+
{
141+
coreimu.registerOnWakeUpCallback({});
142+
143+
auto on_rise_callback = spy_InterruptIn_getRiseCallback();
144+
on_rise_callback();
145+
}
146+
147+
TEST_F(CoreIMUTest, enableOnWakeUpInterrupt)
148+
{
149+
EXPECT_CALL(mocki2c, write).Times(AtLeast(1));
150+
EXPECT_CALL(mocki2c, read).Times(AtLeast(1));
151+
152+
coreimu.enableOnWakeUpInterrupt();
153+
}
154+
155+
TEST_F(CoreIMUTest, switchCallbacks)
156+
{
157+
auto mock_data_available_callback = MockFunction<void(const leka::interface::IMU::SensorData &data)> {};
158+
auto mock_wake_up_callback = MockFunction<void()> {};
159+
auto on_rise_callback = mbed::Callback<void()> {};
160+
161+
EXPECT_CALL(mocki2c, write).Times(AnyNumber());
162+
EXPECT_CALL(mocki2c, read).Times(AnyNumber());
163+
164+
coreimu.registerOnDataReadyCallback(mock_data_available_callback.AsStdFunction());
165+
coreimu.registerOnWakeUpCallback(mock_wake_up_callback.AsStdFunction());
166+
167+
{
168+
// Enable Data Available
169+
EXPECT_CALL(mock_data_available_callback, Call).Times(1);
170+
EXPECT_CALL(mock_wake_up_callback, Call).Times(0);
171+
coreimu.enableOnDataReadyInterrupt();
172+
on_rise_callback = spy_InterruptIn_getRiseCallback();
173+
on_rise_callback();
174+
}
175+
176+
{
177+
// Disable Data Available
178+
EXPECT_CALL(mock_data_available_callback, Call).Times(0);
179+
EXPECT_CALL(mock_wake_up_callback, Call).Times(0);
180+
coreimu.disableOnDataReadyInterrupt();
181+
on_rise_callback = spy_InterruptIn_getRiseCallback();
182+
on_rise_callback();
183+
}
184+
185+
{
186+
// Enable Wake Up
187+
EXPECT_CALL(mock_data_available_callback, Call).Times(0);
188+
EXPECT_CALL(mock_wake_up_callback, Call).Times(AnyNumber());
189+
coreimu.enableOnWakeUpInterrupt();
190+
on_rise_callback = spy_InterruptIn_getRiseCallback();
191+
on_rise_callback();
192+
}
193+
}

include/interface/drivers/IMU.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class IMU
5454
virtual void enableOnDataReadyInterrupt() = 0;
5555
virtual void disableOnDataReadyInterrupt() = 0;
5656

57+
virtual void registerOnWakeUpCallback(std::function<void()> const &callback) = 0;
58+
virtual void enableOnWakeUpInterrupt() = 0;
59+
5760
virtual void setPowerMode(PowerMode) = 0;
5861
};
5962
} // namespace leka::interface

tests/unit/mocks/mocks/leka/IMU.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@ class IMU : public interface::IMU
1919
MOCK_METHOD(void, enableOnDataReadyInterrupt, (), (override));
2020
MOCK_METHOD(void, disableOnDataReadyInterrupt, (), (override));
2121

22+
void registerOnWakeUpCallback(std::function<void()> const &cb) override { wake_up_callback = cb; }
23+
MOCK_METHOD(void, enableOnWakeUpInterrupt, (), (override));
24+
2225
void call_data_ready_callback(const SensorData &data) { data_ready_callback(data); }
26+
void call_wake_up_callback() { wake_up_callback(); }
2327

2428
private:
2529
data_ready_callback_t data_ready_callback {};
30+
std::function<void()> wake_up_callback {};
2631
};
2732

2833
} // namespace leka::mock

0 commit comments

Comments
 (0)