2021-12-30 23:16:03 -05:00
|
|
|
#include "bma.h"
|
|
|
|
|
|
|
|
#define DEBUGPORT Serial
|
|
|
|
#ifdef DEBUGPORT
|
2022-04-28 21:17:00 -04:00
|
|
|
#define DEBUG(...) DEBUGPORT.printf(__VA_ARGS__)
|
2021-12-30 23:16:03 -05:00
|
|
|
#else
|
|
|
|
#define DEBUG(...)
|
|
|
|
#endif
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
BMA423::BMA423() {
|
|
|
|
__readRegisterFptr = nullptr;
|
|
|
|
__writeRegisterFptr = nullptr;
|
|
|
|
__delayCallBlackFptr = nullptr;
|
|
|
|
__init = false;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
BMA423::~BMA423() {}
|
2021-12-30 23:16:03 -05:00
|
|
|
|
|
|
|
bool BMA423::begin(bma4_com_fptr_t readCallBlack,
|
|
|
|
bma4_com_fptr_t writeCallBlack,
|
2022-04-28 21:17:00 -04:00
|
|
|
bma4_delay_fptr_t delayCallBlack, uint8_t address) {
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
if (__init || readCallBlack == nullptr || writeCallBlack == nullptr ||
|
|
|
|
delayCallBlack == nullptr) {
|
|
|
|
return true;
|
|
|
|
}
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
__readRegisterFptr = readCallBlack;
|
|
|
|
__writeRegisterFptr = writeCallBlack;
|
|
|
|
__delayCallBlackFptr = delayCallBlack;
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
__devFptr.dev_addr = address;
|
|
|
|
__devFptr.interface = BMA4_I2C_INTERFACE;
|
|
|
|
__devFptr.bus_read = readCallBlack;
|
|
|
|
__devFptr.bus_write = writeCallBlack;
|
|
|
|
__devFptr.delay = delayCallBlack;
|
|
|
|
__devFptr.read_write_len = 8;
|
|
|
|
__devFptr.resolution = 12;
|
|
|
|
__devFptr.feature_len = BMA423_FEATURE_SIZE;
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
softReset();
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
__delayCallBlackFptr(20);
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
if (bma423_init(&__devFptr) != BMA4_OK) {
|
|
|
|
DEBUG("BMA423 FAIL\n");
|
|
|
|
return false;
|
|
|
|
}
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
if (bma423_write_config_file(&__devFptr) != BMA4_OK) {
|
|
|
|
DEBUG("BMA423 Write Config FAIL\n");
|
|
|
|
return false;
|
|
|
|
}
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
__init = true;
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
struct bma4_int_pin_config config;
|
|
|
|
config.edge_ctrl = BMA4_LEVEL_TRIGGER;
|
|
|
|
config.lvl = BMA4_ACTIVE_HIGH;
|
|
|
|
config.od = BMA4_PUSH_PULL;
|
|
|
|
config.output_en = BMA4_OUTPUT_ENABLE;
|
|
|
|
config.input_en = BMA4_INPUT_DISABLE;
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
if (bma4_set_int_pin_config(&config, BMA4_INTR1_MAP, &__devFptr) != BMA4_OK) {
|
|
|
|
DEBUG("BMA423 SET INT FAIL\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
void BMA423::softReset() {
|
|
|
|
uint8_t reg = BMA4_RESET_ADDR;
|
|
|
|
__writeRegisterFptr(BMA4_I2C_ADDR_PRIMARY, BMA4_RESET_SET_MASK, ®, 1);
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
void BMA423::shutDown() {
|
|
|
|
bma4_set_advance_power_save(BMA4_DISABLE, &__devFptr);
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
void BMA423::wakeUp() { bma4_set_advance_power_save(BMA4_ENABLE, &__devFptr); }
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
uint16_t BMA423::getErrorCode() {
|
|
|
|
struct bma4_err_reg err;
|
|
|
|
uint16_t rslt = bma4_get_error_status(&err, &__devFptr);
|
|
|
|
return rslt;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
uint16_t BMA423::getStatus() {
|
|
|
|
uint8_t status;
|
|
|
|
bma4_get_status(&status, &__devFptr);
|
|
|
|
return status;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
uint32_t BMA423::getSensorTime() {
|
|
|
|
uint32_t ms;
|
|
|
|
bma4_get_sensor_time(&ms, &__devFptr);
|
|
|
|
return ms;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::selfTest() {
|
|
|
|
return (BMA4_OK ==
|
|
|
|
bma4_selftest_config(BMA4_ACCEL_SELFTEST_ENABLE_MSK, &__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
uint8_t BMA423::getDirection() {
|
|
|
|
Accel acc;
|
|
|
|
if (bma4_read_accel_xyz(&acc, &__devFptr) != BMA4_OK) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
uint16_t absX = abs(acc.x);
|
|
|
|
uint16_t absY = abs(acc.y);
|
|
|
|
uint16_t absZ = abs(acc.z);
|
|
|
|
|
|
|
|
if ((absZ > absX) && (absZ > absY)) {
|
|
|
|
if (acc.z > 0) {
|
|
|
|
return DIRECTION_DISP_DOWN;
|
|
|
|
} else {
|
|
|
|
return DIRECTION_DISP_UP;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
2022-04-28 21:17:00 -04:00
|
|
|
} else if ((absY > absX) && (absY > absZ)) {
|
|
|
|
if (acc.y > 0) {
|
|
|
|
return DIRECTION_RIGHT_EDGE;
|
2021-12-30 23:16:03 -05:00
|
|
|
} else {
|
2022-04-28 21:17:00 -04:00
|
|
|
return DIRECTION_LEFT_EDGE;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
2022-04-28 21:17:00 -04:00
|
|
|
} else {
|
|
|
|
if (acc.x < 0) {
|
|
|
|
return DIRECTION_BOTTOM_EDGE;
|
|
|
|
} else {
|
|
|
|
return DIRECTION_TOP_EDGE;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
2022-04-28 21:17:00 -04:00
|
|
|
}
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
float BMA423::readTemperature() {
|
|
|
|
int32_t data = 0;
|
|
|
|
bma4_get_temperature(&data, BMA4_DEG, &__devFptr);
|
|
|
|
float res = (float)data / (float)BMA4_SCALE_TEMP;
|
|
|
|
/* 0x80 - temp read from the register and 23 is the ambient temp added.
|
|
|
|
* If the temp read from register is 0x80, it means no valid
|
|
|
|
* information is available */
|
|
|
|
if (((data - 23) / BMA4_SCALE_TEMP) == 0x80) {
|
|
|
|
res = 0;
|
|
|
|
}
|
|
|
|
return res;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
float BMA423::readTemperatureF() {
|
|
|
|
float temp = readTemperature();
|
|
|
|
if (temp != 0) {
|
|
|
|
temp = temp * 1.8 + 32.0;
|
|
|
|
}
|
|
|
|
return (temp);
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::getAccel(Accel &acc) {
|
|
|
|
memset(&acc, 0, sizeof(acc));
|
|
|
|
if (bma4_read_accel_xyz(&acc, &__devFptr) != BMA4_OK) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::getAccelEnable() {
|
|
|
|
uint8_t en;
|
|
|
|
bma4_get_accel_enable(&en, &__devFptr);
|
|
|
|
return (en & BMA4_ACCEL_ENABLE_POS) == BMA4_ACCEL_ENABLE_POS;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::disableAccel() { return enableAccel(false); }
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::enableAccel(bool en) {
|
|
|
|
return (BMA4_OK ==
|
|
|
|
bma4_set_accel_enable(en ? BMA4_ENABLE : BMA4_DISABLE, &__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::setAccelConfig(Acfg &cfg) {
|
|
|
|
return (BMA4_OK == bma4_set_accel_config(&cfg, &__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::getAccelConfig(Acfg &cfg) {
|
|
|
|
return (BMA4_OK == bma4_get_accel_config(&cfg, &__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::setRemapAxes(struct bma423_axes_remap *remap_data) {
|
|
|
|
return (BMA4_OK == bma423_set_remap_axes(remap_data, &__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::resetStepCounter() {
|
|
|
|
return BMA4_OK == bma423_reset_step_counter(&__devFptr);
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
uint32_t BMA423::getCounter() {
|
|
|
|
uint32_t stepCount;
|
|
|
|
if (bma423_step_counter_output(&stepCount, &__devFptr) == BMA4_OK) {
|
|
|
|
return stepCount;
|
|
|
|
}
|
|
|
|
return 0;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::setINTPinConfig(struct bma4_int_pin_config config,
|
|
|
|
uint8_t pinMap) {
|
|
|
|
return BMA4_OK == bma4_set_int_pin_config(&config, pinMap, &__devFptr);
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::getINT() {
|
|
|
|
return bma423_read_int_status(&__IRQ_MASK, &__devFptr) == BMA4_OK;
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
uint8_t BMA423::getIRQMASK() { return __IRQ_MASK; }
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::disableIRQ(uint16_t int_map) {
|
|
|
|
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, int_map, BMA4_DISABLE,
|
|
|
|
&__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::enableIRQ(uint16_t int_map) {
|
|
|
|
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, int_map, BMA4_ENABLE,
|
|
|
|
&__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::enableFeature(uint8_t feature, uint8_t enable) {
|
|
|
|
if ((feature & BMA423_STEP_CNTR) == BMA423_STEP_CNTR) {
|
|
|
|
bma423_step_detector_enable(enable ? BMA4_ENABLE : BMA4_DISABLE,
|
|
|
|
&__devFptr);
|
|
|
|
}
|
|
|
|
return (BMA4_OK == bma423_feature_enable(feature, enable, &__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::isStepCounter() {
|
|
|
|
return (bool)(BMA423_STEP_CNTR_INT & __IRQ_MASK);
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::isDoubleClick() { return (bool)(BMA423_WAKEUP_INT & __IRQ_MASK); }
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::isTilt() { return (bool)(BMA423_TILT_INT & __IRQ_MASK); }
|
|
|
|
|
|
|
|
bool BMA423::isActivity() { return (bool)(BMA423_ACTIVITY_INT & __IRQ_MASK); }
|
2021-12-30 23:16:03 -05:00
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::isAnyNoMotion() {
|
|
|
|
return (bool)(BMA423_ANY_NO_MOTION_INT & __IRQ_MASK);
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::enableStepCountInterrupt(bool en) {
|
|
|
|
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_STEP_CNTR_INT,
|
|
|
|
en, &__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::enableTiltInterrupt(bool en) {
|
|
|
|
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_TILT_INT, en,
|
|
|
|
&__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::enableWakeupInterrupt(bool en) {
|
|
|
|
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_WAKEUP_INT, en,
|
|
|
|
&__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::enableAnyNoMotionInterrupt(bool en) {
|
|
|
|
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP,
|
|
|
|
BMA423_ANY_NO_MOTION_INT, en,
|
|
|
|
&__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
bool BMA423::enableActivityInterrupt(bool en) {
|
|
|
|
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_ACTIVITY_INT,
|
|
|
|
en, &__devFptr));
|
2021-12-30 23:16:03 -05:00
|
|
|
}
|
|
|
|
|
2022-04-28 21:17:00 -04:00
|
|
|
const char *BMA423::getActivity() {
|
|
|
|
uint8_t activity;
|
|
|
|
bma423_activity_output(&activity, &__devFptr);
|
|
|
|
if (activity & BMA423_USER_STATIONARY) {
|
|
|
|
return "BMA423_USER_STATIONARY";
|
|
|
|
} else if (activity & BMA423_USER_WALKING) {
|
|
|
|
return "BMA423_USER_WALKING";
|
|
|
|
} else if (activity & BMA423_USER_RUNNING) {
|
|
|
|
return "BMA423_USER_RUNNING";
|
|
|
|
} else if (activity & BMA423_STATE_INVALID) {
|
|
|
|
return "BMA423_STATE_INVALID";
|
|
|
|
}
|
|
|
|
return "None";
|
2020-02-23 13:49:44 -05:00
|
|
|
}
|