M module-bsp/board/linux/magnetometer/magnetometer.cpp => module-bsp/board/linux/magnetometer/magnetometer.cpp +1 -5
@@ 35,11 35,7 @@ namespace bsp
void enableIRQ()
{}
- void initFirstReadout()
+ void resetCurrentParsedValue()
{}
- bsp::KeyCodes getCurrentSliderPosition()
- {
- return bsp::KeyCodes::Undefined;
- }
} // namespace magnetometer
} // namespace bsp
M module-bsp/board/rt1051/bsp/magnetometer/ALS31300.hpp => module-bsp/board/rt1051/bsp/magnetometer/ALS31300.hpp +2 -22
@@ 17,7 17,7 @@ namespace drivers::als31300
using whole_reg_t = uint32_t; // ALS31300 always talks 4 bytes
constexpr auto I2C_ADDRESS = 0x64;
- constexpr auto DUMMY_BYTE = 1;
+
// base ALS31300 register struct.
struct base_reg
{
@@ 109,33 109,13 @@ namespace drivers::als31300
constexpr auto PWR_REG_LOOP_MODE_fast_loop = 0b01;
constexpr auto PWR_REG_LOOP_MODE_full_loop = 0b10;
- enum class PWR_REG_SLEEP_MODE
+ enum PWR_REG_SLEEP_MODE
{
active = PWR_REG_SLEEP_MODE_active,
sleep = PWR_REG_SLEEP_MODE_sleep,
periodic_active = PWR_REG_SLEEP_MODE_LPDCM,
};
- enum class LPDCM_INACTIVE_TIME
- {
- inactive_500us,
- inactive_1ms,
- inactive_5ms,
- inactive_10ms,
- inactive_50ms,
- inactive_100ms,
- inactive_500ms,
- inactive_1s
- };
- enum class BANDWIDTH_SELECT
- {
- bandwidth_3500Hz = 0,
- bandwidth_7kHz = 1,
- bandwidth_14kHz = 2,
- bandwidth_10kHz = 4,
- bandwidth_20kHz = 5,
- bandwidth_40kHz = 6
- };
constexpr auto PWR_ON_DELAY_MS = 1; // spec'd as 600µs at most
// --------
D module-bsp/board/rt1051/bsp/magnetometer/doc/magnetometer_values.png => module-bsp/board/rt1051/bsp/magnetometer/doc/magnetometer_values.png +0 -0
D module-bsp/board/rt1051/bsp/magnetometer/doc/readme.md => module-bsp/board/rt1051/bsp/magnetometer/doc/readme.md +0 -27
@@ 1,27 0,0 @@
-# ALS31300 Hall effect sensor
-This magnetometer is used as a detector of the slider position, which has a magnet attached to itself. When slider position changes,
-the magnetic field intensity measured by the sensor is changing and is properly interpreted to determine the position of the slider.
-
-## Values per position
-
-<center><b>Positions: down, middle, up, middle</b></center>
-
-As shown on the graph, using only X and Y axes can clearly determine the slider position so this has been implemented.
-
-## Magnetometer configuration
-Looking at the graph it's easy to find out, that each slider position has some mean value of the magnetic field intensity. This particular
-sensor has the possibility to generate an interrupt on its pin when the absolute threshold has been exceeded or the increment of
-the intensity related to the last taken measurement was higher than a certain, set value.
-
-In this case, increment (delta) mode has been used, combined with Low Power Delta Compare Mode (LPDCM) -
-magnetometer cycles between active and inactive state and takes measurements. When the change in the magnetic field has been higher than
-set value, it generates an interrupt for the main processor, which then retrieves the measurements and does proper action.
-
-## Caveats
-
-- once the magnetometer has been put to the LPDCM mode it cannot be read nor written until the interrupt happens - despite the datasheet which claims,
-that the device should respond to the I2C commands, the only answer to every one command was NAK,
-- setting a too small period for LPDCM mode (too small inactivity time) caused some instability during tests,
-- to get proper measurements after receiving the interrupt, there's a need to put the magnetometer to the active state,
- then take measurements and put it again to the LPDCM mode - doing anything else means the measurements data was inaccurate and way off.
-
M module-bsp/board/rt1051/bsp/magnetometer/magnetometer.cpp => module-bsp/board/rt1051/bsp/magnetometer/magnetometer.cpp +84 -50
@@ 34,6 34,27 @@ namespace bsp
{
namespace magnetometer
{
+ enum class LPDCM_INACTIVE_TIME
+ {
+ inactive_500us,
+ inactive_1ms,
+ inactive_5ms,
+ inactive_10ms,
+ inactive_50ms,
+ inactive_100ms,
+ inactive_500ms,
+ inactive_1s
+ };
+
+ enum class BANDWIDTH_SELECT
+ {
+ bandwidth_3500Hz = 0,
+ bandwidth_7kHz = 1,
+ bandwidth_14kHz = 2,
+ bandwidth_10kHz = 4,
+ bandwidth_20kHz = 5,
+ bandwidth_40kHz = 6
+ };
namespace
{
bool isTimeToCompleteWriteDefinedForRegistry(std::uint8_t address)
@@ 41,28 62,29 @@ namespace bsp
const auto it = std::find(als31300::EEPROM_REGS.begin(), als31300::EEPROM_REGS.end(), address);
return it != als31300::EEPROM_REGS.end();
}
- auto getThresholdLevel(std::uint16_t gaussThreshold) -> std::uint8_t
- {
- return floor(((gaussThreshold + 1) / 32.0) - 1); // calculation formula taken from ALS datasheet
- }
} // namespace
std::shared_ptr<DriverGPIO> gpio;
bsp::KeyCodes current_parsed = bsp::KeyCodes::Undefined;
- bool setActive(als31300::PWR_REG_SLEEP_MODE sleep_mode);
+ static TimerHandle_t timerHandle;
+ static constexpr uint16_t MAGNETOMETER_POLL_INTERVAL_MS = 500;
- bsp::KeyCodes getCurrentSliderPosition()
+ static void TimerHandler(TimerHandle_t xTimer)
{
- return current_parsed;
+ if (qHandleIrq != nullptr) {
+ uint8_t val = 0x01;
+ xQueueSend(qHandleIrq, &val, 0);
+ }
}
+ bool setActive(als31300::PWR_REG_SLEEP_MODE sleep_mode);
+
bool i2cRead(const uint8_t reg_addr, als31300::whole_reg_t &whole_reg)
{
addr.subAddress = reg_addr;
- auto readBytes = i2c->Read(addr, i2c_buf.buf, sizeof(als31300::whole_reg_t));
- if (readBytes != sizeof(als31300::whole_reg_t)) {
+ if (i2c->Read(addr, i2c_buf.buf, sizeof(als31300::whole_reg_t)) != sizeof(als31300::whole_reg_t)) {
return false;
}
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
@@ 99,9 121,11 @@ namespace bsp
// any configuration must be proceeded in active state
setActive(als31300::PWR_REG_SLEEP_MODE::active);
+
// GET WRITE ACCESS
if (!i2cWrite(als31300::CUSTOMER_ACCESS_REG, als31300::CUSTOMER_ACCESS_REG_code)) {
- LOG_WARN("magneto: Customer access already unlocked or write error");
+ LOG_ERROR("magneto: CANNOT INIT SLIDER SENSOR");
+ return kStatus_Fail;
}
// CONFIGURATION register read
@@ 115,12 139,10 @@ namespace bsp
reg_conf.channel_X_en = als31300::CONF_REG_CHANNEL_enabled;
reg_conf.channel_Y_en = als31300::CONF_REG_CHANNEL_enabled;
reg_conf.channel_Z_en = als31300::CONF_REG_CHANNEL_disabled;
- reg_conf.bandwidth = static_cast<std::uint8_t>(als31300::BANDWIDTH_SELECT::bandwidth_7kHz);
+ reg_conf.bandwidth = static_cast<uint8_t>(BANDWIDTH_SELECT::bandwidth_7kHz);
if (current_reg_conf != reg_conf) {
- if (!i2cWrite(als31300::CONF_REG, reg_conf)) {
- LOG_ERROR("magneto: CANNOT INIT SLIDER SENSOR");
- return kStatus_Fail;
- }
+ [[maybe_unused]] auto ret = i2cWrite(als31300::CONF_REG, reg_conf);
+ assert(ret);
LOG_DEBUG("CONF wrote:\t%" PRIu32, static_cast<uint32_t>(reg_conf));
i2cRead(als31300::CONF_REG, read_reg);
@@ 136,16 158,17 @@ namespace bsp
LOG_DEBUG("INT read:\t%" PRIu32, static_cast<uint32_t>(current_reg_int));
als31300::int_reg reg_int = current_reg_int;
reg_int.int_eeprom_en = als31300::INT_REG_INT_EEPROM_disable;
- reg_int.int_mode = als31300::INT_REG_INT_MODE_delta;
+ reg_int.int_mode = als31300::INT_REG_INT_MODE_threshold;
reg_int.int_threshold_signed = als31300::INT_REG_THRESHOLD_absolute;
- reg_int.int_X_en = als31300::INT_REG_INT_CHANNEL_enabled;
- reg_int.int_Y_en = als31300::INT_REG_INT_CHANNEL_enabled;
+ reg_int.int_X_en = als31300::INT_REG_INT_CHANNEL_disabled;
+ reg_int.int_Y_en = als31300::INT_REG_INT_CHANNEL_disabled;
reg_int.int_Z_en = als31300::INT_REG_INT_CHANNEL_disabled;
- reg_int.int_X_threshold = getThresholdLevel(32);
- reg_int.int_Y_threshold = getThresholdLevel(128);
+ reg_int.int_X_threshold = 1;
+ reg_int.int_Y_threshold = 4;
reg_int.int_Z_threshold = 0;
if (current_reg_int != reg_int) {
- i2cWrite(als31300::INT_REG, reg_int);
+ [[maybe_unused]] auto ret = i2cWrite(als31300::INT_REG, reg_int);
+ assert(ret);
LOG_DEBUG("INT wrote:\t%" PRIu32, static_cast<uint32_t>(reg_int));
i2cRead(als31300::INT_REG, read_reg);
@@ 165,8 188,17 @@ namespace bsp
.irqMode = DriverGPIOPinParams::InterruptMode::IntFallingEdge,
.defLogic = 0,
.pin = static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ)});
-
- enableIRQ();
+ // NOTE: irq not yet enabled
+ // this version uses timer to poll the sensor
+ // the timer requests to read the magnetometer periodically
+ if (timerHandle == nullptr) {
+ timerHandle = xTimerCreate(
+ "SliderTimer", pdMS_TO_TICKS(MAGNETOMETER_POLL_INTERVAL_MS), true, nullptr, TimerHandler);
+ if (timerHandle == nullptr) {
+ LOG_FATAL("Could not create the timer for Headset insertion/removal detection");
+ return kStatus_Fail;
+ }
+ }
// POWER register
i2cRead(als31300::PWR_REG, read_reg);
@@ 175,12 207,13 @@ namespace bsp
als31300::pwr_reg reg_pwr = current_reg_pwr;
reg_pwr.I2C_loop_mode = als31300::PWR_REG_LOOP_MODE_single; // we don't want constant data flow
reg_pwr.sleep = als31300::PWR_REG_SLEEP_MODE_active;
- reg_pwr.count_max_LP_mode = static_cast<std::uint8_t>(als31300::LPDCM_INACTIVE_TIME::inactive_100ms);
+ reg_pwr.count_max_LP_mode = static_cast<uint8_t>(LPDCM_INACTIVE_TIME::inactive_10ms);
i2cWrite(als31300::PWR_REG, reg_pwr);
LOG_DEBUG("POWER wrote:\t%" PRIu32, static_cast<uint32_t>(reg_pwr));
- initFirstReadout();
+ xTimerStart(timerHandle, 1000);
+
return kStatus_Success;
}
@@ 197,21 230,30 @@ namespace bsp
if (reg_msb.int_flag == true) {
LOG_DEBUG("magneto: INT flag in register");
- if (!i2cWrite(als31300::MEASUREMENTS_MSB_REG, reg_msb)) {
- return std::make_pair(false, Measurements()); // todo: null opt
- }
}
- Measurements meas;
- i2cRead(als31300::MEASUREMENTS_LSB_REG, read_reg);
+ if (reg_msb.new_data_flag != als31300::MEAS_REG_NEW_DATA_available) {
+ return std::make_pair(false, Measurements());
+ }
+ else {
+ if (reg_msb.int_flag == true) {
+ // clear INT flag
+ if (!i2cWrite(als31300::MEASUREMENTS_MSB_REG, reg_msb)) {
+ return std::make_pair(false, Measurements()); // todo: null opt
+ }
+ }
+ Measurements meas;
+
+ i2cRead(als31300::MEASUREMENTS_LSB_REG, read_reg);
- als31300::measurements_LSB_reg reg_lsb = read_reg;
+ als31300::measurements_LSB_reg reg_lsb = read_reg;
- meas.X = als31300::measurement_sign_convert(reg_msb.X_MSB << 4 | reg_lsb.X_LSB);
- meas.Y = als31300::measurement_sign_convert(reg_msb.Y_MSB << 4 | reg_lsb.Z_LSB);
- meas.Z = als31300::measurement_sign_convert(reg_msb.Z_MSB << 4 | reg_lsb.Z_LSB);
+ meas.X = als31300::measurement_sign_convert(reg_msb.X_MSB << 4 | reg_lsb.X_LSB);
+ meas.Y = als31300::measurement_sign_convert(reg_msb.Y_MSB << 4 | reg_lsb.Z_LSB);
+ meas.Z = als31300::measurement_sign_convert(reg_msb.Z_MSB << 4 | reg_lsb.Z_LSB);
- return std::pair(true, meas);
+ return std::pair(true, meas);
+ }
}
bool setActive(als31300::PWR_REG_SLEEP_MODE sleep_mode)
@@ 220,14 262,12 @@ namespace bsp
als31300::whole_reg_t read_reg;
if (!i2cRead(als31300::PWR_REG, read_reg)) {
- LOG_ERROR("setActive: cannot read PWR REG!");
return false;
}
als31300::pwr_reg reg_pwr = read_reg;
- reg_pwr.sleep = static_cast<std::uint8_t>(sleep_mode);
+ reg_pwr.sleep = sleep_mode;
if (!i2cWrite(als31300::PWR_REG, reg_pwr)) {
- LOG_ERROR("setActive: cannot write PWR REG!");
return false;
}
if (sleep_mode == als31300::PWR_REG_SLEEP_MODE::active ||
@@ 243,10 283,7 @@ namespace bsp
addr.subAddress = 0x00;
auto read = i2c->Read(addr, &buf, 1);
- if (read != 1) {
- return false;
- }
- return true;
+ return read == 1;
}
bsp::KeyCodes parse(const Measurements &measurements)
@@ 280,21 317,17 @@ namespace bsp
}
return bsp::KeyCodes::Undefined;
}
- void initFirstReadout()
+ void resetCurrentParsedValue()
{
current_parsed = bsp::KeyCodes::Undefined;
- if (qHandleIrq != NULL) {
- std::uint8_t val = als31300::DUMMY_BYTE;
- constexpr auto ticksToWait = 1000;
- xQueueSend(qHandleIrq, &val, pdMS_TO_TICKS(ticksToWait));
- }
}
std::optional<bsp::KeyCodes> WorkerEventHandler()
{
+ // try to get new data from active magneto
setActive(als31300::PWR_REG_SLEEP_MODE::active);
auto [new_data, measurement] = getMeasurement();
- setActive(als31300::PWR_REG_SLEEP_MODE::periodic_active);
+ setActive(als31300::PWR_REG_SLEEP_MODE::sleep);
if (new_data) {
auto incoming_parsed = parse(measurement);
if (incoming_parsed != bsp::KeyCodes::Undefined and incoming_parsed != current_parsed) {
@@ 307,9 340,10 @@ namespace bsp
BaseType_t IRQHandler()
{
+ gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ));
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (qHandleIrq != NULL) {
- std::uint8_t val = als31300::DUMMY_BYTE;
+ uint8_t val = 0x01;
xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
}
return xHigherPriorityTaskWoken;
M module-bsp/board/rt1051/drivers/RT1051DriverI2C.cpp => module-bsp/board/rt1051/drivers/RT1051DriverI2C.cpp +0 -2
@@ 50,7 50,6 @@ namespace drivers
auto ret = BOARD_LPI2C_Send(
base, addr.deviceAddress, addr.subAddress, addr.subAddressSize, const_cast<uint8_t *>(txBuff), size);
if (ret != kStatus_Success) {
- LOG_ERROR("I2C Write: Error %ld", ret);
return -1; // TODO:M.P: fix me
}
else {
@@ 63,7 62,6 @@ namespace drivers
cpp_freertos::LockGuard lock(mutex);
auto ret = BOARD_LPI2C_Receive(base, addr.deviceAddress, addr.subAddress, addr.subAddressSize, rxBuff, size);
if (ret != kStatus_Success) {
- LOG_ERROR("I2C Read: Error %ld", ret);
return -1; // TODO:M.P: fix me
}
else {
M module-bsp/bsp/BoardDefinitions.hpp => module-bsp/bsp/BoardDefinitions.hpp +2 -3
@@ 18,9 18,8 @@ enum class BoardDefinitions
USB_FUNCTION_MUX_SELECT = 25, // GPIO_AD_B1_09, USB_MUX_SEL0
USB_POWER_ACK = 3, // GPIO_B0_03 Note: pull-up in order to read
+ I2C_STD_BAUDRATE = 100000,
- I2C_STD_BAUDRATE = 100000,
- I2C_FAST_BAUDRATE = 400000,
AUDIOCODEC_I2C_BAUDRATE = I2C_STD_BAUDRATE,
AUDIOCODEC_I2C = static_cast<int>(drivers::I2CInstances ::I2C2),
AUDIOCODEC_DMAMUX = static_cast<int>(drivers::DMAMuxInstances ::DMAMUX0),
@@ 107,7 106,7 @@ enum class BoardDefinitions
VIBRATOR_EN = 0, // GPIO_AD_B0_00
MAGNETOMETER_I2C = AUDIOCODEC_I2C,
- MAGNETOMETER_I2C_BAUDRATE = I2C_FAST_BAUDRATE,
+ MAGNETOMETER_I2C_BAUDRATE = AUDIOCODEC_I2C_BAUDRATE,
MAGNETOMETER_GPIO = static_cast<int>(drivers::GPIOInstances::GPIO_1),
MAGNETOMETER_IRQ = 20, // GPIO_AD_B1_04
M module-bsp/bsp/magnetometer/magnetometer.hpp => module-bsp/bsp/magnetometer/magnetometer.hpp +1 -2
@@ 39,8 39,7 @@ namespace bsp
bsp::KeyCodes parse(const Measurements &measurements);
std::optional<bsp::KeyCodes> WorkerEventHandler();
- void initFirstReadout();
- bsp::KeyCodes getCurrentSliderPosition();
+ void resetCurrentParsedValue();
BaseType_t IRQHandler();
void enableIRQ();
M module-services/service-evtmgr/WorkerEvent.cpp => module-services/service-evtmgr/WorkerEvent.cpp +5 -1
@@ 184,7 184,10 @@ bool WorkerEvent::handleMessage(uint32_t queueID)
if (!queue->Dequeue(¬ification, 0)) {
return false;
}
- processKeyEvent(bsp::KeyEvents::Pressed, bsp::magnetometer::getCurrentSliderPosition());
+
+ bsp::magnetometer::resetCurrentParsedValue();
+ LOG_WARN("Received notify, current value reset!");
+ handleMagnetometerEvent();
}
if (queueID == static_cast<uint32_t>(WorkerEventQueues::queueMagnetometerIRQ)) {
@@ 244,6 247,7 @@ bool WorkerEvent::init(std::list<sys::WorkerQueueInfo> queuesList)
auto sentinelRegistrationMsg = std::make_shared<sys::SentinelRegistrationMessage>(cpuSentinel);
service->bus.sendUnicast(std::move(sentinelRegistrationMsg), service::name::system_manager);
+
return true;
}