diff --git a/MC36XX.cpp b/MC36XX.cpp index 174e8ea..fd34378 100644 --- a/MC36XX.cpp +++ b/MC36XX.cpp @@ -1,17 +1,37 @@ +/****************************************************************************** + * + * Copyright (c) 2018 mCube, Inc. All rights reserved. + * + * This source is subject to the mCube Software License. + * This software is protected by Copyright and the information and source code + * contained herein is confidential. The software including the source code + * may not be copied and the information contained herein may not be used or + * disclosed except with the written permission of mCube Inc. + * + * All other rights reserved. + *****************************************************************************/ + +/** + * @file MC36XX.c + * @author mCube + * @date 10 May 2018 + * @brief Driver interface header file for accelerometer mc36xx series. + * @see http://www.mcubemems.com + */ #include "MC36XX.h" - -#ifdef MC36XX_CFG_BUS_I2C - #define MC36XX_CFG_I2C_ADDR (0x4C) + +#ifdef MC36XX_CFG_BUS_I2C + #define MC36XX_CFG_I2C_ADDR (0x4C) #endif -#define MC36XX_CFG_MODE_DEFAULT MC36XX_MODE_STANDBY +#define MC36XX_CFG_MODE_DEFAULT MC36XX_MODE_STANDBY #define MC36XX_CFG_SAMPLE_RATE_CWAKE_DEFAULT MC36XX_CWAKE_SR_DEFAULT_54Hz -#define MC36XX_CFG_SAMPLE_RATE_SNIFF_DEFAULT MC36XX_SNIFF_SR_7Hz -#define MC36XX_CFG_RANGE_DEFAULT MC36XX_RANGE_8G -#define MC36XX_CFG_RESOLUTION_DEFAULT MC36XX_RESOLUTION_14BIT -#define MC36XX_CFG_ORIENTATION_MAP_DEFAULT ORIENTATION_TOP_RIGHT_UP +#define MC36XX_CFG_SAMPLE_RATE_SNIFF_DEFAULT MC36XX_SNIFF_SR_105Hz//MC36XX_SNIFF_SR_DEFAULT_7Hz +#define MC36XX_CFG_RANGE_DEFAULT MC36XX_RANGE_8G +#define MC36XX_CFG_RESOLUTION_DEFAULT MC36XX_RESOLUTION_14BIT +#define MC36XX_CFG_ORIENTATION_MAP_DEFAULT ORIENTATION_TOP_RIGHT_UP -uint8_t CfgRange, CfgResolution; +uint8_t CfgRange, CfgResolution, CfgFifo, CfgINT; // Read register bit bool MC36XX::readRegisterBit(uint8_t reg, uint8_t pos) @@ -21,55 +41,31 @@ bool MC36XX::readRegisterBit(uint8_t reg, uint8_t pos) return ((value >> pos) & 1); } -// Write register bit -void MC36XX::writeRegisterBit(uint8_t reg, uint8_t pos, bool state) -{ - uint8_t value; - value = readRegister8(reg); - - if (state) - value |= (1 << pos); - else - value &= ~(1 << pos); - - writeRegister8(reg, value); -} - // Read 8-bit from register uint8_t MC36XX::readRegister8(uint8_t reg) { uint8_t value; - -#ifdef MC36XX_CFG_BUS_I2C + +#ifdef MC36XX_CFG_BUS_I2C Wire.beginTransmission(MC36XX_CFG_I2C_ADDR); Wire.write(reg); - Wire.endTransmission(false); //endTransmission but keep the connection active - Wire.requestFrom(MC36XX_CFG_I2C_ADDR, 1); //Once done, bus is released by default + //endTransmission but keep the connection active + Wire.endTransmission(false); + //Once done, bus is released by default + Wire.requestFrom(MC36XX_CFG_I2C_ADDR, 1); value = Wire.read(); #else //Reads an 8-bit register with the SPI port. - digitalWrite(chipSelectPin, LOW); //Set active-low CS low to start the SPI cycle - SPI.transfer(reg | 0x80 | 0x40); //Send the register address - value = SPI.transfer(0x00); //Read the value from the register - digitalWrite(chipSelectPin, HIGH); //Raise CS -#endif + //Set active-low CS low to start the SPI cycle + digitalWrite(chipSelectPin, LOW); + //Send the register address + SPI.transfer(reg | 0x80 | 0x40); + //Read the value from the register + value = SPI.transfer(0x00); + //Raise CS + digitalWrite(chipSelectPin, HIGH); +#endif return value; -} - -// Write 8-bit to register -void MC36XX::writeRegister8(uint8_t reg, uint8_t value) -{ -#ifdef MC36XX_CFG_BUS_I2C - Wire.beginTransmission(MC36XX_CFG_I2C_ADDR); - Wire.write(reg); - Wire.write(value); - Wire.endTransmission(); -#else - digitalWrite(chipSelectPin, LOW); //Set active-low CS low to start the SPI cycle - SPI.transfer(reg | 0x40); //Send the register address - SPI.transfer(value); //Send value to write into register - digitalWrite(chipSelectPin, HIGH); //Raise CS -#endif } // Read 16-bit from register @@ -77,7 +73,7 @@ int16_t MC36XX::readRegister16(uint8_t reg) { int16_t value; -#ifdef MC36XX_CFG_BUS_I2C +#ifdef MC36XX_CFG_BUS_I2C Wire.beginTransmission(MC36XX_CFG_I2C_ADDR); Wire.write(reg); Wire.endTransmission(); @@ -85,74 +81,275 @@ int16_t MC36XX::readRegister16(uint8_t reg) while(!Wire.available()) {}; uint8_t vha = Wire.read(); uint8_t vla = Wire.read(); -#else - digitalWrite(chipSelectPin, LOW); //Set active-low CS low to start the SPI cycle - SPI.transfer(reg | 0x80 | 0x40); //Send the register address - uint8_t vha = SPI.transfer(0x00); //Send a value of 0 to read the first byte returned - uint8_t vla = SPI.transfer(0x00); //Send a value of 0 to read the second byte returned - digitalWrite(chipSelectPin, HIGH); //Raise CS -#endif - - value = vha << 8 | vla; - +#else + //Set active-low CS low to start the SPI cycle + digitalWrite(chipSelectPin, LOW); + //Send the register address + SPI.transfer(reg | 0x80 | 0x40); + //Send a value of 0 to read the first byte returned + uint8_t vha = SPI.transfer(0x00); + //Send a value of 0 to read the second byte returned + uint8_t vla = SPI.transfer(0x00); + //Raise CS + digitalWrite(chipSelectPin, HIGH); +#endif + + value = vha << 8 | vla; + return value; } +// Repeated Read Byte(s) from register +void MC36XX::readRegisters(uint8_t reg, byte *buffer, uint8_t len) +{ +#ifdef MC36XX_CFG_BUS_I2C + Wire.beginTransmission(MC36XX_CFG_I2C_ADDR); + Wire.write(reg); + //endTransmission but keep the connection active + Wire.endTransmission(false); + //Ask for bytes, once done, bus is released by default + Wire.requestFrom(MC36XX_CFG_I2C_ADDR, len); + + //Hang out until we get the # of bytes we expect + while(Wire.available() < len); + for(int x = 0 ; x < len ; x++) + buffer[x] = Wire.read(); +#else + //Set active-low CS low to start the SPI cycle + digitalWrite(chipSelectPin, LOW); + //send the device the register you want to read + SPI.transfer(reg | 0x80 | 0x40); + + //Prepare to clock in the data to be read + for(int x = 0 ; x < len ; x++) + buffer[x] = SPI.transfer(0x00); + //Raise CS + digitalWrite(chipSelectPin, HIGH); +#endif + +} + +// Write register bit +void MC36XX::writeRegisterBit(uint8_t reg, uint8_t pos, bool state) +{ + uint8_t value; + value = readRegister8(reg); + + if (state) + value |= (1 << pos); + else + value &= ~(1 << pos); + + writeRegister8(reg, value); +} + +// Write 8-bit to register +void MC36XX::writeRegister8(uint8_t reg, uint8_t value) +{ +#ifdef MC36XX_CFG_BUS_I2C + Wire.beginTransmission(MC36XX_CFG_I2C_ADDR); + Wire.write(reg); + Wire.write(value); + Wire.endTransmission(); +#else + //Set active-low CS low to start the SPI cycle + digitalWrite(chipSelectPin, LOW); + //Send the register address + SPI.transfer(reg | 0x40); + //Send value to write into register + SPI.transfer(value); + //Raise CS + digitalWrite(chipSelectPin, HIGH); +#endif +} + // Write 16-bit to register void MC36XX::writeRegister16(uint8_t reg, int16_t value) { -#ifdef MC36XX_CFG_BUS_I2C +#ifdef MC36XX_CFG_BUS_I2C Wire.beginTransmission(MC36XX_CFG_I2C_ADDR); Wire.write(reg); Wire.write((uint8_t)(value >> 8)); Wire.write((uint8_t)value); Wire.endTransmission(); -#else - digitalWrite(chipSelectPin, LOW); //Set active-low CS low to start the SPI cycle - SPI.transfer(reg | 0x40); //Send the register address - SPI.transfer((uint8_t)(value >> 8)); //Send value to write into register - SPI.transfer((uint8_t)value); //Send value to write into register - digitalWrite(chipSelectPin, HIGH); //Raise CS -#endif +#else + //Set active-low CS low to start the SPI cycle + digitalWrite(chipSelectPin, LOW); + //Send the register address + SPI.transfer(reg | 0x40); + //Send value to write into register + SPI.transfer((uint8_t)(value >> 8)); + //Send value to write into register + SPI.transfer((uint8_t)value); + //Raise CS + digitalWrite(chipSelectPin, HIGH); +#endif } -// Repeated Read Byte(s) from register -void MC36XX::readRegisters(uint8_t reg, byte *buffer, uint8_t len) +//Initialize the MC36XX sensor and set as the default configuration +bool MC36XX::start(void) { -#ifdef MC36XX_CFG_BUS_I2C - Wire.beginTransmission(MC36XX_CFG_I2C_ADDR); - Wire.write(reg); - Wire.endTransmission(false); //endTransmission but keep the connection active - Wire.requestFrom(MC36XX_CFG_I2C_ADDR, len); //Ask for bytes, once done, bus is released by default - while(Wire.available() < len); //Hang out until we get the # of bytes we expect - for(int x = 0 ; x < len ; x++) - buffer[x] = Wire.read(); +#ifdef MC36XX_CFG_BUS_I2C + // Initialize I2C + Wire.begin(); #else - digitalWrite(chipSelectPin, LOW); //Set active-low CS low to start the SPI cycle - SPI.transfer(reg | 0x80 | 0x40); //send the device the register you want to read - - for(int x = 0 ; x < len ; x++) //Prepare to clock in the data to be read - buffer[x] = SPI.transfer(0x00); - digitalWrite(chipSelectPin, HIGH); //Raise CS -#endif + //Set active-low CS low to start the SPI cycle + digitalWrite(chipSelectPin, HIGH); + pinMode(chipSelectPin, OUTPUT); +#if 1 + SPI.begin(); + SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE3)); +#else + SPI.setDataMode (SPI_MODE3); + SPI.setClockDivider(SPI_CLOCK_DIV8); + // Initialize SPI + SPI.begin(); +#endif +#endif + + //Init Reset + reset(); + SetMode(MC36XX_MODE_STANDBY); + + //SetWakeAGAIN + SetWakeAGAIN(MC36XX_GAIN_1X); + //SetSniffAGAIN + SetSniffAGAIN(MC36XX_GAIN_1X); + + /* Check I2C connection */ + uint8_t id = readRegister8(MC36XX_REG_PROD); + if (id != 0x71) + { + /* No MC36XX detected ... return false */ + Serial.println("No MC36XX detected!"); + Serial.println(id, HEX); + return false; + } + +//Running mc36xx in high speed SPI (8MHz) +#ifdef SPI_HS + uint8_t value; + value = readRegister8(MC36XX_REG_FEATURE_CTL); + value &= 0b00111111; + value |= 0x80 ; + writeRegister8(MC36XX_REG_FEATURE_CTL, value); + + value = readRegister8(MC36XX_REG_PMCR); + value |= 0x80 ; + writeRegister8(MC36XX_REG_PMCR, value); + SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE3)); + delay(50); +#endif + + //Range: 8g + SetRangeCtrl(MC36XX_CFG_RANGE_DEFAULT); + //Resolution: 14bit + SetResolutionCtrl(MC36XX_CFG_RESOLUTION_DEFAULT); + //Sampling Rate: 50Hz by default + SetCWakeSampleRate(MC36XX_CFG_SAMPLE_RATE_CWAKE_DEFAULT); + //Sampling Rate: 7Hz by default + SetSniffSampleRate(MC36XX_CFG_SAMPLE_RATE_SNIFF_DEFAULT); + //Mode: Active + SetMode(MC36XX_MODE_CWAKE); + + delay(50); + + return true; +} + +void MC36XX::wake() +{ + //Set mode as wake + SetMode(MC36XX_MODE_CWAKE); +} +void MC36XX::stop() +{ + //Set mode as Sleep + SetMode(MC36XX_MODE_STANDBY); } - -//Set the operation mode + +//Initial reset +void MC36XX::reset() +{ + writeRegister8(0x10, 0x01); + + delay(10); + + writeRegister8(0x24, 0x40); + + delay(50); + + writeRegister8(0x09, 0x00); + delay(10); + writeRegister8(0x0F, 0x42); + delay(10); + writeRegister8(0x20, 0x01); + delay(10); + writeRegister8(0x21, 0x80); + delay(10); + writeRegister8(0x28, 0x00); + delay(10); + writeRegister8(0x1a, 0x00); + + delay(50); + + uint8_t _bRegIO_C = 0; + + _bRegIO_C = readRegister8(0x0D); + + #ifdef MC36XX_CFG_BUS_I2C + _bRegIO_C &= 0x3F; + _bRegIO_C |= 0x40; + #else + _bRegIO_C &= 0x3F; + _bRegIO_C |= 0x80; + #endif + + writeRegister8(0x0D, _bRegIO_C); + + delay(50); + + writeRegister8(0x10, 0x01); + + delay(10); +} + +void MC36XX::sniff() +{ + //Set mode as Sleep + SetMode(MC36XX_MODE_SNIFF); +} + +void MC36XX::sniffreset() +{ + uint8_t value; + + value = readRegister8(MC36XX_REG_SNIFF_CONF_C); + value |= 0b10000000; + + writeRegister8(MC36XX_REG_SNIFF_CONF_C, value); +} + +//Set the operation mode void MC36XX::SetMode(MC36XX_mode_t mode) { uint8_t value; + uint8_t cfgfifovdd = 0x42; + value = readRegister8(MC36XX_REG_MODE_C); value &= 0b11110000; value |= mode; + + writeRegister8(MC36XX_REG_PWR_CONTROL, cfgfifovdd); writeRegister8(MC36XX_REG_MODE_C, value); } //Set the range control void MC36XX::SetRangeCtrl(MC36XX_range_t range) { - uint8_t value; + uint8_t value; CfgRange = range; SetMode(MC36XX_MODE_STANDBY); value = readRegister8(MC36XX_REG_RANGE_C); @@ -161,56 +358,96 @@ void MC36XX::SetRangeCtrl(MC36XX_range_t range) writeRegister8(MC36XX_REG_RANGE_C, value); } -//Initial reset -void MC36XX::reset() +//Set the resolution control +void MC36XX::SetResolutionCtrl(MC36XX_resolution_t resolution) { - writeRegister8(0x10, 0x01); - - delay(10); - - writeRegister8(0x24, 0x40); + uint8_t value; + CfgResolution = resolution; + SetMode(MC36XX_MODE_STANDBY); + value = readRegister8(MC36XX_REG_RANGE_C); + value &= 0b01110000; + value |= resolution; + writeRegister8(MC36XX_REG_RANGE_C, value); +} - delay(50); - - writeRegister8(0x09, 0x00); - delay(10); - writeRegister8(0x0F, 0x42); - delay(10); - writeRegister8(0x20, 0x01); - delay(10); - writeRegister8(0x21, 0x80); - delay(10); - writeRegister8(0x28, 0x00); - delay(10); - writeRegister8(0x1a, 0x00); - - delay(50); - - uint8_t _bRegIO_C = 0; +//Set the sampling rate +void MC36XX::SetCWakeSampleRate(MC36XX_cwake_sr_t sample_rate) +{ + uint8_t value; + SetMode(MC36XX_MODE_STANDBY); + value = readRegister8(MC36XX_REG_WAKE_C); + value &= 0b00000000; + value |= sample_rate; + writeRegister8(MC36XX_REG_WAKE_C, value); +} + +//Set the sniff sampling rate +void MC36XX::SetSniffSampleRate(MC36XX_sniff_sr_t sniff_sr) +{ + uint8_t value; + SetMode(MC36XX_MODE_STANDBY); + value = readRegister8(MC36XX_REG_SNIFF_C); + value &= 0b00000000; + value |= sniff_sr; + writeRegister8(MC36XX_REG_SNIFF_C, value); +} - _bRegIO_C = readRegister8(0x0D); +//Set FIFO +void MC36XX::SetFIFOCtrl(MC36XX_fifo_ctl_t fifo_ctl, + MC36XX_fifo_mode_t fifo_mode, + uint8_t fifo_thr) +{ + if (fifo_thr > 31) //maximum threshold + fifo_thr = 31; + + SetMode(MC36XX_MODE_STANDBY); + + CfgFifo = ((fifo_ctl << 6) | (fifo_mode << 5) | fifo_thr); + writeRegister8(MC36XX_REG_FIFO_C, CfgFifo); +} - #ifdef MC36XX_CFG_BUS_I2C - _bRegIO_C &= 0x3F; - _bRegIO_C |= 0x40; - #else - _bRegIO_C &= 0x3F; - _bRegIO_C |= 0x80; - #endif +//Set interrupt control register +void MC36XX::SetINTCtrl(uint8_t fifo_thr_int_ctl, + uint8_t fifo_full_int_ctl, + uint8_t fifo_empty_int_ctl, + uint8_t acq_int_ctl, + uint8_t wake_int_ctl) +{ + + SetMode(MC36XX_MODE_STANDBY); + + CfgINT = (((fifo_thr_int_ctl & 0x01) << 6) + | ((fifo_full_int_ctl & 0x01) << 5) + | ((fifo_empty_int_ctl & 0x01) << 4) + | ((acq_int_ctl & 0x01) << 3) + | ((wake_int_ctl & 0x01) << 2) + | MC36XX_INTR_C_IAH_ACTIVE_HIGH//MC36XX_INTR_C_IAH_ACTIVE_LOW// + | MC36XX_INTR_C_IPP_MODE_PUSH_PULL);//MC36XX_INTR_C_IPP_MODE_OPEN_DRAIN);// + writeRegister8(MC36XX_REG_INTR_C, CfgINT); +} - writeRegister8(0x0D, _bRegIO_C); - - delay(50); +//Interrupt handler (clear interrupt flag) +void MC36XX::INTHandler(MC36XX_interrupt_event_t *ptINT_Event) +{ + uint8_t value; - writeRegister8(0x10, 0x01); + value = readRegister8(MC36XX_REG_STATUS_2); + + ptINT_Event->bWAKE = ((value >> 2) & 0x01); + ptINT_Event->bACQ = ((value >> 3) & 0x01); + ptINT_Event->bFIFO_EMPTY = ((value >> 4) & 0x01); + ptINT_Event->bFIFO_FULL = ((value >> 5) & 0x01); + ptINT_Event->bFIFO_THRESHOLD = ((value >> 6) & 0x01); + ptINT_Event->bSWAKE_SNIFF = ((value >> 7) & 0x01); - delay(10); + value &= 0x03; + writeRegister8(MC36XX_REG_STATUS_2, value); } -//Set Sniff Analog Gain -void MC36XX::SetSniffAGAIN(MC36XX_gain_t gain) +//Set CWake Analog Gain +void MC36XX::SetWakeAGAIN(MC36XX_gain_t gain) { - writeRegister8(0x20, 0x00); + writeRegister8(0x20, 0x01); uint8_t value; value = readRegister8(MC36XX_REG_GAIN); value &= 0b00111111; @@ -218,10 +455,10 @@ void MC36XX::SetSniffAGAIN(MC36XX_gain_t gain) writeRegister8(MC36XX_REG_GAIN, value); } -//Set CWake Analog Gain -void MC36XX::SetWakeAGAIN(MC36XX_gain_t gain) +//Set Sniff Analog Gain +void MC36XX::SetSniffAGAIN(MC36XX_gain_t gain) { - writeRegister8(0x20, 0x01); + writeRegister8(0x20, 0x00); uint8_t value; value = readRegister8(MC36XX_REG_GAIN); value &= 0b00111111; @@ -229,135 +466,202 @@ void MC36XX::SetWakeAGAIN(MC36XX_gain_t gain) writeRegister8(MC36XX_REG_GAIN, value); } -//Set the resolution control -void MC36XX::SetResolutionCtrl(MC36XX_resolution_t resolution) +//Set Sniff threshold +void MC36XX::SetSniffThreshold(MC36XX_axis_t axis_cfg, uint8_t sniff_thr) { - uint8_t value; - CfgResolution = resolution; - SetMode(MC36XX_MODE_STANDBY); - value = readRegister8(MC36XX_REG_RANGE_C); - value &= 0b01110000; - value |= resolution; - writeRegister8(MC36XX_REG_RANGE_C, value); + uint8_t value; + uint8_t regSniff_addr; + value = readRegister8(MC36XX_REG_SNIFFTH_C); + + switch(axis_cfg) + { + case MC36XX_AXIS_X: + regSniff_addr = 0x01; //Put X-axis to active + break; + case MC36XX_AXIS_Y: //Put Y-axis to active + regSniff_addr = 0x02; + break; + case MC36XX_AXIS_Z: //Put Z-axis to active + regSniff_addr = 0x03; + break; + default: + break; + } + + writeRegister8(MC36XX_REG_SNIFF_CONF_C, regSniff_addr); + value |= sniff_thr; + writeRegister8(MC36XX_REG_SNIFFTH_C, value); } -//Set the sampling rate -void MC36XX::SetCWakeSampleRate(MC36XX_cwake_sr_t sample_rate) +//Set Sniff detect counts, 1~62 events +void MC36XX::SetSniffDetectCount(MC36XX_axis_t axis_cfg, uint8_t sniff_cnt) { - uint8_t value; - SetMode(MC36XX_MODE_STANDBY); - value = readRegister8(MC36XX_REG_WAKE_C); - value &= 0b00000000; - value |= sample_rate; - writeRegister8(MC36XX_REG_WAKE_C, value); + uint8_t value; + uint8_t sniff_cfg; + uint8_t regSniff_addr; + + sniff_cfg = readRegister8(MC36XX_REG_SNIFF_CONF_C); + + switch(axis_cfg) + { + case MC36XX_AXIS_X: //Select x detection count shadow register + regSniff_addr = 0x05; + break; + case MC36XX_AXIS_Y: //Select y detection count shadow register + regSniff_addr = 0x06; + break; + case MC36XX_AXIS_Z: //Select z detection count shadow register + regSniff_addr = 0x07; + break; + default: + break; + } + + sniff_cfg |= regSniff_addr; + writeRegister8(MC36XX_REG_SNIFF_CONF_C, sniff_cfg); + + value = readRegister8(MC36XX_REG_SNIFFTH_C); + + value |= sniff_cnt; + writeRegister8(MC36XX_REG_SNIFFTH_C, value); + + sniff_cfg |= 0x08; + writeRegister8(MC36XX_REG_SNIFF_CONF_C, sniff_cfg); } -//Get the output sampling rate -MC36XX_cwake_sr_t MC36XX::GetCWakeSampleRate(void) +//Set sensor interrupt mode +void MC36XX::SetSniffAndOrN(MC36XX_andorn_t logicandor) { - /* Read the data format register to preserve bits */ - uint8_t value; - value = readRegister8(MC36XX_REG_WAKE_C); - Serial.println("GetCWakeSampleRate"); - Serial.println(value, HEX); - value &= 0b00001111; - return (MC36XX_cwake_sr_t) (value); + uint8_t value; + + value = readRegister8(MC36XX_REG_SNIFFTH_C); + + switch(logicandor) + { + case MC36XX_ANDORN_OR: //Axis or mode + value &= 0xBF; + break; + case MC36XX_ANDORN_AND: //Axis and mode + value |= 0x40; + break; + default: + break; + } + + writeRegister8(MC36XX_REG_SNIFFTH_C, value); +} + +//Set sensor sniff delta mode +void MC36XX::SetSniffDeltaMode(MC36XX_delta_mode_t deltamode) +{ + uint8_t value; + + value = readRegister8(MC36XX_REG_SNIFFTH_C); + + switch(deltamode) + { + case MC36XX_DELTA_MODE_C2P: //Axis C2P mode + value &= 0x7F; + break; + case MC36XX_DELTA_MODE_C2B: //Axis C2B mode + value |= 0x80; + break; + default: + break; + } + + writeRegister8(MC36XX_REG_SNIFFTH_C, value); + + value = readRegister8(MC36XX_REG_SNIFFTH_C); + Serial.println("SniffModeSet"); + Serial.println(value, HEX); } //Get the range control MC36XX_range_t MC36XX::GetRangeCtrl(void) { - /* Read the data format register to preserve bits */ - uint8_t value; - value = readRegister8(MC36XX_REG_RANGE_C); - Serial.println("GetRangeCtrl"); - Serial.println(value, HEX); - value &= 0x70; - return (MC36XX_range_t) (value >> 4); + // Read the data format register to preserve bits + uint8_t value; + value = readRegister8(MC36XX_REG_RANGE_C); + Serial.println("GetRangeCtrl"); + Serial.println(value, HEX); + value &= 0x70; + return (MC36XX_range_t) (value >> 4); } //Get the range control MC36XX_resolution_t MC36XX::GetResolutionCtrl(void) { - /* Read the data format register to preserve bits */ - uint8_t value; - value = readRegister8(MC36XX_REG_RANGE_C); - Serial.println("GetResolutionCtrl"); - Serial.println(value, HEX); - value &= 0x07; - return (MC36XX_resolution_t) (value); + // Read the data format register to preserve bits + uint8_t value; + value = readRegister8(MC36XX_REG_RANGE_C); + Serial.println("GetResolutionCtrl"); + Serial.println(value, HEX); + value &= 0x07; + return (MC36XX_resolution_t) (value); } -//Initialize the MC36XX sensor and set as the default configuration -bool MC36XX::start(void) +//Get the output sampling rate +MC36XX_cwake_sr_t MC36XX::GetCWakeSampleRate(void) { - -#ifdef MC36XX_CFG_BUS_I2C - Wire.begin(); // Initialize I2C -#else - digitalWrite(chipSelectPin, HIGH); //Set active-low CS low to start the SPI cycle - pinMode(chipSelectPin, OUTPUT); - #if 1 - SPI.begin(); - SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE3)); - #else - SPI.setDataMode (SPI_MODE3); - SPI.setClockDivider(SPI_CLOCK_DIV8); - SPI.begin(); // Initialize SPI - #endif -#endif - - //Init Reset - reset(); - SetMode(MC36XX_MODE_STANDBY); - - //SetWakeAGAIN - SetWakeAGAIN(MC36XX_GAIN_1X); - //SetSniffAGAIN - SetSniffAGAIN(MC36XX_GAIN_1X); - - /* Check I2C connection */ - uint8_t id = readRegister8(MC36XX_REG_PROD); - if (id != 0x71) - { - /* No MC36XX detected ... return false */ - Serial.println("No MC36XX detected!"); - Serial.println(id, HEX); - return false; - } - SetRangeCtrl(MC36XX_RANGE_8G); //Range: 8g - SetResolutionCtrl(MC36XX_RESOLUTION_14BIT); //Resolution: 14bit - SetCWakeSampleRate(MC36XX_CWAKE_SR_DEFAULT_54Hz); //Sampling Rate: 50Hz - SetMode(MC36XX_MODE_CWAKE); //Mode: Active - - delay(50); - - return true; + // Read the data format register to preserve bits + uint8_t value; + value = readRegister8(MC36XX_REG_WAKE_C); + Serial.println("GetCWakeSampleRate"); + Serial.println(value, HEX); + value &= 0b00001111; + return (MC36XX_cwake_sr_t) (value); } -void MC36XX::stop() +//Get the sniff sample rate +MC36XX_sniff_sr_t MC36XX::GetSniffSampleRate(void) { - SetMode(MC36XX_MODE_SLEEP); //Set mode as Sleep + // Read the data format register to preserve bits + uint8_t value; + value = readRegister8(MC36XX_REG_SNIFF_C); + Serial.println("GetSniffSampleRate"); + Serial.println(value, HEX); + value &= 0b00001111; + return (MC36XX_sniff_sr_t) (value); } -//Read the raw counts and SI units mearsurement data -MC36XX_acc_t MC36XX::readRawAccel(void) +//Is FIFO empty +bool MC36XX::IsFIFOEmpty(void) { - float faRange[5] = { 19.614f, 39.228f, 78.456f, 156.912f, 117.684f}; //{2g, 4g, 8g, 16g, 12g} - float faResolution[6] = { 32.0f, 64.0f, 128.0f, 512.0f, 2048.0f, 8192.0f}; //{6bit, 7bit, 8bit, 10bit, 12bit, 14bit} - - byte rawData[6]; - readRegisters(MC36XX_REG_XOUT_LSB, rawData, 6); // Read the six raw data registers into data array - x = (short)((((unsigned short)rawData[1]) << 8) | rawData[0]); - y = (short)((((unsigned short)rawData[3]) << 8) | rawData[2]); - z = (short)((((unsigned short)rawData[5]) << 8) | rawData[4]); - - AccRaw.XAxis = (short) (x); - AccRaw.YAxis = (short) (y); - AccRaw.ZAxis = (short) (z); - AccRaw.XAxis_g = (float) (x) / faResolution[CfgResolution]*faRange[CfgRange]; - AccRaw.YAxis_g = (float) (y) / faResolution[CfgResolution]*faRange[CfgRange]; - AccRaw.ZAxis_g = (float) (z) / faResolution[CfgResolution]*faRange[CfgRange]; + // Read the data format register to preserve bits + uint8_t value; + value = readRegister8(MC36XX_REG_STATUS_1); + value &= 0x10; + Serial.println("FIFO_Status"); + Serial.println(value, HEX); + + if (value^0x10) + return false; //Not empty + else + return true; //Is empty +} - return AccRaw; +//Read the raw counts and SI units measurement data +MC36XX_acc_t MC36XX::readRawAccel(void) +{ + //{2g, 4g, 8g, 16g, 12g} + float faRange[5] = { 19.614f, 39.228f, 78.456f, 156.912f, 117.684f}; + //{6bit, 7bit, 8bit, 10bit, 12bit, 14bit} + float faResolution[6] = { 32.0f, 64.0f, 128.0f, 512.0f, 2048.0f, 8192.0f}; + + byte rawData[6]; + // Read the six raw data registers into data array + readRegisters(MC36XX_REG_XOUT_LSB, rawData, 6); + x = (short)((((unsigned short)rawData[1]) << 8) | rawData[0]); + y = (short)((((unsigned short)rawData[3]) << 8) | rawData[2]); + z = (short)((((unsigned short)rawData[5]) << 8) | rawData[4]); + + AccRaw.XAxis = (short) (x); + AccRaw.YAxis = (short) (y); + AccRaw.ZAxis = (short) (z); + AccRaw.XAxis_g = (float) (x)/faResolution[CfgResolution]*faRange[CfgRange]; + AccRaw.YAxis_g = (float) (y)/faResolution[CfgResolution]*faRange[CfgRange]; + AccRaw.ZAxis_g = (float) (z)/faResolution[CfgResolution]*faRange[CfgRange]; + + return AccRaw; } diff --git a/MC36XX.h b/MC36XX.h index 29213ce..6ed6d0d 100644 --- a/MC36XX.h +++ b/MC36XX.h @@ -1,14 +1,45 @@ +/****************************************************************************** + * + * Copyright (c) 2018 mCube, Inc. All rights reserved. + * + * This source is subject to the mCube Software License. + * This software is protected by Copyright and the information and source code + * contained herein is confidential. The software including the source code + * may not be copied and the information contained herein may not be used or + * disclosed except with the written permission of mCube Inc. + * + * All other rights reserved. + *****************************************************************************/ + +/** + * @file MC36XX.h + * @author mCube + * @date 10 May 2018 + * @brief Driver interface header file for accelerometer mc36xx series. + * @see http://www.mcubemems.com + */ + #ifndef MC36XX_h #define MC36XX_h -//#define MC36XX_CFG_BUS_I2C // !!! DO NOT use both I2C and SPI simutaneously +/****************************************************************************** + *** INFORMATION + *****************************************************************************/ +#define M_DRV_MC36XX_VERSION "2.0.0" + +/****************************************************************************** + *** CONFIGURATION + *****************************************************************************/ + +// !!! DO NOT use I2C and SPI simultaneously. +//#define MC36XX_CFG_BUS_I2C #define MC36XX_CFG_BUS_SPI -/* -SS : pin 2, Active-low CSĦXchip select -MOSI: pin 11, MOSIĦXmaster out slave in -MISO: pin 12, MISOĦXmaster in slave out -SCK : pin 13, SCK - SPI clock -*/ + +//SPI pin definition +//SS : pin 10, Active-low CSĦXchip select +//MOSI: pin 11, MOSIĦXmaster out slave in +//MISO: pin 12, MISOĦXmaster in slave out +//SCK : pin 13, SCK - SPI clock #if (!defined (MC36XX_CFG_BUS_SPI) && !defined (MC36XX_CFG_BUS_I2C)) #error "MUST use one bus to access register!" @@ -19,19 +50,20 @@ SCK : pin 13, SCK - SPI clock #endif #ifdef MC36XX_CFG_BUS_I2C - #include + #include #else - #include - // pins used for the connection with the sensor - // other information you can refer to the Arduino SPI library - const int chipSelectPin = 2; -#endif + #include + #define SPI_HS + // pins used for the connection with the sensor + // other information you can refer to the Arduino SPI library + const int chipSelectPin = 10; +#endif #include "Arduino.h" -/******************************************************************************* +/****************************************************************************** *** CONSTANT / DEFINE - *******************************************************************************/ + *****************************************************************************/ #define MC36XX_RETCODE_SUCCESS (0) #define MC36XX_RETCODE_ERROR_BUS (-1) #define MC36XX_RETCODE_ERROR_NULL_POINTER (-2) @@ -41,27 +73,21 @@ SCK : pin 13, SCK - SPI clock #define MC36XX_RETCODE_ERROR_IDENTIFICATION (-6) #define MC36XX_RETCODE_ERROR_NO_DATA (-7) #define MC36XX_RETCODE_ERROR_WRONG_ARGUMENT (-8) -#define MC36XX_FIFO_DEPTH 32 -#define MC36XX_REG_MAP_SIZE 64 - +#define MC36XX_FIFO_DEPTH 32 +#define MC36XX_REG_MAP_SIZE 64 - -/******************************************************************************* +/****************************************************************************** *** CONSTANT / DEFINE - *******************************************************************************/ - -//============================================= + *****************************************************************************/ #define MC36XX_INTR_C_IPP_MODE_OPEN_DRAIN (0x00) #define MC36XX_INTR_C_IPP_MODE_PUSH_PULL (0x01) -#define MC36XX_INTR_C_IAH_ACTIVE_LOW (0x00) -#define MC36XX_INTR_C_IAH_ACTIVE_HIGH (0x02) - +#define MC36XX_INTR_C_IAH_ACTIVE_LOW (0x00) +#define MC36XX_INTR_C_IAH_ACTIVE_HIGH (0x02) -/******************************************************************************* +/****************************************************************************** *** Register Map - *******************************************************************************/ -//============================================= + *****************************************************************************/ #define MC36XX_REG_EXT_STAT_1 (0x00) #define MC36XX_REG_EXT_STAT_2 (0x01) #define MC36XX_REG_XOUT_LSB (0x02) @@ -72,6 +98,8 @@ SCK : pin 13, SCK - SPI clock #define MC36XX_REG_ZOUT_MSB (0x07) #define MC36XX_REG_STATUS_1 (0x08) #define MC36XX_REG_STATUS_2 (0x09) +#define MC36XX_REG_FEATURE_CTL (0x0D) +#define MC36XX_REG_PWR_CONTROL (0X0F) #define MC36XX_REG_MODE_C (0x10) #define MC36XX_REG_WAKE_C (0x11) #define MC36XX_REG_SNIFF_C (0x12) @@ -81,6 +109,7 @@ SCK : pin 13, SCK - SPI clock #define MC36XX_REG_FIFO_C (0x16) #define MC36XX_REG_INTR_C (0x17) #define MC36XX_REG_PROD (0x18) +#define MC36XX_REG_PMCR (0x1C) #define MC36XX_REG_DMX (0x20) #define MC36XX_REG_DMY (0x21) #define MC36XX_REG_GAIN (0x21) @@ -101,13 +130,13 @@ SCK : pin 13, SCK - SPI clock #define MC36XX_REG_LOT_dAOFSZ (0x3E) #define MC36XX_REG_WAF_LOT (0x3F) -#define MC36XX_NULL_ADDR (0) +#define MC36XX_NULL_ADDR (0) struct MC36XX_acc_t { short XAxis; short YAxis; - short ZAxis; + short ZAxis; float XAxis_g; float YAxis_g; float ZAxis_g; @@ -118,23 +147,23 @@ typedef enum MC36XX_GAIN_DEFAULT = 0b00, MC36XX_GAIN_4X = 0b01, MC36XX_GAIN_1X = 0b10, - MC36XX_GAIN_NOT_USED = 0b11, + MC36XX_GAIN_NOT_USED = 0b11, } MC36XX_gain_t; typedef enum { - MC36XX_MODE_SLEEP = 0b000, + MC36XX_MODE_SLEEP = 0b000, MC36XX_MODE_STANDBY = 0b001, MC36XX_MODE_SNIFF = 0b010, - MC36XX_MODE_CWAKE = 0b101, - MC36XX_MODE_TRIG = 0b111, + MC36XX_MODE_CWAKE = 0b101, + MC36XX_MODE_TRIG = 0b111, } MC36XX_mode_t; typedef enum { MC36XX_RANGE_2G = 0b000, MC36XX_RANGE_4G = 0b001, - MC36XX_RANGE_8G = 0b010, + MC36XX_RANGE_8G = 0b010, MC36XX_RANGE_16G = 0b011, MC36XX_RANGE_12G = 0b100, MC36XX_RANGE_END, @@ -142,11 +171,11 @@ typedef enum typedef enum { - MC36XX_RESOLUTION_6BIT = 0b000, - MC36XX_RESOLUTION_7BIT = 0b001, - MC36XX_RESOLUTION_8BIT = 0b010, - MC36XX_RESOLUTION_10BIT = 0b011, - MC36XX_RESOLUTION_12BIT = 0b100, + MC36XX_RESOLUTION_6BIT = 0b000, + MC36XX_RESOLUTION_7BIT = 0b001, + MC36XX_RESOLUTION_8BIT = 0b010, + MC36XX_RESOLUTION_10BIT = 0b011, + MC36XX_RESOLUTION_12BIT = 0b100, MC36XX_RESOLUTION_14BIT = 0b101, //(Do not select if FIFO enabled) MC36XX_RESOLUTION_END, } MC36XX_resolution_t; @@ -183,10 +212,10 @@ typedef enum typedef enum { - MC36XX_FIFO_CONTROL_DISABLE = 0, - MC36XX_FIFO_CONTROL_ENABLE, - MC36XX_FIFO_CONTROL_END, -} MC36XX_fifo_control_t; + MC36XX_FIFO_CTL_DISABLE = 0, + MC36XX_FIFO_CTL_ENABLE, + MC36XX_FIFO_CTL_END, +} MC36XX_fifo_ctl_t; typedef enum { @@ -195,47 +224,110 @@ typedef enum MC36XX_FIFO_MODE_END, } MC36XX_fifo_mode_t; +typedef enum +{ + MC36XX_ANDORN_OR = 0, + MC36XX_ANDORN_AND, + MC36XX_ANDORN_END, +} MC36XX_andorn_t; + +typedef enum +{ + //Compare to previous + MC36XX_DELTA_MODE_C2P = 0, + //Compare to baseline + MC36XX_DELTA_MODE_C2B, + MC36XX_DELTA_MODE_END, +} MC36XX_delta_mode_t; + typedef struct { - unsigned char bWAKE; // Sensor wakes from sniff mode. - unsigned char bACQ; // New sample is ready and acquired. - unsigned char bFIFO_EMPTY; // FIFO is empty. - unsigned char bFIFO_FULL; // FIFO is full. - unsigned char bFIFO_THRESHOLD; // FIFO sample count is equal to or greater than the threshold count. + unsigned char bWAKE; + unsigned char bACQ; + unsigned char bFIFO_EMPTY; + unsigned char bFIFO_FULL; + unsigned char bFIFO_THRESHOLD; unsigned char bRESV; + unsigned char bSWAKE_SNIFF; unsigned char baPadding[2]; -} MC36XX_InterruptEvent; +} MC36XX_interrupt_event_t; + +typedef enum +{ + MC36XX_AXIS_X = 0, + MC36XX_AXIS_Y, + MC36XX_AXIS_Z, + MC36XX_AXIS_END, +} MC36XX_axis_t; +typedef struct +{ + // Sensor wakes from sniff mode. + unsigned char bWAKE; + // New sample is ready and acquired. + unsigned char bACQ; + // FIFO is empty. + unsigned char bFIFO_EMPTY; + // FIFO is full. + unsigned char bFIFO_FULL; + // FIFO sample count is equal to or greater than the threshold count. + unsigned char bFIFO_THRESHOLD; + // Reserved + unsigned char bRESV; + unsigned char baPadding[2]; +} MC36XX_InterruptEvent; +/* general accel methods */ class MC36XX{ public: + // Setup and begin measurements + bool start(); + // Start measurement + void wake(); + // End measurement + void stop(); + // Sensor reset + void reset(); + // Sensor sniff + void sniff(); + void sniffreset(); + void SetMode(MC36XX_mode_t mode); + void SetRangeCtrl(MC36XX_range_t range); + void SetResolutionCtrl(MC36XX_resolution_t resolution); + void SetCWakeSampleRate(MC36XX_cwake_sr_t sample_rate); + void SetSniffSampleRate(MC36XX_sniff_sr_t sniff_sr); + void SetFIFOCtrl(MC36XX_fifo_ctl_t fifo_ctl, + MC36XX_fifo_mode_t fifo_mode, + uint8_t fifo_thr); + void SetINTCtrl(uint8_t fifo_thr_int_ctl, + uint8_t fifo_full_int_ctl, + uint8_t fifo_empty_int_ctl, + uint8_t acq_int_ctl, + uint8_t wake_int_ctl); + void INTHandler(MC36XX_interrupt_event_t *ptINT_Event); + void SetWakeAGAIN(MC36XX_gain_t gain); + void SetSniffAGAIN(MC36XX_gain_t gain); + void SetSniffThreshold(MC36XX_axis_t axis_cfg, uint8_t sniff_thr); + void SetSniffDetectCount(MC36XX_axis_t axis_cfg, uint8_t sniff_cnt); + void SetSniffAndOrN(MC36XX_andorn_t logicandor); + void SetSniffDeltaMode(MC36XX_delta_mode_t deltamode); + MC36XX_range_t GetRangeCtrl(void); + MC36XX_resolution_t GetResolutionCtrl(void); + MC36XX_cwake_sr_t GetCWakeSampleRate(void); + MC36XX_sniff_sr_t GetSniffSampleRate(void); + bool IsFIFOEmpty(void); + MC36XX_acc_t readRawAccel(void); - /* general accel methods */ - bool start(); // begin measurements - void stop(); // end measurments - void reset(); - void SetMode(MC36XX_mode_t); - void SetRangeCtrl(MC36XX_range_t); - void SetResolutionCtrl(MC36XX_resolution_t); - void SetCWakeSampleRate(MC36XX_cwake_sr_t); - void SetSniffAGAIN(MC36XX_gain_t); - void SetWakeAGAIN(MC36XX_gain_t); - MC36XX_sniff_sr_t GetSniffSampleRate(MC36XX_sniff_sr_t); - MC36XX_resolution_t GetResolutionCtrl(void); - MC36XX_range_t GetRangeCtrl(void); - MC36XX_cwake_sr_t GetCWakeSampleRate(void); - MC36XX_acc_t readRawAccel(void); - - private: - short x, y, z; - MC36XX_acc_t AccRaw; // Raw Accelerometer data + short x, y, z; + // Raw Accelerometer data + MC36XX_acc_t AccRaw; + bool readRegisterBit(uint8_t reg, uint8_t pos); uint8_t readRegister8(uint8_t reg); - int16_t readRegister16(uint8_t reg); - void readRegisters(uint8_t reg, byte *buffer, uint8_t len); - bool readRegisterBit(uint8_t reg, uint8_t pos); - void writeRegisterBit(uint8_t reg, uint8_t pos, bool state); + int16_t readRegister16(uint8_t reg); + void readRegisters(uint8_t reg, byte *buffer, uint8_t len); + void writeRegisterBit(uint8_t reg, uint8_t pos, bool state); + void writeRegister8(uint8_t reg, uint8_t value); void writeRegister16(uint8_t reg, int16_t value); - void writeRegister8(uint8_t reg, uint8_t value); }; #endif diff --git a/MC36XX_demo.ino b/MC36XX_demo.ino index 3f6ad15..f266c33 100644 --- a/MC36XX_demo.ino +++ b/MC36XX_demo.ino @@ -1,79 +1,288 @@ +/***************************************************************************** + * + * Copyright (c) 2018 mCube, Inc. All rights reserved. + * + * This source is subject to the mCube Software License. + * This software is protected by Copyright and the information and source code + * contained herein is confidential. The software including the source code + * may not be copied and the information contained herein may not be used or + * disclosed except with the written permission of mCube Inc. + * + * All other rights reserved. + *****************************************************************************/ + +/** + * @file MC36XX_demo.ino + * @author mCube + * @date 10 May 2018 + * @brief Arduino example code for accelerometer mc36xx series. + * @see http://www.mcubemems.com + */ #include "MC36XX.h" +#define INTERRUPT_PIN 8 +#define FIFO_SIZE 3 + +//DO NOT ENABLE (ENABLE_FIFO_WAKEUP) AND (ENABLE_SNIFF_SHAKE_WAKEUP) AT THE SAME TIME +#define ENABLE_FIFO_WAKEUP 0 //Sensor will wake up automatically when FIFO is full +#define ENABLE_SNIFF_SHAKE_WAKEUP 1 //Sensor will wake up until external force over the threshold setting + +MC36XX_interrupt_event_t evt_mc36xx = {0}; MC36XX MC36XX_acc = MC36XX(); void setup() { - Serial.begin(115200); + pinMode(INTERRUPT_PIN, INPUT); + + Serial.begin(115200); Serial.println("mCube Accelerometer MC36XX:"); MC36XX_acc.start(); - checkRange(); - checkResolution(); - checkSamplingRate(); - Serial.println(); + checkRange(); + checkResolution(); + checkSamplingRate(); + checkSniffSamplingRate(); + Serial.println(); + + //Test read + MC36XX_acc_t rawAccel = MC36XX_acc.readRawAccel(); + delay(10); + Serial.print("X:\t"); Serial.print(rawAccel.XAxis); Serial.print("\t"); + Serial.print("Y:\t"); Serial.print(rawAccel.YAxis); Serial.print("\t"); + Serial.print("Z:\t"); Serial.print(rawAccel.ZAxis); Serial.print("\t"); + Serial.println("counts"); + + // Display the results (acceleration is measured in m/s^2) + Serial.print("X: \t"); Serial.print(rawAccel.XAxis_g); Serial.print("\t"); + Serial.print("Y: \t"); Serial.print(rawAccel.YAxis_g); Serial.print("\t"); + Serial.print("Z: \t"); Serial.print(rawAccel.ZAxis_g); Serial.print("\t"); + Serial.println("m/s^2"); + + Serial.println("---------------------------------------------------------"); + +#if ENABLE_SNIFF_SHAKE_WAKEUP + sensorsniff(); +#elif ENABLE_FIFO_WAKEUP + sensorFIFO(); +#endif + +} + +void sensorsniff() +{ + //Sensor sniff + MC36XX_acc.stop(); + MC36XX_acc.SetSniffThreshold(MC36XX_AXIS_X,5); + MC36XX_acc.SetSniffThreshold(MC36XX_AXIS_Y,5); + MC36XX_acc.SetSniffThreshold(MC36XX_AXIS_Z,5); + MC36XX_acc.SetSniffDetectCount(MC36XX_AXIS_X,3); + MC36XX_acc.SetSniffDetectCount(MC36XX_AXIS_Y,3); + MC36XX_acc.SetSniffDetectCount(MC36XX_AXIS_Z,3); + MC36XX_acc.SetSniffAndOrN(MC36XX_ANDORN_OR); + MC36XX_acc.SetSniffDeltaMode(MC36XX_DELTA_MODE_C2P); + MC36XX_acc.SetINTCtrl(0,0,0,0,1); //Enable wake-up INT + MC36XX_acc.sniff(); + Serial.println("Sensor sniff."); +} + +void sensorFIFO() +{ + //Enable FIFO and interrupt + MC36XX_acc.stop(); + MC36XX_acc.SetCWakeSampleRate(MC36XX_CWAKE_SR_14Hz); + MC36XX_acc.SetResolutionCtrl(MC36XX_RESOLUTION_12BIT); //FIFO mode could only support 12 bit resolution + MC36XX_acc.SetFIFOCtrl(MC36XX_FIFO_CTL_ENABLE, MC36XX_FIFO_MODE_WATERMARK, FIFO_SIZE); + MC36XX_acc.SetINTCtrl(1,0,0,0,0); //Enable FIFO threshold interrupt + MC36XX_acc.wake(); + + Serial.println("Sensor FIFO enable."); } void checkRange() { - switch(MC36XX_acc.GetRangeCtrl()) - { - case MC36XX_RANGE_16G: Serial.println("Range: +/- 16 g"); break; - case MC36XX_RANGE_12G: Serial.println("Range: +/- 12 g"); break; - case MC36XX_RANGE_8G: Serial.println("Range: +/- 8 g"); break; - case MC36XX_RANGE_4G: Serial.println("Range: +/- 4 g"); break; - case MC36XX_RANGE_2G: Serial.println("Range: +/- 2 g"); break; - default: Serial.println("Range: +/- 8 g"); break; - } + switch(MC36XX_acc.GetRangeCtrl()) + { + case MC36XX_RANGE_16G: + Serial.println("Range: +/- 16 g"); + break; + case MC36XX_RANGE_12G: + Serial.println("Range: +/- 12 g"); + break; + case MC36XX_RANGE_8G: + Serial.println("Range: +/- 8 g"); + break; + case MC36XX_RANGE_4G: + Serial.println("Range: +/- 4 g"); + break; + case MC36XX_RANGE_2G: + Serial.println("Range: +/- 2 g"); + break; + default: + Serial.println("Range: +/- 8 g"); + break; + } } void checkResolution() { - switch(MC36XX_acc.GetResolutionCtrl()) - { - case MC36XX_RESOLUTION_6BIT: Serial.println("Resolution: 6bit"); break; - case MC36XX_RESOLUTION_7BIT: Serial.println("Resolution: 7bit"); break; - case MC36XX_RESOLUTION_8BIT: Serial.println("Resolution: 8bit"); break; - case MC36XX_RESOLUTION_10BIT: Serial.println("Resolution: 10bit"); break; - case MC36XX_RESOLUTION_14BIT: Serial.println("Resolution: 14bit"); break; - case MC36XX_RESOLUTION_12BIT: Serial.println("Resolution: 12bit"); break; - default: Serial.println("Resolution: 14bit"); break; - } + switch(MC36XX_acc.GetResolutionCtrl()) + { + case MC36XX_RESOLUTION_6BIT: + Serial.println("Resolution: 6bit"); + break; + case MC36XX_RESOLUTION_7BIT: + Serial.println("Resolution: 7bit"); + break; + case MC36XX_RESOLUTION_8BIT: + Serial.println("Resolution: 8bit"); + break; + case MC36XX_RESOLUTION_10BIT: + Serial.println("Resolution: 10bit"); + break; + case MC36XX_RESOLUTION_14BIT: + Serial.println("Resolution: 14bit"); + break; + case MC36XX_RESOLUTION_12BIT: + Serial.println("Resolution: 12bit"); + break; + default: + Serial.println("Resolution: 14bit"); + break; + } } void checkSamplingRate() { - Serial.println("Low Power Mode"); - switch(MC36XX_acc.GetCWakeSampleRate()) - { - case MC36XX_CWAKE_SR_DEFAULT_54Hz: Serial.println("Output Sampling Rate: 54 Hz"); break; - case MC36XX_CWAKE_SR_14Hz: Serial.println("Output Sampling Rate: 14 Hz"); break; - case MC36XX_CWAKE_SR_28Hz: Serial.println("Output Sampling Rate: 28 Hz"); break; - case MC36XX_CWAKE_SR_54Hz: Serial.println("Output Sampling Rate: 54 Hz"); break; - case MC36XX_CWAKE_SR_105Hz: Serial.println("Output Sampling Rate: 105 Hz"); break; - case MC36XX_CWAKE_SR_210Hz: Serial.println("Output Sampling Rate: 210 Hz"); break; - case MC36XX_CWAKE_SR_400Hz: Serial.println("Output Sampling Rate: 400 Hz"); break; - case MC36XX_CWAKE_SR_600Hz: Serial.println("Output Sampling Rate: 600 Hz"); break; - default: Serial.println("Output Sampling Rate: 54 Hz"); break; - } + Serial.println("Low Power Mode SR"); + switch(MC36XX_acc.GetCWakeSampleRate()) + { + case MC36XX_CWAKE_SR_DEFAULT_54Hz: + Serial.println("Output Sampling Rate: 54 Hz"); + break; + case MC36XX_CWAKE_SR_14Hz: + Serial.println("Output Sampling Rate: 14 Hz"); + break; + case MC36XX_CWAKE_SR_28Hz: + Serial.println("Output Sampling Rate: 28 Hz"); + break; + case MC36XX_CWAKE_SR_54Hz: + Serial.println("Output Sampling Rate: 54 Hz"); + break; + case MC36XX_CWAKE_SR_105Hz: + Serial.println("Output Sampling Rate: 105 Hz"); + break; + case MC36XX_CWAKE_SR_210Hz: + Serial.println("Output Sampling Rate: 210 Hz"); + break; + case MC36XX_CWAKE_SR_400Hz: + Serial.println("Output Sampling Rate: 400 Hz"); + break; + case MC36XX_CWAKE_SR_600Hz: + Serial.println("Output Sampling Rate: 600 Hz"); + break; + default: + Serial.println("Output Sampling Rate: 54 Hz"); + break; + } } -void loop() +void checkSniffSamplingRate() { - // Read the raw sensor data count - MC36XX_acc_t rawAccel = MC36XX_acc.readRawAccel(); - delay(10); - Serial.print("X:\t"); Serial.print(rawAccel.XAxis); Serial.print("\t"); - Serial.print("Y:\t"); Serial.print(rawAccel.YAxis); Serial.print("\t"); - Serial.print("Z:\t"); Serial.print(rawAccel.ZAxis); Serial.print("\t"); - Serial.println("counts"); - - // Display the results (acceleration is measured in m/s^2) - Serial.print("X: \t"); Serial.print(rawAccel.XAxis_g); Serial.print("\t"); - Serial.print("Y: \t"); Serial.print(rawAccel.YAxis_g); Serial.print("\t"); - Serial.print("Z: \t"); Serial.print(rawAccel.ZAxis_g); Serial.print("\t"); - Serial.println("m/s^2"); - - Serial.println("--------------------------------------------------------------"); - delay(1000); + Serial.println("Sniff Mode SR"); + switch(MC36XX_acc.GetSniffSampleRate()) + { + case MC36XX_SNIFF_SR_DEFAULT_7Hz: + Serial.println("Sniff Sampling Rate: 7 Hz"); + break; + case MC36XX_SNIFF_SR_0p4Hz: + Serial.println("Sniff Sampling Rate: 0.4 Hz"); + break; + case MC36XX_SNIFF_SR_0p8Hz: + Serial.println("Sniff Sampling Rate: 0.8 Hz"); + break; + case MC36XX_SNIFF_SR_1p5Hz: + Serial.println("Sniff Sampling Rate: 1.5 Hz"); + break; + case MC36XX_SNIFF_SR_7Hz: + Serial.println("Sniff Sampling Rate: 7 Hz"); + break; + case MC36XX_SNIFF_SR_14Hz: + Serial.println("Sniff Sampling Rate: 14 Hz"); + break; + case MC36XX_SNIFF_SR_28Hz: + Serial.println("Sniff Sampling Rate: 28 Hz"); + break; + case MC36XX_SNIFF_SR_54Hz: + Serial.println("Sniff Sampling Rate: 54 Hz"); + break; + case MC36XX_SNIFF_SR_105Hz: + Serial.println("Sniff Sampling Rate: 105 Hz"); + break; + case MC36XX_SNIFF_SR_210Hz: + Serial.println("Sniff Sampling Rate: 210 Hz"); + break; + case MC36XX_SNIFF_SR_400Hz: + Serial.println("Sniff Sampling Rate: 400 Hz"); + break; + case MC36XX_SNIFF_SR_600Hz: + Serial.println("Sniff Sampling Rate: 600 Hz"); + break; + default: + Serial.println("Sniff Sampling Rate: 7 Hz"); + break; + } } + +void loop() +{ +#if ENABLE_SNIFF_SHAKE_WAKEUP || ENABLE_FIFO_WAKEUP + if (digitalRead(INTERRUPT_PIN) == HIGH) + { + Serial.println("Get interrupt."); + delay(100); +#if ENABLE_FIFO_WAKEUP + while(!(MC36XX_acc.IsFIFOEmpty())) +#endif +#endif + { + // Read the raw sensor data count + MC36XX_acc_t rawAccel = MC36XX_acc.readRawAccel(); + + Serial.print("X:\t"); Serial.print(rawAccel.XAxis); Serial.print("\t"); + Serial.print("Y:\t"); Serial.print(rawAccel.YAxis); Serial.print("\t"); + Serial.print("Z:\t"); Serial.print(rawAccel.ZAxis); Serial.print("\t"); + Serial.println("counts"); + + // Display the results (acceleration is measured in m/s^2) + Serial.print("X: \t"); Serial.print(rawAccel.XAxis_g); Serial.print("\t"); + Serial.print("Y: \t"); Serial.print(rawAccel.YAxis_g); Serial.print("\t"); + Serial.print("Z: \t"); Serial.print(rawAccel.ZAxis_g); Serial.print("\t"); + Serial.println("m/s^2"); + + Serial.println("---------------------------------------------------------"); + + rawAccel = MC36XX_acc.readRawAccel(); + + Serial.print("X:\t"); Serial.print(rawAccel.XAxis); Serial.print("\t"); + Serial.print("Y:\t"); Serial.print(rawAccel.YAxis); Serial.print("\t"); + Serial.print("Z:\t"); Serial.print(rawAccel.ZAxis); Serial.print("\t"); + Serial.println("counts"); + + // Display the results (acceleration is measured in m/s^2) + Serial.print("X: \t"); Serial.print(rawAccel.XAxis_g); Serial.print("\t"); + Serial.print("Y: \t"); Serial.print(rawAccel.YAxis_g); Serial.print("\t"); + Serial.print("Z: \t"); Serial.print(rawAccel.ZAxis_g); Serial.print("\t"); + Serial.println("m/s^2"); + + Serial.println("---------------------------------------------------------"); + } +#if ENABLE_SNIFF_SHAKE_WAKEUP || ENABLE_FIFO_WAKEUP + MC36XX_acc.INTHandler(&evt_mc36xx); +#if ENABLE_SNIFF_SHAKE_WAKEUP + sensorsniff(); +#endif + } +#else + delay(1000); +#endif +}