From 40f6bd9c6cee9e88ffd08f21bb8ec0d7103efee8 Mon Sep 17 00:00:00 2001 From: Adelin Dobre Date: Mon, 16 Jul 2018 18:12:37 +0300 Subject: [PATCH] BMA250E: Add string based constructor Signed-off-by: Adelin Dobre Signed-off-by: Mihai Tudor Panu --- src/bma250e/bma250e.cxx | 193 ++++++++++++++++++++++++++++++++++++++++ src/bma250e/bma250e.hpp | 10 ++- 2 files changed, 202 insertions(+), 1 deletion(-) diff --git a/src/bma250e/bma250e.cxx b/src/bma250e/bma250e.cxx index e219dbe9..4aa51e5e 100644 --- a/src/bma250e/bma250e.cxx +++ b/src/bma250e/bma250e.cxx @@ -30,6 +30,7 @@ #include #include "bma250e.hpp" +#include "upm_string_parser.hpp" using namespace upm; using namespace std; @@ -49,6 +50,198 @@ BMA250E::BMA250E(int bus, int addr, int cs) : + ": bma250e_init() failed"); } +BMA250E::BMA250E(std::string initStr) : mraaIo(initStr) +{ + mraa_io_descriptor* descs = mraaIo.getMraaDescriptors(); + std::vector upmTokens; + + if(!mraaIo.getLeftoverStr().empty()) { + upmTokens = UpmStringParser::parse(mraaIo.getLeftoverStr()); + } + + m_bma250e = (bma250e_context)malloc(sizeof(struct _bma250e_context)); + if(!m_bma250e) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": bma250e_init() failed"); + } + + // zero out context + memset((void *)m_bma250e, 0, sizeof(struct _bma250e_context)); + + // make sure MRAA is initialized + int mraa_rv; + if ((mraa_rv = mraa_init()) != MRAA_SUCCESS) + { + bma250e_close(m_bma250e); + throw std::runtime_error(std::string(__FUNCTION__) + + ": mraa_init() failed"); + } + + if(descs->spis) { + m_bma250e->isSPI = true; + if( !(m_bma250e->spi = descs->spis[0]) ) { + bma250e_close(m_bma250e); + throw std::runtime_error(std::string(__FUNCTION__) + + ": mraa_spi_init() failed"); + } + if(descs->gpios) { + if( !(m_bma250e->gpioCS = descs->gpios[0]) ) { + bma250e_close(m_bma250e); + throw std::runtime_error(std::string(__FUNCTION__) + + ": mraa_gpio_init() failed"); + } + mraa_gpio_dir(m_bma250e->gpioCS, MRAA_GPIO_OUT); + } else { + throw std::runtime_error(std::string(__FUNCTION__) + + ": mraa_gpio_init() failed"); + } + mraa_spi_mode(m_bma250e->spi, MRAA_SPI_MODE0); + if (mraa_spi_frequency(m_bma250e->spi, 5000000)) { + bma250e_close(m_bma250e); + throw std::runtime_error(std::string(__FUNCTION__) + + ": mraa_spi_frequency() failed"); + } + } else { + // init the i2c context + if(!descs->i2cs) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": mraa_i2c_init() failed"); + } else { + if( !(m_bma250e->i2c = descs->i2cs[0]) ) + { + bma250e_close(m_bma250e); + throw std::runtime_error(std::string(__FUNCTION__) + + ": mraa_i2c_init() failed"); + } + } + } + + // check the chip id + + uint8_t chipID = bma250e_get_chip_id(m_bma250e); + + // check the various chips id's and set appropriate capabilities. + // Bail if the chip id is unknown. + switch (chipID) + { + case 0xf9: // standalone bma250e + m_bma250e->resolution = BMA250E_RESOLUTION_10BITS; + m_bma250e->fifoAvailable = true; + + break; + + case 0xfa: // bmx055, bmi055 variants, 12b resolution + m_bma250e->resolution = BMA250E_RESOLUTION_12BITS; + m_bma250e->fifoAvailable = true; + + break; + + case 0x03: // bmc050 variant, no FIFO, 12b resolution + m_bma250e->resolution = BMA250E_RESOLUTION_12BITS; + m_bma250e->fifoAvailable = false; + + break; + + default: + printf("%s: invalid chip id: %02x. Expected f9, fa, or 03\n", + __FUNCTION__, chipID); + bma250e_close(m_bma250e); + throw std::runtime_error(std::string(__FUNCTION__) + + ": bma250e_init() failed"); + } + + // call devinit with default options + if (bma250e_devinit(m_bma250e, BMA250E_POWER_MODE_NORMAL, BMA250E_RANGE_2G, + BMA250E_BW_250)) + { + printf("%s: bma250e_devinit() failed.\n", __FUNCTION__); + bma250e_close(m_bma250e); + throw std::runtime_error(std::string(__FUNCTION__) + + ": bma250e_init() failed"); + } + + std::string::size_type sz; + for(std::string tok:upmTokens) { + if(tok.substr(0,11) == "enableFIFO:") { + bool useFIFO = std::stoi(tok.substr(11),&sz,0); + enableFIFO(useFIFO); + } + if(tok.substr(0,9) == "writeReg:") { + uint8_t reg = std::stoi(tok.substr(9),&sz,0); + tok = tok.substr(9); + uint8_t val = std::stoi(tok.substr(sz+1),nullptr,0); + writeReg(reg, val); + } + if(tok.substr(0,9) == "setRange:") { + BMA250E_RANGE_T scale = (BMA250E_RANGE_T)std::stoi(tok.substr(22),nullptr,0); + setRange(scale); + } + + if(tok.substr(0,13) == "setBandwidth:") { + BMA250E_BW_T bw = (BMA250E_BW_T)std::stoi(tok.substr(13),nullptr,0); + setBandwidth(bw); + } + if(tok.substr(0,13) == "setPowerMode:") { + BMA250E_POWER_MODE_T power = (BMA250E_POWER_MODE_T)std::stoi(tok.substr(13),nullptr,0); + setPowerMode(power); + } + if(tok.substr(0,17) == "fifoSetWatermark:") { + BMA250E_RANGE_T wm = (BMA250E_RANGE_T)std::stoi(tok.substr(17),nullptr,0); + fifoSetWatermark(wm); + } + if(tok.substr(0,11) == "fifoConfig:") { + BMA250E_FIFO_MODE_T mode = (BMA250E_FIFO_MODE_T)std::stoi(tok.substr(11),&sz,0); + tok = tok.substr(11); + BMA250E_FIFO_DATA_SEL_T axes = (BMA250E_FIFO_DATA_SEL_T)std::stoi(tok.substr(sz+1),nullptr,0); + fifoConfig(mode, axes); + } + if(tok.substr(0,20) == "setInterruptEnable0:") { + u_int8_t bits = (u_int8_t)std::stoi(tok.substr(20),nullptr,0); + setInterruptEnable0(bits); + } + if(tok.substr(0,20) == "setInterruptEnable1:") { + u_int8_t bits = (u_int8_t)std::stoi(tok.substr(20),nullptr,0); + setInterruptEnable1(bits); + } + if(tok.substr(0,20) == "setInterruptEnable2:") { + u_int8_t bits = (u_int8_t)std::stoi(tok.substr(20),nullptr,0); + setInterruptEnable2(bits); + } + if(tok.substr(0,17) == "setInterruptMap0:") { + u_int8_t bits = (u_int8_t)std::stoi(tok.substr(17),nullptr,0); + setInterruptMap0(bits); + } + if(tok.substr(0,17) == "setInterruptMap1:") { + u_int8_t bits = (u_int8_t)std::stoi(tok.substr(17),nullptr,0); + setInterruptMap1(bits); + } + if(tok.substr(0,17) == "setInterruptMap2:") { + u_int8_t bits = (u_int8_t)std::stoi(tok.substr(17),nullptr,0); + setInterruptMap2(bits); + } + if(tok.substr(0,16) == "setInterruptSrc:") { + u_int8_t bits = (u_int8_t)std::stoi(tok.substr(16),nullptr,0); + setInterruptSrc(bits); + } + if(tok.substr(0,26) == "setInterruptOutputControl:") { + u_int8_t bits = (u_int8_t)std::stoi(tok.substr(26),nullptr,0); + setInterruptOutputControl(bits); + } + if(tok.substr(0,26) == "setInterruptLatchBehavior:") { + BMA250E_RST_LATCH_T latch = (BMA250E_RST_LATCH_T)std::stoi(tok.substr(26),nullptr,0); + setInterruptLatchBehavior(latch); + } + if(tok.substr(0,24) == "enableRegisterShadowing:") { + bool shadow = std::stoi(tok.substr(24),nullptr,0); + enableRegisterShadowing(shadow); + } + if(tok.substr(0,22) == "enableOutputFiltering:") { + bool filter = std::stoi(tok.substr(22),nullptr,0); + enableOutputFiltering(filter); + } + } +} + BMA250E::~BMA250E() { bma250e_close(m_bma250e); diff --git a/src/bma250e/bma250e.hpp b/src/bma250e/bma250e.hpp index fb4e6b21..a44ef0ae 100644 --- a/src/bma250e/bma250e.hpp +++ b/src/bma250e/bma250e.hpp @@ -28,6 +28,7 @@ #include #include +#include #include #include "bma250e.h" @@ -98,6 +99,13 @@ namespace upm { int addr=BMA250E_DEFAULT_ADDR, int cs=-1); + /** + * Instantiates BMA250E 3-axis Accelerometer based on a given string. + * + * @param initStr string containing specific information for BMA250E initialization. + */ + BMA250E(std::string initStr); + /** * BMA250E Destructor. */ @@ -581,11 +589,11 @@ namespace upm { protected: bma250e_context m_bma250e; + mraa::MraaIo mraaIo; private: /* Disable implicit copy and assignment operators */ BMA250E(const BMA250E&) = delete; BMA250E &operator=(const BMA250E&) = delete; - }; }