diff --git a/examples/example1_basic_readings/example1_basic_readings.ino b/examples/example1_basic_readings/example1_basic_readings.ino index 7f02342..e8ccf29 100644 --- a/examples/example1_basic_readings/example1_basic_readings.ino +++ b/examples/example1_basic_readings/example1_basic_readings.ino @@ -2,105 +2,101 @@ example1-BasicReadings This example shows the basic settings and functions for retrieving accelerometer - data. Other possible Range settings, depending on your accelerometer KX132 or KX134, are - the following: - - SFE_KX132_RANGE2G - SFE_KX132_RANGE4G - SFE_KX132_RANGE8G - SFE_KX132_RANGE16G - - SFE_KX134_RANGE8G - SFE_KX134_RANGE16G - SFE_KX134_RANGE32G - SFE_KX134_RANGE64G + data. Other possible Range settings, depending on your accelerometer KX132 or KX134, are + the following: + + SFE_KX132_RANGE2G + SFE_KX132_RANGE4G + SFE_KX132_RANGE8G + SFE_KX132_RANGE16G + + SFE_KX134_RANGE8G + SFE_KX134_RANGE16G + SFE_KX134_RANGE32G + SFE_KX134_RANGE64G Written by Elias Santistevan @ SparkFun Electronics, October 2022 - Products: + Products: - SparkFun Triple Axis Accelerometer Breakout - KX132: - https://www.sparkfun.com/products/17871 + SparkFun Triple Axis Accelerometer Breakout - KX132: + https://www.sparkfun.com/products/17871 - SparkFun Triple Axis Accelerometer Breakout - KX134: - https://www.sparkfun.com/products/17589 + SparkFun Triple Axis Accelerometer Breakout - KX134: + https://www.sparkfun.com/products/17589 Repository: - https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library + https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library - SparkFun code, firmware, and software is released under the MIT - License (http://opensource.org/licenses/MIT). + SparkFun code, firmware, and software is released under the MIT + License (http://opensource.org/licenses/MIT). */ #include -#include "SparkFun_KX13X.h" +#include // Click here to get the library: http://librarymanager/All#SparkFun_KX13X -SparkFun_KX132 kxAccel; -//SparkFun_KX134 kxAccel; // For the KX134, uncomment this and comment line above +SparkFun_KX132 kxAccel; +// SparkFun_KX134 kxAccel; // For the KX134, uncomment this and comment line above -outputData myData; // Struct for the accelerometer's data +outputData myData; // Struct for the accelerometer's data -void setup() +void setup() { - - Wire.begin(); - Serial.begin(115200); + Wire.begin(); + + Serial.begin(115200); Serial.println("Welcome."); - // Wait for the Serial monitor to be opened. - while(!Serial) + // Wait for the Serial monitor to be opened. + while (!Serial) delay(50); - - if( !kxAccel.begin() ) - { + if (!kxAccel.begin()) + { Serial.println("Could not communicate with the the KX13X. Freezing."); - while(1); - } + while (1) + ; + } - Serial.println("Ready."); + Serial.println("Ready."); - if( kxAccel.softwareReset() ) - Serial.println("Reset."); + if (kxAccel.softwareReset()) + Serial.println("Reset."); - //Give some time for the accelerometer to reset. - //It needs two, but give it five for good measure. - delay(5); - - // Many settings for KX13X can only be - // applied when the accelerometer is powered down. - // However there are many that can be changed "on-the-fly" - // check datasheet for more info, or the comments in the - // "...regs.h" file which specify which can be changed when. - kxAccel.enableAccel(false); - - kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range - //kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 - - kxAccel.enableDataEngine(); // Enables the bit that indicates data is ready. - // kxAccel.setOutputDataRate(); // Default is 50Hz - kxAccel.enableAccel(); + // Give some time for the accelerometer to reset. + // It needs two, but give it five for good measure. + delay(5); + // Many settings for KX13X can only be + // applied when the accelerometer is powered down. + // However there are many that can be changed "on-the-fly" + // check datasheet for more info, or the comments in the + // "...regs.h" file which specify which can be changed when. + kxAccel.enableAccel(false); + kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range + // kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 + kxAccel.enableDataEngine(); // Enables the bit that indicates data is ready. + // kxAccel.setOutputDataRate(); // Default is 50Hz + kxAccel.enableAccel(); } -void loop() +void loop() { - // Check if data is ready. - if( kxAccel.dataReady() ) - { - kxAccel.getAccelData(&myData); - Serial.print("X: "); - Serial.print(myData.xData, 4); - Serial.print(" Y: "); - Serial.print(myData.yData, 4); - Serial.print(" Z: "); - Serial.print(myData.zData, 4); - Serial.println(); - } + // Check if data is ready. + if (kxAccel.dataReady()) + { + kxAccel.getAccelData(&myData); + Serial.print("X: "); + Serial.print(myData.xData, 4); + Serial.print(" Y: "); + Serial.print(myData.yData, 4); + Serial.print(" Z: "); + Serial.print(myData.zData, 4); + Serial.println(); + } delay(20); // Delay should be 1/ODR (Output Data Rate), default is 1/50ODR - } diff --git a/examples/example2_interrupts/example2_interrupts.ino b/examples/example2_interrupts/example2_interrupts.ino index 982e847..c9a659a 100644 --- a/examples/example2_interrupts/example2_interrupts.ino +++ b/examples/example2_interrupts/example2_interrupts.ino @@ -5,98 +5,96 @@ Written by Elias Santistevan @ SparkFun Electronics, October 2022 - Products: + Products: - SparkFun Triple Axis Accelerometer Breakout - KX132: - https://www.sparkfun.com/products/17871 + SparkFun Triple Axis Accelerometer Breakout - KX132: + https://www.sparkfun.com/products/17871 - SparkFun Triple Axis Accelerometer Breakout - KX134: - https://www.sparkfun.com/products/17589 + SparkFun Triple Axis Accelerometer Breakout - KX134: + https://www.sparkfun.com/products/17589 Repository: - https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library + https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library - SparkFun code, firmware, and software is released under the MIT - License (http://opensource.org/licenses/MIT). + SparkFun code, firmware, and software is released under the MIT + License (http://opensource.org/licenses/MIT). */ #include #include -#include "SparkFun_KX13X.h" +#include // Click here to get the library: http://librarymanager/All#SparkFun_KX13X -SparkFun_KX132 kxAccel; +SparkFun_KX132 kxAccel; // SparkFun_KX134 kxAccel; // For the KX134, uncomment this and comment line above outputData myData; // Struct for the accelerometer's data byte dataReadyPin = 2; // Change to fit your project. -void setup() +void setup() { - - Wire.begin(); - Serial.begin(115200); + Wire.begin(); + + Serial.begin(115200); Serial.println("Welcome."); - // Wait for the Serial monitor to be opened. - while(!Serial) + // Wait for the Serial monitor to be opened. + while (!Serial) delay(50); - - if( !kxAccel.begin() ) - { + if (!kxAccel.begin()) + { Serial.println("Could not communicate with the the KX13X. Freezing."); - while(1); - } + while (1) + ; + } - Serial.println("Ready."); + Serial.println("Ready."); - // Reset the chip so that old settings don't apply to new setups. - if( kxAccel.softwareReset() ) - Serial.println("Reset."); + // Reset the chip so that old settings don't apply to new setups. + if (kxAccel.softwareReset()) + Serial.println("Reset."); - //Give some time for the accelerometer to reset. - //It needs two, but give it five for good measure. - delay(5); + // Give some time for the accelerometer to reset. + // It needs two, but give it five for good measure. + delay(5); - // Many settings for KX13X can only be - // applied when the accelerometer is powered down. - // However there are many that can be changed "on-the-fly" - // check datasheet for more info, or the comments in the - // "...regs.h" file which specify which can be changed when. - kxAccel.enableAccel(false); + // Many settings for KX13X can only be + // applied when the accelerometer is powered down. + // However there are many that can be changed "on-the-fly" + // check datasheet for more info, or the comments in the + // "...regs.h" file which specify which can be changed when. + kxAccel.enableAccel(false); - kxAccel.enableDataEngine(); // Enables the bit that indicates data is ready. - kxAccel.enablePhysInterrupt(); // Enables interrupt pin 1 - kxAccel.routeHardwareInterrupt(0x10); // Routes the data ready bit to pin 1 + kxAccel.enableDataEngine(); // Enables the bit that indicates data is ready. + kxAccel.enablePhysInterrupt(); // Enables interrupt pin 1 + kxAccel.routeHardwareInterrupt(0x10); // Routes the data ready bit to pin 1 - // Routing Data Ready pin to interrupt pin 2. - //kxAccel.enablePhysInterrupt(true, 2); // Enables interrupt pin 2 - //kxAccel.routeHardwareInterrupt(0x10, 2); // Routes the data ready bit to pin 2 + // Routing Data Ready pin to interrupt pin 2. + // kxAccel.enablePhysInterrupt(true, 2); // Enables interrupt pin 2 + // kxAccel.routeHardwareInterrupt(0x10, 2); // Routes the data ready bit to pin 2 // This will change the interrupt behavior to latch instead of pulse - // In this case you'll need to release directly with clearInterrupt();. - //kxAccel.setLatchControl(); + // In this case you'll need to release directly with clearInterrupt();. + // kxAccel.setLatchControl(); - //kxAccel.setPinMode(); // Change interrupt to active HIGH - //kxAccel.setPulseWidth(); // Change the length of a pulsed (non latched) interrupt - - kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range - //kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 - - //kxAccel.setOutputDataRate(); // Default is 400Hz - kxAccel.enableAccel(); + // kxAccel.setPinMode(); // Change interrupt to active HIGH + // kxAccel.setPulseWidth(); // Change the length of a pulsed (non latched) interrupt + kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range + // kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 + // kxAccel.setOutputDataRate(); // Default is 400Hz + kxAccel.enableAccel(); } -void loop() +void loop() { - if( digitalRead(dataReadyPin) == HIGH ) // Check for data ready pin - { + if (digitalRead(dataReadyPin) == HIGH) // Check for data ready pin + { kxAccel.getAccelData(&myData); Serial.print("X: "); Serial.print(myData.xData, 4); @@ -104,11 +102,11 @@ void loop() Serial.print(myData.yData, 4); Serial.print(" Z: "); Serial.print(myData.zData, 4); - Serial.println(); - - // If interrupt behavior has been changed to latch, use the - // following function to clear it after reading data. - //kxAccel.clearInterrupt(); + Serial.println(); + + // If interrupt behavior has been changed to latch, use the + // following function to clear it after reading data. + // kxAccel.clearInterrupt(); } delay(20); // Delay should be 1/ODR (Output Data Rate), default is 50Hz diff --git a/examples/example3_buffer/example3_buffer.ino b/examples/example3_buffer/example3_buffer.ino index e954b37..d2bed3d 100644 --- a/examples/example3_buffer/example3_buffer.ino +++ b/examples/example3_buffer/example3_buffer.ino @@ -1,116 +1,144 @@ /* - example3-Buffer + example3-Buffer - This example shows both how to setup the buffer but also how to route the buffer's - interrupt to a physical interrupt pin. + This example shows both how to setup the buffer but also how to route the buffer's + interrupt to a physical interrupt pin. Written by Elias Santistevan @ SparkFun Electronics, October 2022 - Products: + Products: - SparkFun Triple Axis Accelerometer Breakout - KX132: - https://www.sparkfun.com/products/17871 + SparkFun Triple Axis Accelerometer Breakout - KX132: + https://www.sparkfun.com/products/17871 - SparkFun Triple Axis Accelerometer Breakout - KX134: - https://www.sparkfun.com/products/17589 + SparkFun Triple Axis Accelerometer Breakout - KX134: + https://www.sparkfun.com/products/17589 Repository: - https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library + https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library - SparkFun code, firmware, and software is released under the MIT - License (http://opensource.org/licenses/MIT). + SparkFun code, firmware, and software is released under the MIT + License (http://opensource.org/licenses/MIT). */ #include -#include "SparkFun_Qwiic_KX13X.h" +#include // Click here to get the library: http://librarymanager/All#SparkFun_KX13X -SparkFun_KX132 kxAccel; +SparkFun_KX132 kxAccel; // SparkFun_KX134 kxAccel; // For the KX134, uncomment this and comment line above outputData myData; // Struct for the accelerometer's data byte dataReadyPin = 2; // Change to fit your project. -void setup() +void setup() { - - Wire.begin(); - Serial.begin(115200); + Wire.begin(); + + Serial.begin(115200); Serial.println("Welcome."); - // Wait for the Serial monitor to be opened. - while(!Serial) + // Wait for the Serial monitor to be opened. + while (!Serial) delay(50); - - if( !kxAccel.begin() ) - { + if (!kxAccel.begin()) + { Serial.println("Could not communicate with the the KX13X. Freezing."); - while(1); - } + while (1) + ; + } - Serial.println("Ready."); + Serial.println("Ready."); - // Reset the chip so that old settings don't apply to new setups. - if( kxAccel.softwareReset() ) - Serial.println("Reset."); + // Reset the chip so that old settings don't apply to new setups. + if (kxAccel.softwareReset()) + Serial.println("Reset."); - //Give some time for the accelerometer to reset. - //It needs two, but give it five for good measure. - delay(5); + // Give some time for the accelerometer to reset. + // It needs two, but give it five for good measure. + delay(5); - // Many settings for KX13X can only be - // applied when the accelerometer is powered down. - // However there are many that can be changed "on-the-fly" - // check datasheet for more info, or the comments in the - // "...regs.h" file which specify which can be changed when. - kxAccel.enableAccel(false); + // Many settings for KX13X can only be + // applied when the accelerometer is powered down. + // However there are many that can be changed "on-the-fly" + // check datasheet for more info, or the comments in the + // "...regs.h" file which specify which can be changed when. + kxAccel.enableAccel(false); - kxAccel.enableBufferInt(); // Enables the Buffer interrupt - kxAccel.enablePhysInterrupt(); // Enables interrupt pin 1 - kxAccel.routeHardwareInterrupt(0x40); // Routes the data ready bit to pin 1 + kxAccel.enableBufferInt(); // Enables the Buffer interrupt + kxAccel.enablePhysInterrupt(); // Enables interrupt pin 1 + kxAccel.routeHardwareInterrupt(0x40); // Routes the data ready bit to pin 1 - kxAccel.enableSampleBuffer(); // Enable buffer. + kxAccel.enableSampleBuffer(); // Enable buffer. kxAccel.setBufferOperationMode(0x00); // Enable the buffer to be FIFO. - // Additional Buffer Settings - - //uint8_t numSamples = 140; - //kxAccel.setBufferThreshold(numSamples); // Set the number of sample that can be stored in the buffer + // Additional Buffer Settings - //kxAccel.setBufferResolution(); // Change sample resolution to 16 bit, 8 bit by default. - // This will change how many samples can be held in buffer. + // uint8_t numSamples = 140; + // kxAccel.setBufferThreshold(numSamples); // Set the number of sample that can be stored in the buffer - //kxAccel.clearBuffer(); // Clear the buffer - //kxAccel.getSampleLevel(); // Get the number of samples in the buffer. This number - // Changes depending on the resolution, see datasheet for more info. + kxAccel.setBufferResolution(); // Change sample resolution to 16 bit, 8 bit by default. + // This will change how many samples can be held in buffer. + // Comment the above line if you want to try using 8-bit data. - kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range - //kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 - - //kxAccel.setOutputDataRate(); // Default is 50Hz - kxAccel.enableAccel(); + // kxAccel.clearBuffer(); // Clear the buffer + // kxAccel.getSampleLevel(); // Get the number of samples in the buffer. This number + // Changes depending on the resolution, see datasheet for more info. + kxAccel.setRange(SFE_KX132_RANGE2G); // 2g Range + // kxAccel.setRange(SFE_KX134_RANGE8G); // 8g for the KX134 + // kxAccel.setOutputDataRate(); // Default is 50Hz + kxAccel.enableAccel(); } -void loop() +void loop() { - if( digitalRead(dataReadyPin) == HIGH ) // Check for data ready pin - { - kxAccel.getAccelData(&myData); - Serial.print("X: "); - Serial.print(myData.xData, 4); - Serial.print(" Y: "); - Serial.print(myData.yData, 4); - Serial.print(" Z: "); - Serial.print(myData.zData, 4); - Serial.println(); - + // We could use the KX13X interrupt pin and dataReadyPin to indicate when data is ready. + // But we can also use getSampleLevel. getSampleLevel will return how much data is in the buffer. + if (kxAccel.getSampleLevel() > 0) + { + /* + // getAccelData is slow as it manually checks if the buffer is being used + // and if the data resolution is 16-bit or 8-bit. + if (kxAccel.getAccelData(&myData) == true) + { + Serial.println(); + Serial.print("X: "); + Serial.print(myData.xData, 4); + Serial.print(" Y: "); + Serial.print(myData.yData, 4); + Serial.print(" Z: "); + Serial.print(myData.zData, 4); + Serial.println(); + } + */ + + // We can read the data more quickly by calling getRawAccelBufferData because we know + // the buffer is being used and what the data resolution is. + // The default buffer resolution is 8-bit. It will be 16-bit because we called setBufferResolution above. + // If you comment setBufferResolution, change the '1' to a '0' for 8-bit data. + rawOutputData myRawData; + if (kxAccel.getRawAccelBufferData(&myRawData, 1) == true) // Change the '1' to a '0' for 8-bit data. + { + kxAccel.convAccelData(&myData, &myRawData); // Manually convert the raw data to floating point + Serial.println(); + Serial.print("X: "); + Serial.print(myData.xData, 4); + Serial.print(" Y: "); + Serial.print(myData.yData, 4); + Serial.print(" Z: "); + Serial.print(myData.zData, 4); + Serial.println(); + } + } + else + { + Serial.print("."); // If the data rate is 50Hz (default), we'll expect to see ~20 dots between samples + delay(1); // Wait 1ms } - - delay(20); // Delay should be 1/ODR (Output Data Rate), default is 50Hz } diff --git a/examples/example4_tap/example4_tap.ino b/examples/example4_tap/example4_tap.ino index 7ad9920..9580e71 100644 --- a/examples/example4_tap/example4_tap.ino +++ b/examples/example4_tap/example4_tap.ino @@ -5,91 +5,88 @@ Written by Elias Santistevan @ SparkFun Electronics, October 2022 - Products: + Products: - SparkFun Triple Axis Accelerometer Breakout - KX132: - https://www.sparkfun.com/products/17871 + SparkFun Triple Axis Accelerometer Breakout - KX132: + https://www.sparkfun.com/products/17871 - SparkFun Triple Axis Accelerometer Breakout - KX134: - https://www.sparkfun.com/products/17589 + SparkFun Triple Axis Accelerometer Breakout - KX134: + https://www.sparkfun.com/products/17589 Repository: - https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library + https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library - SparkFun code, firmware, and software is released under the MIT - License (http://opensource.org/licenses/MIT). + SparkFun code, firmware, and software is released under the MIT + License (http://opensource.org/licenses/MIT). */ #include -#include "SparkFun_KX13X.h" +#include // Click here to get the library: http://librarymanager/All#SparkFun_KX13X -SparkFun_KX132 kxAccel; +SparkFun_KX132 kxAccel; // SparkFun_KX134 kxAccel; // For the KX134, uncomment this and comment line above byte direction = 0; -void setup() +void setup() { - - Wire.begin(); - Serial.begin(115200); + Wire.begin(); + + Serial.begin(115200); Serial.println("Welcome."); - // Wait for the Serial monitor to be opened. - while(!Serial) + // Wait for the Serial monitor to be opened. + while (!Serial) delay(50); - - if( !kxAccel.begin() ) - { + if (!kxAccel.begin()) + { Serial.println("Could not communicate with the the KX13X. Freezing."); - while(1); - } - - Serial.println("Ready."); - - // Reset the chip so that old settings don't apply to new setups. - if( kxAccel.softwareReset() ) - Serial.println("Reset."); - - //Give some time for the accelerometer to reset. - //It needs two, but give it five for good measure. - delay(5); - - // Many settings for KX13X can only be - // applied when the accelerometer is powered down. - // However there are many that can be changed "on-the-fly" - // check datasheet for more info, or the comments in the - // "...regs.h" file which specify which can be changed when. - kxAccel.enableAccel(false); - - kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range - //kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 - - kxAccel.enableTapEngine(); // Enable tap Engine - kxAccel.enableDirecTapInterupt(); // This enables checking the direction of the interrupt - //kxAccel.setTapDataRate(uint8_t rate); // Default is 400Hz - kxAccel.enableAccel(); - - + while (1) + ; + } + + Serial.println("Ready."); + + // Reset the chip so that old settings don't apply to new setups. + if (kxAccel.softwareReset()) + Serial.println("Reset."); + + // Give some time for the accelerometer to reset. + // It needs two, but give it five for good measure. + delay(5); + + // Many settings for KX13X can only be + // applied when the accelerometer is powered down. + // However there are many that can be changed "on-the-fly" + // check datasheet for more info, or the comments in the + // "...regs.h" file which specify which can be changed when. + kxAccel.enableAccel(false); + + kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range + // kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 + + kxAccel.enableTapEngine(); // Enable tap Engine + kxAccel.enableDirecTapInterupt(); // This enables checking the direction of the interrupt + // kxAccel.setTapDataRate(uint8_t rate); // Default is 400Hz + kxAccel.enableAccel(); } -void loop() +void loop() { - // Check if tap was detected - if( kxAccel.tapDetected() ) - { - Serial.print("Tap Detected: "); - Serial.println(kxAccel.getDirection(), HEX); - kxAccel.clearInterrupt(); - } + // Check if tap was detected + if (kxAccel.tapDetected()) + { + Serial.print("Tap Detected: "); + Serial.println(kxAccel.getDirection(), HEX); + kxAccel.clearInterrupt(); + } - if( kxAccel.unknownTap() || kxAccel.doubleTapDetected() ) // These all share the same bit space - kxAccel.clearInterrupt(); + if (kxAccel.unknownTap() || kxAccel.doubleTapDetected()) // These all share the same bit space + kxAccel.clearInterrupt(); delay(2.5); // Delay should be 1/ODR (Output Data Rate), default tap ODR is 400Hz - } diff --git a/examples/example5_spi/example5_spi.ino b/examples/example5_spi/example5_spi.ino index c0ac2f4..18a56e2 100644 --- a/examples/example5_spi/example5_spi.ino +++ b/examples/example5_spi/example5_spi.ino @@ -2,97 +2,94 @@ example5-BasicReadings-SPI This example shows the basic settings and functions for retrieving accelerometer - data using SPI. - Please refer to the header file for more possible settings, found here: - ..\SparkFun_KX13X_Arduino_Library\src\sfe_kx13x_defs.h + data using SPI. + Please refer to the header file for more possible settings, found here: + ..\SparkFun_KX13X_Arduino_Library\src\sfe_kx13x_defs.h Written by Elias Santistevan @ SparkFun Electronics, October 2022 - Product: + Product: - https://www.sparkfun.com/products/17871 + https://www.sparkfun.com/products/17871 Repository: - https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library + https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library - SparkFun code, firmware, and software is released under the MIT - License (http://opensource.org/licenses/MIT). + SparkFun code, firmware, and software is released under the MIT + License (http://opensource.org/licenses/MIT). */ #include -#include "SparkFun_KX13X.h" +#include // Click here to get the library: http://librarymanager/All#SparkFun_KX13X -SparkFun_KX132_SPI kxAccel; +SparkFun_KX132_SPI kxAccel; // SparkFun_KX134_SPI kxAccel; // For the KX134, uncomment this and comment line above outputData myData; // Struct for the accelerometer's data byte chipSelect = 1; // Change to fit your project. -void setup() +void setup() { - - // Get the chip select pin ready. - pinMode(chipSelect, OUTPUT); - digitalWrite(chipSelect, HIGH); - SPI.begin(); + // Get the chip select pin ready. + pinMode(chipSelect, OUTPUT); + digitalWrite(chipSelect, HIGH); - Serial.begin(115200); + SPI.begin(); + + Serial.begin(115200); Serial.println("Welcome."); - // Wait for the Serial monitor to be opened. - while(!Serial) + // Wait for the Serial monitor to be opened. + while (!Serial) delay(50); - - if( !kxAccel.begin(chipSelect) ) - { + if (!kxAccel.begin(chipSelect)) + { Serial.println("Could not communicate with the the KX13X. Freezing."); - while(1); - } - - Serial.println("Ready."); + while (1) + ; + } - // Reset the chip so that old settings don't apply to new setups. - if( kxAccel.softwareReset() ) - Serial.println("Reset."); + Serial.println("Ready."); - //Give some time for the accelerometer to reset. - //It needs two, but give it five for good measure. - delay(5); + // Reset the chip so that old settings don't apply to new setups. + if (kxAccel.softwareReset()) + Serial.println("Reset."); - // Many settings for KX13X can only be - // applied when the accelerometer is powered down. - // However there are many that can be changed "on-the-fly" - // check datasheet for more info, or the comments in the - // "...regs.h" file which specify which can be changed when. - kxAccel.enableAccel(false); + // Give some time for the accelerometer to reset. + // It needs two, but give it five for good measure. + delay(5); - kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range - //kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 - - kxAccel.enableDataEngine(); // Enables the bit that indicates data is ready. - // kxAccel.setOutputDataRate(); // Default is 50Hz - kxAccel.enableAccel(); + // Many settings for KX13X can only be + // applied when the accelerometer is powered down. + // However there are many that can be changed "on-the-fly" + // check datasheet for more info, or the comments in the + // "...regs.h" file which specify which can be changed when. + kxAccel.enableAccel(false); + kxAccel.setRange(SFE_KX132_RANGE16G); // 16g Range + // kxAccel.setRange(SFE_KX134_RANGE16G); // 16g for the KX134 + kxAccel.enableDataEngine(); // Enables the bit that indicates data is ready. + // kxAccel.setOutputDataRate(); // Default is 50Hz + kxAccel.enableAccel(); } -void loop() +void loop() { - // Check if data is ready. - if( kxAccel.dataReady() ) - { - kxAccel.getAccelData(&myData); - Serial.print("X: "); - Serial.print(myData.xData, 4); - Serial.print(" Y: "); - Serial.print(myData.yData, 4); - Serial.print(" Z: "); - Serial.print(myData.zData, 4); - Serial.println(); - } + // Check if data is ready. + if (kxAccel.dataReady()) + { + kxAccel.getAccelData(&myData); + Serial.print("X: "); + Serial.print(myData.xData, 4); + Serial.print(" Y: "); + Serial.print(myData.yData, 4); + Serial.print(" Z: "); + Serial.print(myData.zData, 4); + Serial.println(); + } delay(20); // Delay should be 1/ODR (Output Data Rate), default is 1/50ODR - } diff --git a/keywords.txt b/keywords.txt index b3d691f..39a441e 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,41 +1,77 @@ ================================== CLASS ================================== -QwiicKX13xCore KEYWORD1 +SparkFun_KX134 KEYWORD1 +SparkFun_KX134_SPI KEYWORD1 +SparkFun_KX132 KEYWORD1 +SparkFun_KX132_SPI KEYWORD1 +QwDevKX13X KEYWORD1 ================================== FUNCTIONS ================================== +getUniqueI KEYWORD2D initialize KEYWORD2 -runCommandTest KEYWORD2 -accelControl KEYWORD2 -readAccelState KEYWORD2 +enableAccel KEYWORD2 +softwareReset KEYWORD2 +getOperatingMode KEYWORD2 setRange KEYWORD2 +setInterruptPin KEYWORD2 +enableDataEngine KEYWORD2 setOutputDataRate KEYWORD2 +getOutputDataRate KEYWORD2 +dataReady KEYWORD2 +runCommandTest KEYWORD2 +readAccelState KEYWORD2 +getRawAccelData KEYWORD2 +getRawAccelRegisterData KEYWORD2 +getRawAccelBufferData KEYWORD2 readOutputDataRate KEYWORD2 -setInterruptPin KEYWORD2 +enableTapEngine KEYWORD2 +setTapDataRate KEYWORD2 +enableDirecTapInterupt KEYWORD2 +enableDoubleTapInterrupt KEYWORD2 +enableTiltEngine KEYWORD2 +setTiltDataRate KEYWORD2 +setWakeDataRate KEYWORD2 +enableSleepEngine KEYWORD2 +enableWakeEngine KEYWORD2 +forceWake KEYWORD2 +forceSleep KEYWORD2 +configureInterruptPin KEYWORD2 routeHardwareInterrupt KEYWORD2 +enablePhysInterrupt KEYWORD2 +setPinMode KEYWORD2 +setLatchControl KEYWORD2 +setPulseWidth KEYWORD2 clearInterrupt KEYWORD2 -dataTrigger KEYWORD2 +tapDetected KEYWORD2 +getDirection KEYWORD2 +unknownTap KEYWORD2 +waterMarkReached KEYWORD2 +bufferFull KEYWORD2 +freeFall KEYWORD2 +doubleTapDetected KEYWORD2 +tiltChange KEYWORD2 setBufferThreshold KEYWORD2 -setBufferOperation KEYWORD2 -enableBuffer KEYWORD2 -getRawAccelData KEYWORD2 -readRegister KEYWORD2 -writeRegister KEYWORD2 -readMultipleRegisters KEYWORD2 -overBufLenI2CRead KEYWORD2 +setBufferOperationMode KEYWORD2 +setBufferResolution KEYWORD2 +enableBufferInt KEYWORD2 +enableSampleBuffer KEYWORD2 +getSampleLevel KEYWORD2 +clearBuffer KEYWORD2 +getAccelData KEYWORD2 +convAccelData KEYWORD2 ================================== CONSTANTS ================================== -KX13X_DEFAULT_ADDRESS LITERAL1 -KX13X_ALT_ADDRESS LITERAL1 +KX13X_ADDRESS_HIGH LITERAL1 +KX13X_ADDRESS_LOW LITERAL1 KX132_WHO_AM_I LITERAL1 KX134_WHO_AM_I LITERAL1 TOTAL_ACCEL_DATA_16BIT LITERAL1 TOTAL_ACCEL_DATA_8BIT LITERAL1 -MAX_BUFFER_LENGTH LITERAL1 XLSB LITERAL1 XMSB LITERAL1 YLSB LITERAL1 @@ -43,7 +79,6 @@ YMSB LITERAL1 ZLSB LITERAL1 ZMSB LITERAL1 SPI_READ LITERAL1 -SPI_WRITE LITERAL1 DEFAULT_SETTINGS LITERAL1 INT_SETTINGS LITERAL1 SOFT_INT_SETTINGS LITERAL1 @@ -56,109 +91,101 @@ BUFFER_8BIT_SAMPLES LITERAL1 BUFFER_MODE_FIFO LITERAL1 BUFFER_MODE_STREAM LITERAL1 BUFFER_MODE_TRIGGER LITERAL1 -KX132_RANGE2G LITERAL1 -KX132_RANGE4G LITERAL1 -KX132_RANGE8G LITERAL1 -KX132_RANGE16G LITERAL1 -KX134_RANGE8G LITERAL1 -KX134_RANGE16G LITERAL1 -KX134_RANGE32G LITERAL1 -KX134_RANGE64G LITERAL1 -KX13X_MAN_ID LITERAL1 -KX13X_PART_ID LITERAL1 -KX13X_XADP_L LITERAL1 -KX13X_XADP_H LITERAL1 -KX13X_YADP_L LITERAL1 -KX13X_YADP_H LITERAL1 -KX13X_ZADP_L LITERAL1 -KX13X_ZADP_H LITERAL1 -KX13X_XOUT_L LITERAL1 -KX13X_XOUT_H LITERAL1 -KX13X_YOUT_L LITERAL1 -KX13X_YOUT_H LITERAL1 -KX13X_ZOUT_L LITERAL1 -KX13X_ZOUT_H LITERAL1 -KX13X_COTR LITERAL1 -KX13X_WHO_AM_I LITERAL1 -KXI3X_TSCP LITERAL1 -KX13X_TSPP LITERAL1 -KX13X_INS1 LITERAL1 -KX13X_INS2 LITERAL1 -KX13X_INS3 LITERAL1 -KX13X_STATUS_REG LITERAL1 -KX13X_INT_REL LITERAL1 -KX13X_CNTL1 LITERAL1 -KX13X_CNTL2 LITERAL1 -KX13X_CNTL3 LITERAL1 -KX13X_CNTL4 LITERAL1 -KX13X_CNTL5 LITERAL1 -KX13X_CNTL6 LITERAL1 -KX13X_ODCNTL LITERAL1 -KX13X_INC1 LITERAL1 -KX13X_INC2 LITERAL1 -KX13X_INC3 LITERAL1 -KX13X_INC4 LITERAL1 -KX13X_INC5 LITERAL1 -KX13X_INC6 LITERAL1 -KX13X_TILT_TIMER LITERAL1 -KX13X_TDTRC LITERAL1 -KX13X_TDTC LITERAL1 -KX13X_TTH LITERAL1 -KX13X_TTL LITERAL1 -KX13X_FTD LITERAL1 -KX13X_STD LITERAL1 -KX13X_TLT LITERAL1 -KX13X_TWS LITERAL1 -KX13X_FFTH LITERAL1 -KX13X_FFC LITERAL1 -KX13X_FFCNTL LITERAL1 -KX13X_TILT_ANGLE_LL LITERAL1 -KX13X_TILT_ANGLE_HL LITERAL1 -KX13X_HYST_SET LITERAL1 -KX13X_LP_CNTL1 LITERAL1 -KX13X_LP_CNTL2 LITERAL1 -KX13X_WUFTH LITERAL1 -KX13X_BTSWUFTH LITERAL1 -KX13X_BTSTH LITERAL1 -KX13X_BTSC LITERAL1 -KX13X_WUFC LITERAL1 -KX13X_SELF_TEST LITERAL1 -KX13X_BUF_CNTL1 LITERAL1 -KX13X_BUF_CNTL2 LITERAL1 -KX13X_BUF_STATUS_1 LITERAL1 -KX13X_BUF_STATUS_2 LITERAL1 -KX13X_BUF_CLEAR LITERAL1 -KX13X_BUF_READ LITERAL1 -KX13X_ADP_CNTL1 LITERAL1 -KX13X_ADP_CNTL2 LITERAL1 -KX13X_ADP_CNTL3 LITERAL1 -KX13X_ADP_CNTL4 LITERAL1 -KX13X_ADP_CNTL5 LITERAL1 -KX13X_ADP_CNTL6 LITERAL1 -KX13X_ADP_CNTL7 LITERAL1 -KX13X_ADP_CNTL8 LITERAL1 -KX13X_ADP_CNTL9 LITERAL1 -KX13X_ADP_CNTL10 LITERAL1 -KX13X_ADP_CNTL11 LITERAL1 -KX13X_ADP_CNTL12 LITERAL1 -KX13X_ADP_CNTL13 LITERAL1 -KX13X_ADP_CNTL14 LITERAL1 -KX13X_ADP_CNTL15 LITERAL1 -KX13X_ADP_CNTL16 LITERAL1 -KX13X_ADP_CNTL17 LITERAL1 -KX13X_ADP_CNTL18 LITERAL1 -KX13X_ADP_CNTL19 LITERAL1 -KX13X_SUCCESS LITERAL1 -KX13X_GENERAL_ERROR LITERAL1 -KX13X_I2C_ERROR LITERAL1 -HI_TILT_POSITION LITERAL1 -HI_WAKE_UP LITERAL1 -HI_TAP_DOUBLE_TAP LITERAL1 -HI_BACK_TO_SLEEP LITERAL1 -HI_DATA_READY LITERAL1 -HI_WATERMARK LITERAL1 -HI_BUFFER_FULL LITERAL1 -HI_FREEFALL LITERAL1 +SFE_KX132_RANGE2G LITERAL1 +SFE_KX132_RANGE4G LITERAL1 +SFE_KX132_RANGE8G LITERAL1 +SFE_KX132_RANGE16G LITERAL1 +SFE_KX134_RANGE8G LITERAL1 +SFE_KX134_RANGE16G LITERAL1 +SFE_KX134_RANGE32G LITERAL1 +SFE_KX134_RANGE64G LITERAL1 +SFE_KX13X_MAN_ID LITERAL1 +SFE_KX13X_PART_ID LITERAL1 +SFE_KX13X_XADP_L LITERAL1 +SFE_KX13X_XADP_H LITERAL1 +SFE_KX13X_YADP_L LITERAL1 +SFE_KX13X_YADP_H LITERAL1 +SFE_KX13X_ZADP_L LITERAL1 +SFE_KX13X_ZADP_H LITERAL1 +SFE_KX13X_XOUT_L LITERAL1 +SFE_KX13X_XOUT_H LITERAL1 +SFE_KX13X_YOUT_L LITERAL1 +SFE_KX13X_YOUT_H LITERAL1 +SFE_KX13X_ZOUT_L LITERAL1 +SFE_KX13X_ZOUT_H LITERAL1 +SFE_KX13X_COTR LITERAL1 +SFE_KX13X_WHO_AM_I LITERAL1 +SFE_KX13X_TSCP LITERAL1 +SFE_KX13X_TSPP LITERAL1 +SFE_KX13X_INS1 LITERAL1 +SFE_KX13X_INS2 LITERAL1 +SFE_KX13X_INS3 LITERAL1 +SFE_KX13X_STATUS_REG LITERAL1 +SFE_KX13X_INT_REL LITERAL1 +SFE_KX13X_CNTL1 LITERAL1 +SFE_KX13X_CNTL2 LITERAL1 +SFE_KX13X_CNTL3 LITERAL1 +SFE_KX13X_CNTL4 LITERAL1 +SFE_KX13X_CNTL5 LITERAL1 +SFE_KX13X_CNTL6 LITERAL1 +SFE_KX13X_ODCNTL LITERAL1 +SFE_KX13X_INC1 LITERAL1 +SFE_KX13X_INC2 LITERAL1 +SFE_KX13X_INC3 LITERAL1 +SFE_KX13X_INC4 LITERAL1 +SFE_KX13X_INC5 LITERAL1 +SFE_KX13X_INC6 LITERAL1 +SFE_KX13X_TILT_TIMER LITERAL1 +SFE_KX13X_TDTRC LITERAL1 +SFE_KX13X_TDTC LITERAL1 +SFE_KX13X_TTH LITERAL1 +SFE_KX13X_TTL LITERAL1 +SFE_KX13X_FTD LITERAL1 +SFE_KX13X_STD LITERAL1 +SFE_KX13X_TLT LITERAL1 +SFE_KX13X_TWS LITERAL1 +SFE_KX13X_FFTH LITERAL1 +SFE_KX13X_FFC LITERAL1 +SFE_KX13X_FFCNTL LITERAL1 +SFE_KX13X_TILT_ANGLE_LL LITERAL1 +SFE_KX13X_TILT_ANGLE_HL LITERAL1 +SFE_KX13X_HYST_SET LITERAL1 +SFE_KX13X_LP_CNTL1 LITERAL1 +SFE_KX13X_LP_CNTL2 LITERAL1 +SFE_KX13X_WUFTH LITERAL1 +SFE_KX13X_BTSWUFTH LITERAL1 +SFE_KX13X_BTSTH LITERAL1 +SFE_KX13X_BTSC LITERAL1 +SFE_KX13X_WUFC LITERAL1 +SFE_KX13X_SELF_TEST LITERAL1 +SFE_KX13X_BUF_CNTL1 LITERAL1 +SFE_KX13X_BUF_CNTL2 LITERAL1 +SFE_KX13X_BUF_STATUS_1 LITERAL1 +SFE_KX13X_BUF_STATUS_2 LITERAL1 +SFE_KX13X_BUF_CLEAR LITERAL1 +SFE_KX13X_BUF_READ LITERAL1 +SFE_KX13X_ADP_CNTL1 LITERAL1 +SFE_KX13X_ADP_CNTL2 LITERAL1 +SFE_KX13X_ADP_CNTL3 LITERAL1 +SFE_KX13X_ADP_CNTL4 LITERAL1 +SFE_KX13X_ADP_CNTL5 LITERAL1 +SFE_KX13X_ADP_CNTL6 LITERAL1 +SFE_KX13X_ADP_CNTL7 LITERAL1 +SFE_KX13X_ADP_CNTL8 LITERAL1 +SFE_KX13X_ADP_CNTL9 LITERAL1 +SFE_KX13X_ADP_CNTL10 LITERAL1 +SFE_KX13X_ADP_CNTL11 LITERAL1 +SFE_KX13X_ADP_CNTL12 LITERAL1 +SFE_KX13X_ADP_CNTL13 LITERAL1 +SFE_KX13X_ADP_CNTL14 LITERAL1 +SFE_KX13X_ADP_CNTL15 LITERAL1 +SFE_KX13X_ADP_CNTL16 LITERAL1 +SFE_KX13X_ADP_CNTL17 LITERAL1 +SFE_KX13X_ADP_CNTL18 LITERAL1 +SFE_KX13X_ADP_CNTL19 LITERAL1 +SFE_KX13X_SUCCESS LITERAL1 +SFE_KX13X_GENERAL_ERROR LITERAL1 +SFE_KX13X_I2C_ERROR LITERAL1 ================================== DATA TYPES @@ -166,3 +193,5 @@ DATA TYPES KX13X_REGISTERS KEYWORD1 KX13X_STATUS_t KEYWORD1 HARDWARE_INTERRUPT KEYWORD1 +rawOutputData KEYWORD1 +rawAccelData KEYWORD1 diff --git a/library.properties b/library.properties index 5ab1b87..c435298 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=SparkFun KX13X Arduino Library -version=2.0.2 +version=2.0.3 author=SparkFun Electronics maintainer=Elias Santistevan @ SparkFun Electronics sentence=Communicates and configures the SparkFun KX132/KX134 Accelerometer. paragraph=This library breaks out all the functionality of the Kionix KX132 and KX134. category=Sensors -url=www.github.com/sparkfun/SparkFun_KX13X_Arduino_Library +url=https://github.com/sparkfun/SparkFun_KX13X_Arduino_Library architectures=* diff --git a/src/SparkFun_KX13X.h b/src/SparkFun_KX13X.h index b6c4e65..826faf1 100644 --- a/src/SparkFun_KX13X.h +++ b/src/SparkFun_KX13X.h @@ -9,7 +9,7 @@ // Written by Elias Santistevan @ SparkFun Electronics, October 2022 // // Product: -//SparkFun Triple Axis Accelerometer - KX132/KX134 (Qwiic) +// SparkFun Triple Axis Accelerometer - KX132/KX134 (Qwiic) // * KX132 - https://www.sparkfun.com/products/17871 // * KX134 - https://www.sparkfun.com/products/17589 // @@ -39,7 +39,6 @@ // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - // The following class implements the Arduino Interface for the SparkFun Triple // Axis Acceleromters - KX132/KX134. @@ -51,241 +50,229 @@ class SparkFun_KX132 : public QwDevKX132 { - public: - - SparkFun_KX132() {}; - - /////////////////////////////////////////////////////////////////////// - // begin() - // - // This method is called to initialize the ISM330DHCX library and connect to - // the ISM330DHCX device. This method must be called before calling any other method - // that interacts with the device. - // - // This method follows the standard startup pattern in SparkFun Arduino - // libraries. - // - // Parameter Description - // --------- ---------------------------- - // wirePort optional. The Wire port. If not provided, the default port is used - // address optional. I2C Address. If not provided, the default address is used. - // retval true on success, false on startup failure - // - // This methond is overridden, implementing two versions. - // - // Version 1: - // User skips passing in an I2C object which then defaults to Wire. - bool begin(uint8_t deviceAddress = KX13X_ADDRESS_HIGH) - { - // Setup I2C object and pass into the superclass - setCommunicationBus(_i2cBus, deviceAddress); - - // Initialize the I2C buss class i.e. setup default Wire port - _i2cBus.init(); - - // Initialize the system - return results - return this->QwDevKX132::init(); - } - - //Version 2: - // User passes in an I2C object and an address (optional). - bool begin(TwoWire &wirePort, uint8_t deviceAddress = KX13X_ADDRESS_HIGH) - { - // Setup I2C object and pass into the superclass - setCommunicationBus(_i2cBus, deviceAddress); - - // Give the I2C port provided by the user to the I2C bus class. - _i2cBus.init(wirePort, true); - - // Initialize the system - return results - return this->QwDevKX132::init(); - } - - private: - - //I2C bus class - QwI2C _i2cBus; - +public: + SparkFun_KX132(){}; + + /////////////////////////////////////////////////////////////////////// + // begin() + // + // This method is called to initialize the ISM330DHCX library and connect to + // the ISM330DHCX device. This method must be called before calling any other method + // that interacts with the device. + // + // This method follows the standard startup pattern in SparkFun Arduino + // libraries. + // + // Parameter Description + // --------- ---------------------------- + // wirePort optional. The Wire port. If not provided, the default port is used + // address optional. I2C Address. If not provided, the default address is used. + // retval true on success, false on startup failure + // + // This methond is overridden, implementing two versions. + // + // Version 1: + // User skips passing in an I2C object which then defaults to Wire. + bool begin(uint8_t deviceAddress = KX13X_ADDRESS_HIGH) + { + // Setup I2C object and pass into the superclass + setCommunicationBus(_i2cBus, deviceAddress); + + // Initialize the I2C buss class i.e. setup default Wire port + _i2cBus.init(); + + // Initialize the system - return results + return this->QwDevKX132::init(); + } + + // Version 2: + // User passes in an I2C object and an address (optional). + bool begin(TwoWire &wirePort, uint8_t deviceAddress = KX13X_ADDRESS_HIGH) + { + // Setup I2C object and pass into the superclass + setCommunicationBus(_i2cBus, deviceAddress); + + // Give the I2C port provided by the user to the I2C bus class. + _i2cBus.init(wirePort, true); + + // Initialize the system - return results + return this->QwDevKX132::init(); + } + +private: + // I2C bus class + sfe_KX13X::QwI2C _i2cBus; }; - + class SparkFun_KX132_SPI : public QwDevKX132 { - public: - - SparkFun_KX132_SPI() {}; - - /////////////////////////////////////////////////////////////////////// - // begin() - // - // This method is called to initialize the ISM330DHCX library and connect to - // the ISM330DHCX device. This method must be called before calling any other method - // that interacts with the device. - // - // This method follows the standard startup pattern in SparkFun Arduino - // libraries. - // - // Parameter Description - // --------- ---------------------------- - // spiPort optional. The SPI port. If not provided, the default port is used - // SPISettings optional. SPI "transaction" settings are need for every data transfer. - // Default used if not provided. - // Chip Select mandatory. The chip select pin ("CS") can't be guessed, so must be provided. - // retval true on success, false on startup failure - // - // This methond is overridden, implementing two versions. - // - // Version 1: - // User skips passing in an SPI object which then defaults to SPI. - - bool begin(uint8_t cs) - { - // Setup a SPI object and pass into the superclass - setCommunicationBus(_spiBus); - - // Initialize the SPI bus class with the chip select pin, SPI port defaults to SPI, - // and SPI settings are set to class defaults. - _spiBus.init(cs, true); - - // Initialize the system - return results - return this->QwDevKX132::init(); - } - - bool begin(SPIClass &spiPort, SPISettings kxSettings, uint8_t cs) - { - // Setup a SPI object and pass into the superclass - setCommunicationBus(_spiBus); - - // Initialize the SPI bus class with provided SPI port, SPI setttings, and chip select pin. - _spiBus.init(spiPort, kxSettings, cs, true); - - // Initialize the system - return results - return this->QwDevKX132::init(); - } - - private: - - // SPI bus class - SfeSPI _spiBus; - +public: + SparkFun_KX132_SPI(){}; + + /////////////////////////////////////////////////////////////////////// + // begin() + // + // This method is called to initialize the ISM330DHCX library and connect to + // the ISM330DHCX device. This method must be called before calling any other method + // that interacts with the device. + // + // This method follows the standard startup pattern in SparkFun Arduino + // libraries. + // + // Parameter Description + // --------- ---------------------------- + // spiPort optional. The SPI port. If not provided, the default port is used + // SPISettings optional. SPI "transaction" settings are need for every data transfer. + // Default used if not provided. + // Chip Select mandatory. The chip select pin ("CS") can't be guessed, so must be provided. + // retval true on success, false on startup failure + // + // This methond is overridden, implementing two versions. + // + // Version 1: + // User skips passing in an SPI object which then defaults to SPI. + + bool begin(uint8_t cs) + { + // Setup a SPI object and pass into the superclass + setCommunicationBus(_spiBus); + + // Initialize the SPI bus class with the chip select pin, SPI port defaults to SPI, + // and SPI settings are set to class defaults. + _spiBus.init(cs, true); + + // Initialize the system - return results + return this->QwDevKX132::init(); + } + + bool begin(SPIClass &spiPort, SPISettings kxSettings, uint8_t cs) + { + // Setup a SPI object and pass into the superclass + setCommunicationBus(_spiBus); + + // Initialize the SPI bus class with provided SPI port, SPI setttings, and chip select pin. + _spiBus.init(spiPort, kxSettings, cs, true); + + // Initialize the system - return results + return this->QwDevKX132::init(); + } + +private: + // SPI bus class + sfe_KX13X::SfeSPI _spiBus; }; class SparkFun_KX134 : public QwDevKX134 { - public: - - SparkFun_KX134() {}; - - /////////////////////////////////////////////////////////////////////// - // begin() - // - // This method is called to initialize the ISM330DHCX library and connect to - // the ISM330DHCX device. This method must be called before calling any other method - // that interacts with the device. - // - // This method follows the standard startup pattern in SparkFun Arduino - // libraries. - // - // Parameter Description - // --------- ---------------------------- - // wirePort optional. The Wire port. If not provided, the default port is used - // address optional. I2C Address. If not provided, the default address is used. - // retval true on success, false on startup failure - // - // This methond is overridden, implementing two versions. - // - // Version 1: - // User skips passing in an I2C object which then defaults to Wire. - bool begin(uint8_t deviceAddress = KX13X_ADDRESS_HIGH) - { - // Setup I2C object and pass into the superclass - setCommunicationBus(_i2cBus, deviceAddress); - - // Initialize the I2C buss class i.e. setup default Wire port - _i2cBus.init(); - - // Initialize the system - return results - return this->QwDevKX134::init(); - } - - //Version 2: - // User passes in an I2C object and an address (optional). - bool begin(TwoWire &wirePort, uint8_t deviceAddress = KX13X_ADDRESS_HIGH) - { - // Setup I2C object and pass into the superclass - setCommunicationBus(_i2cBus, deviceAddress); - - // Give the I2C port provided by the user to the I2C bus class. - _i2cBus.init(wirePort, true); - - // Initialize the system - return results - return this->QwDevKX134::init(); - } - - private: - - //I2C bus class - QwI2C _i2cBus; - +public: + SparkFun_KX134(){}; + + /////////////////////////////////////////////////////////////////////// + // begin() + // + // This method is called to initialize the ISM330DHCX library and connect to + // the ISM330DHCX device. This method must be called before calling any other method + // that interacts with the device. + // + // This method follows the standard startup pattern in SparkFun Arduino + // libraries. + // + // Parameter Description + // --------- ---------------------------- + // wirePort optional. The Wire port. If not provided, the default port is used + // address optional. I2C Address. If not provided, the default address is used. + // retval true on success, false on startup failure + // + // This methond is overridden, implementing two versions. + // + // Version 1: + // User skips passing in an I2C object which then defaults to Wire. + bool begin(uint8_t deviceAddress = KX13X_ADDRESS_HIGH) + { + // Setup I2C object and pass into the superclass + setCommunicationBus(_i2cBus, deviceAddress); + + // Initialize the I2C buss class i.e. setup default Wire port + _i2cBus.init(); + + // Initialize the system - return results + return this->QwDevKX134::init(); + } + + // Version 2: + // User passes in an I2C object and an address (optional). + bool begin(TwoWire &wirePort, uint8_t deviceAddress = KX13X_ADDRESS_HIGH) + { + // Setup I2C object and pass into the superclass + setCommunicationBus(_i2cBus, deviceAddress); + + // Give the I2C port provided by the user to the I2C bus class. + _i2cBus.init(wirePort, true); + + // Initialize the system - return results + return this->QwDevKX134::init(); + } + +private: + // I2C bus class + sfe_KX13X::QwI2C _i2cBus; }; - + class SparkFun_KX134_SPI : public QwDevKX134 { - public: - - SparkFun_KX134_SPI() {}; - - /////////////////////////////////////////////////////////////////////// - // begin() - // - // This method is called to initialize the ISM330DHCX library and connect to - // the ISM330DHCX device. This method must be called before calling any other method - // that interacts with the device. - // - // This method follows the standard startup pattern in SparkFun Arduino - // libraries. - // - // Parameter Description - // --------- ---------------------------- - // spiPort optional. The SPI port. If not provided, the default port is used - // SPISettings optional. SPI "transaction" settings are need for every data transfer. - // Default used if not provided. - // Chip Select mandatory. The chip select pin ("CS") can't be guessed, so must be provided. - // retval true on success, false on startup failure - // - // This methond is overridden, implementing two versions. - // - // Version 1: - // User skips passing in an SPI object which then defaults to SPI. - - bool begin(uint8_t cs) - { - // Setup a SPI object and pass into the superclass - setCommunicationBus(_spiBus); - - // Initialize the SPI bus class with the chip select pin, SPI port defaults to SPI, - // and SPI settings are set to class defaults. - _spiBus.init(cs, true); - - // Initialize the system - return results - return this->QwDevKX134::init(); - } - - bool begin(SPIClass &spiPort, SPISettings kxSettings, uint8_t cs) - { - // Setup a SPI object and pass into the superclass - setCommunicationBus(_spiBus); - - // Initialize the SPI bus class with provided SPI port, SPI setttings, and chip select pin. - _spiBus.init(spiPort, kxSettings, cs, true); - - // Initialize the system - return results - return this->QwDevKX134::init(); - } - - private: - - // SPI bus class - SfeSPI _spiBus; - +public: + SparkFun_KX134_SPI(){}; + + /////////////////////////////////////////////////////////////////////// + // begin() + // + // This method is called to initialize the ISM330DHCX library and connect to + // the ISM330DHCX device. This method must be called before calling any other method + // that interacts with the device. + // + // This method follows the standard startup pattern in SparkFun Arduino + // libraries. + // + // Parameter Description + // --------- ---------------------------- + // spiPort optional. The SPI port. If not provided, the default port is used + // SPISettings optional. SPI "transaction" settings are need for every data transfer. + // Default used if not provided. + // Chip Select mandatory. The chip select pin ("CS") can't be guessed, so must be provided. + // retval true on success, false on startup failure + // + // This methond is overridden, implementing two versions. + // + // Version 1: + // User skips passing in an SPI object which then defaults to SPI. + + bool begin(uint8_t cs) + { + // Setup a SPI object and pass into the superclass + setCommunicationBus(_spiBus); + + // Initialize the SPI bus class with the chip select pin, SPI port defaults to SPI, + // and SPI settings are set to class defaults. + _spiBus.init(cs, true); + + // Initialize the system - return results + return this->QwDevKX134::init(); + } + + bool begin(SPIClass &spiPort, SPISettings kxSettings, uint8_t cs) + { + // Setup a SPI object and pass into the superclass + setCommunicationBus(_spiBus); + + // Initialize the SPI bus class with provided SPI port, SPI setttings, and chip select pin. + _spiBus.init(spiPort, kxSettings, cs, true); + + // Initialize the system - return results + return this->QwDevKX134::init(); + } + +private: + // SPI bus class + sfe_KX13X::SfeSPI _spiBus; }; diff --git a/src/SparkFun_KX13X_regs.h b/src/SparkFun_KX13X_regs.h index 1c70472..e72f22f 100644 --- a/src/SparkFun_KX13X_regs.h +++ b/src/SparkFun_KX13X_regs.h @@ -41,309 +41,358 @@ // This file holds the bit fields for the KX132/KX134 registers. -#define SFE_KX13X_MAN_ID 0x00// Retuns "KION" in ASCII - // -typedef struct +#define SFE_KX13X_MAN_ID 0x00 // Retuns "KION" in ASCII + // +typedef struct { - uint8_t man_id : 8; + uint8_t man_id : 8; } sfe_kx13x_man_id_t; -#define SFE_KX13X_PART_ID 0x01// Retuns "KION" in ASCII -typedef struct +#define SFE_KX13X_PART_ID 0x01 // Retuns "KION" in ASCII +typedef struct { - uint8_t part_id : 8; -} sfe_kx13x_part_id_t; + uint8_t part_id : 8; +} sfe_kx13x_part_id_t; #define SFE_KX13X_XADP_L 0x02 typedef struct { - uint8_t xadp_l : 8; + uint8_t xadp_l : 8; } sfe_kx13x_xadp_l_t; #define SFE_KX13X_XADP_H 0x03 typedef struct { - uint8_t xadp_h : 8; + uint8_t xadp_h : 8; } sfe_kx13x_xadp_h_t; #define SFE_KX13X_YADP_L 0x04 typedef struct { - uint8_t yadp_l : 8; + uint8_t yadp_l : 8; } sfe_kx13x_yadp_l_t; #define SFE_KX13X_YADP_H 0x05 typedef struct { - uint8_t yadp_l : 8; + uint8_t yadp_h : 8; } sfe_kx13x_yadp_h_t; #define SFE_KX13X_ZADP_L 0x06 typedef struct { - uint8_t yadp_l : 8; + uint8_t zadp_l : 8; } sfe_kx13x_zadp_l_t; #define SFE_KX13X_ZADP_H 0x07 typedef struct { - uint8_t zadp_h : 8; + uint8_t zadp_h : 8; } sfe_kx13x_zadp_h_t; #define SFE_KX13X_XOUT_L 0x08 typedef struct { - uint8_t xout_l : 8; + uint8_t xout_l : 8; } sfe_kx13x_xout_l_t; #define SFE_KX13X_XOUT_H 0x09 typedef struct { - uint8_t xout_h : 8; + uint8_t xout_h : 8; } sfe_kx13x_xout_h_t; #define SFE_KX13X_YOUT_L 0x0A typedef struct { - uint8_t yout_l : 8; + uint8_t yout_l : 8; } sfe_kx13x_yout_l_t; #define SFE_KX13X_YOUT_H 0x0B typedef struct { - uint8_t yout_h : 8; + uint8_t yout_h : 8; } sfe_kx13x_yout_h_t; #define SFE_KX13X_ZOUT_L 0x0C typedef struct { - uint8_t zout_l : 8; + uint8_t zout_l : 8; } sfe_kx13x_zout_l_t; -#define SFE_KX13X_ZOUT_H 0x0D --------------^^-------------------------- +#define SFE_KX13X_ZOUT_H 0x0D typedef struct { - uint8_t zout_h : 8; + uint8_t zout_h : 8; } sfe_kx13x_zout_h_t; -#define SFE_KX13X_COTR 0x12 -// Command Test Response +#define SFE_KX13X_COTR 0x12 +// Command Test Response // Verifies the proper integrated circuit intergrity typedef struct { - uint8_t dc_str : 8; //Default 0b01010101 : 0x55 + uint8_t dc_str : 8; // Default 0b01010101 : 0x55 } sfe_kx13x_cotr_t; -#define SFE_KX13X_WHO_AM_I 0x13 -//Identifies the accelerometer being used: 0x3D - KX132 and 0x46 - KX135 +#define SFE_KX13X_WHO_AM_I 0x13 +// Identifies the accelerometer being used: 0x3D - KX132 and 0x46 - KX135 typedef struct { - uint8_t wai : 8; + uint8_t wai : 8; } sfe_kx13x_wai_t; #define SFE_KXI3X_TSCP 0x14 -//Current Tilt Position Register reports current position data +// Current Tilt Position Register reports current position data typedef struct { - uint8_t reserved_one : 1; - uint8_t reserved_two : 1; - uint8_t left_state : 1; //X- - uint8_t right_state : 1; //X+ - uint8_t down_state : 1; //Y- - uint8_t up_state : 1; //Y+ - uint8_t face_down_state : 1; //Z- - uint8_t face_up_down_state : 1; //Z+ + uint8_t face_up_state : 1; // Z+ + uint8_t face_down_state : 1; // Z- + uint8_t up_state : 1; // Y+ + uint8_t down_state : 1; // Y- + uint8_t right_state : 1; // X+ + uint8_t left_state : 1; // X- + uint8_t reserved_one : 1; + uint8_t reserved_two : 1; } sfe_kx13x_tscp_t; #define SFE_KX13X_TSPP 0x15 -//Previous Tilt Position Register reports previous position data +// Previous Tilt Position Register reports previous position data typedef struct { - uint8_t reserved_one : 1; - uint8_t reserved_two : 1; - uint8_t left_state : 1; //X- - uint8_t right_state : 1; //X+ - uint8_t down_state : 1; //Y- - uint8_t up_state : 1; //Y+ - uint8_t face_down_state : 1; //Z- - uint8_t face_up_down_state : 1; //Z+ + uint8_t face_up_state : 1; // Z+ + uint8_t face_down_state : 1; // Z- + uint8_t up_state : 1; // Y+ + uint8_t down_state : 1; // Y- + uint8_t right_state : 1; // X+ + uint8_t left_state : 1; // X- + uint8_t reserved_one : 1; + uint8_t reserved_two : 1; } sfe_kx13x_tspp_t; -#define SFE_KX13X_INS1 0x16 +#define SFE_KX13X_INS1 0x16 // Reports Tap and Double Tap interrupts according to the bit. Bit -// is cleared when the interrupt latch release register (INT_REL) is read. +// is cleared when the interrupt latch release register (INT_REL) is read. typedef struct { - uint8_t reserved_one : 1; - uint8_t reserved_two : 1; - uint8_t tap_left : 1; //X- - uint8_t tap_right : 1; //X+ - uint8_t tap_down : 1; //Y- - uint8_t tap_up : 1; //Y+ - uint8_t tap_face_down : 1; //Z- - uint8_t tap_face_up : 1; //Z+ + uint8_t tap_face_up : 1; // Z+ + uint8_t tap_face_down : 1; // Z- + uint8_t tap_up : 1; // Y+ + uint8_t tap_down : 1; // Y- + uint8_t tap_right : 1; // X+ + uint8_t tap_left : 1; // X- + uint8_t reserved_one : 1; + uint8_t reserved_two : 1; } sfe_kx13x_ins1_t; #define SFE_KX13X_INS2 0x17 // Reports which function caused an interrupt typedef struct { - uint8_t ffs : 1; // Free fall - uint8_t bfi : 1; // Buffer full - uint8_t wmi : 1; // Watermark - uint8_t drdy : 1; // Data Ready - uint8_t tdts : 2; // Tap/Double Tap - uint8_t reserved : 1; - uint8_t tps : 1; // Tilt Position + uint8_t tps : 1; // Tilt Position + uint8_t reserved : 1; + uint8_t tdts : 2; // Tap/Double Tap + uint8_t drdy : 1; // Data Ready + uint8_t wmi : 1; // Watermark + uint8_t bfi : 1; // Buffer full + uint8_t ffs : 1; // Free fall } sfe_kx13x_ins2_t; +typedef union +{ + uint8_t all; + sfe_kx13x_ins2_t bits; +} sfe_kx13x_ins2_bitfield_t; + #define SFE_KX13X_INS3 0x18 // Reports which axis and direction of detected motion triggered the wakeup interrupt typedef struct { - uint8_t wufs : 1; - uint8_t bts : 1; - uint8_t xnwu : 1; //X- - uint8_t xpwu : 1; //X+ - uint8_t ynwu : 1; //Y- - uint8_t ypwu : 1; //Y+ - uint8_t znwu : 1; //Z- - uint8_t zpwu : 1; //Z+ + uint8_t zpwu : 1; // Z+ + uint8_t znwu : 1; // Z- + uint8_t ypwu : 1; // Y+ + uint8_t ynwu : 1; // Y- + uint8_t xpwu : 1; // X+ + uint8_t xnwu : 1; // X- + uint8_t bts : 1; + uint8_t wufs : 1; } sfe_kx13x_ins3_t; -#define SFE_KX13X_STATUS_REG 0x19 +#define SFE_KX13X_STATUS_REG 0x19 // Reports the combined status of the interrupts and the wake/back to sleep state typedef struct { - uint8_t reserved_one : 3; - uint8_t combined_int : 1; - uint8_t reserved_two : 3; - uint8_t wake : 1; + uint8_t wake : 1; + uint8_t reserved_one : 3; + uint8_t combined_int : 1; + uint8_t reserved_two : 3; } sfe_kx13x_status_reg_t; -#define SFE_KX13X_INT_REL 0x1A +#define SFE_KX13X_INT_REL 0x1A // Interrupt latch release: when an interrupt is flipped read this status to clear -// interrupt. +// interrupt. typedef struct { - uint8_t latch_release : 8; + uint8_t latch_release : 8; } sfe_kx13x_int_rel_t; #define SFE_KX13X_CNTL1 0x1B // Read/write control register that controls the "main feature" set. // To change these values PC1 (bit 8) must be set to zero (stand-by mode). +// Default value: 0b00000000 typedef struct { - uint8_t pc1 : 1; - uint8_t res : 1; - uint8_t drdye : 1; - uint8_t gsel : 2; - uint8_t tdte : 1; - uint8_t reserved_one : 1; - uint8_t tpe : 1; + uint8_t tpe : 1; + uint8_t reserved_one : 1; + uint8_t tdte : 1; + uint8_t gsel : 2; + uint8_t drdye : 1; + uint8_t res : 1; + uint8_t pc1 : 1; } sfe_kx13x_cntl1_t; +typedef union +{ + uint8_t all; + sfe_kx13x_cntl1_t bits; +} sfe_kx13x_cntl1_bitfield_t; + #define SFE_KX13X_CNTL2 0x1C // Read/Write control register that controls tilt position state enabling // Default value: 0b00111111 typedef struct { - uint8_t srst : 1; //Software reset - uint8_t cotc : 1; //Command Test Control bit - // The following bits control when an interrupt is generated - // for tilt: 1 = enabled - uint8_t lem : 1; // Left state (X-) - uint8_t rim : 2; // Right state (X+) - uint8_t dom : 1; // Down state (Y-) - uint8_t upm : 1; // Up state (Y+) - uint8_t fdm : 1; // Face-Down state (Z-) - uint8_t fum : 1; // Face-Up state (Z+) + uint8_t fum : 1; // Face-Up state (Z+) + uint8_t fdm : 1; // Face-Down state (Z-) + uint8_t upm : 1; // Up state (Y+) + uint8_t dom : 1; // Down state (Y-) + uint8_t rim : 1; // Right state (X+) + uint8_t lem : 1; // Left state (X-) + uint8_t cotc : 1; // Command Test Control bit + // The following bits control when an interrupt is generated + // for tilt: 1 = enabled + uint8_t srst : 1; // Software reset } sfe_kx13x_cntl2_t; +typedef union +{ + uint8_t all; + sfe_kx13x_cntl2_t bits; +} sfe_kx13x_cntl2_bitfield_t; + #define SFE_KX13X_CNTL3 0x1D // Read/Write control register that provides control of the Output Data Rate (ODR) // for tilt, tap, wake-up registers. typedef struct { - uint8_t opt : 2; // ODR tilt position - uint8_t otdt : 3; // ODR tap/double-tap - uint8_t owuf : 3; // ORR wake-up + uint8_t owuf : 3; // ORR wake-up + uint8_t otdt : 3; // ODR tap/double-tap + uint8_t otp : 2; // ODR tilt position } sfe_kx13x_cntl3_t; +typedef union +{ + uint8_t all; + sfe_kx13x_cntl3_t bits; +} sfe_kx13x_cntl3_bitfield_t; + #define SFE_KX13X_CNTL4 0x1E // Read/write control register that provides more feature set control. // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t c_mode : 1; - uint8_t th_mode : 1; - uint8_t wufe : 1; - uint8_t btse : 1; - uint8_t pr_mode : 1; - uint8_t obts : 3; + uint8_t obts : 3; + uint8_t pr_mode : 1; + uint8_t btse : 1; + uint8_t wufe : 1; + uint8_t th_mode : 1; + uint8_t c_mode : 1; } sfe_kx13x_cntl4_t; +typedef union +{ + uint8_t all; + sfe_kx13x_cntl4_t bits; +} sfe_kx13x_cntl4_bitfield_t; + #define SFE_KX13X_CNTL5 0x1F -// Read/Write control register that providers more feature set control. +// Read/Write control register that providers more feature set control. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t reserved_one : 3; - uint8_t adpe : 1; - uint8_t reserved_two : 2; - uint8_t man_wake : 1; - uint8_t man_sleep : 1; + uint8_t man_sleep : 1; + uint8_t man_wake : 1; + uint8_t reserved_one : 2; + uint8_t adpe : 1; + uint8_t reserved_two : 3; } sfe_kx13x_cntl5_t; +typedef union +{ + uint8_t all; + sfe_kx13x_cntl5_t bits; +} sfe_kx13x_cntl5_bitfield_t; + #define SFE_KX13X_CNTL6 0x20 -// Read/Write control register that providers more feature set control. +// Read/Write control register that providers more feature set control. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t i2c_ale : 1; - uint8_t reserved_one : 5; - uint8_t i2c_alc : 2; + uint8_t i2c_alc : 2; + uint8_t reserved_one : 5; + uint8_t i2c_ale : 1; } sfe_kx13x_cntl6_t; #define SFE_KX13X_ODCNTL 0x21 -// Control registers that contorls acceleration outputs. +// Control registers that contorls acceleration outputs. // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t reserved_one : 1; - uint8_t lpro : 1; // 0 - Filter ODR/9 : 1 - Filter ODR/2 - uint8_t fstup : 1; - uint8_t reserved_two : 1; - uint8_t osa : 4; + uint8_t osa : 4; + uint8_t reserved_one : 1; + uint8_t fstup : 1; + uint8_t lpro : 1; // 0 - Filter ODR/9 : 1 - Filter ODR/2 + uint8_t iir_bypass : 1; } sfe_kx13x_odcntl_t; +typedef union +{ + uint8_t all; + sfe_kx13x_odcntl_t bits; +} sfe_kx13x_odcntl_bitfield_t; + #define SFE_KX13X_INC1 0x22 -// Controls settings for physical interrupt pin +// Controls settings for physical interrupt pin // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t pw1 : 2; - uint8_t ien1 : 1; // Enable/disable physical interrupt pin - uint8_t iea1 : 1; // Interrupt active level control, 0 - LOW : 1 - HIGH - uint8_t iel1 : 1; // Interrupt lactch control, 0 - latched : 1 - pulsed - uint8_t reserved_one : 1; - uint8_t stpol : 1; - uint8_t spi3e : 1; + uint8_t spi3e : 1; + uint8_t stpol : 1; + uint8_t reserved_one : 1; + uint8_t iel1 : 1; // Interrupt lactch control, 0 - latched : 1 - pulsed + uint8_t iea1 : 1; // Interrupt active level control, 0 - LOW : 1 - HIGH + uint8_t ien1 : 1; // Enable/disable physical interrupt pin + uint8_t pw1 : 2; } sfe_kx13x_inc1_t; - + +typedef union +{ + uint8_t all; + sfe_kx13x_inc1_t bits; +} sfe_kx13x_inc1_bitfield_t; + #define SFE_KX13X_INC2 0x23 // Defines behavior for Wake-Up Function and Back To Sleep // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t reserved_one : 1; - uint8_t aoi : 1; - uint8_t xnwue : 1; //X- - uint8_t xpwue : 1; //X+ - uint8_t ynwue : 1; //Y- - uint8_t ypwue : 1; //Y+ - uint8_t znwue : 1; //Z- - uint8_t zpwue : 1; //Z+ + uint8_t zpwue : 1; // Z+ + uint8_t znwue : 1; // Z- + uint8_t ypwue : 1; // Y+ + uint8_t ynwue : 1; // Y- + uint8_t xpwue : 1; // X+ + uint8_t xnwue : 1; // X- + uint8_t aoi : 1; + uint8_t reserved_one : 1; } sfe_kx13x_inc2_t; #define SFE_KX13X_INC3 0x24 @@ -351,146 +400,170 @@ typedef struct // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t undefined : 1; - uint8_t tmen : 1; // Alternate masking scheme - uint8_t tlem : 1; //X- - uint8_t trim : 1; //X+ - uint8_t tdom : 1; //Y- - uint8_t tpum : 1; //Y+ - uint8_t tfdm : 1; //Z- - uint8_t tfum : 1; //Z+ + uint8_t tfum : 1; // Z+ + uint8_t tfdm : 1; // Z- + uint8_t tupm : 1; // Y+ + uint8_t tdom : 1; // Y- + uint8_t trim : 1; // X+ + uint8_t tlem : 1; // X- + uint8_t tmen : 1; // Alternate masking scheme + uint8_t undefined : 1; } sfe_kx13x_inc3_t; -#define SFE_KX13X_INC4 0x25 +#define SFE_KX13X_INC4 0x25 // Controls which function triggers INT1 // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t ffi1 : 1; - uint8_t bfi1 : 1; - uint8_t wmi1 : 1; - uint8_t drdyi1 : 1; - uint8_t btsi1 : 1; - uint8_t tdti1 : 1; - uint8_t wufi1 : 1; - uint8_t tpi1 : 1; + uint8_t tpi1 : 1; + uint8_t wufi1 : 1; + uint8_t tdti1 : 1; + uint8_t btsi1 : 1; + uint8_t drdyi1 : 1; + uint8_t wmi1 : 1; + uint8_t bfi1 : 1; + uint8_t ffi1 : 1; } sfe_kx13x_inc4_t; +typedef union +{ + uint8_t all; + sfe_kx13x_inc4_t bits; +} sfe_kx13x_inc4_bitfield_t; + #define SFE_KX13X_INC5 0x26 // Controls the settings for the physical interrupt pin INT2. // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t pw2 : 2; - uint8_t ien2 : 1; - uint8_t iea2 : 1; - uint8_t iel2 : 1; - uint8_t reserved_one : 1; - uint8_t aclr2 : 1; - uint8_t aclr1 : 1; + uint8_t aclr1 : 1; + uint8_t aclr2 : 1; + uint8_t reserved_one : 1; + uint8_t iel2 : 1; + uint8_t iea2 : 1; + uint8_t ien2 : 1; + uint8_t pw2 : 2; } sfe_kx13x_inc5_t; +typedef union +{ + uint8_t all; + sfe_kx13x_inc5_t bits; +} sfe_kx13x_inc5_bitfield_t; + #define SFE_KX13X_INC6 0x27 // Controls which function triggers INT2 // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t ffi2 : 1; - uint8_t bfi2 : 1; - uint8_t wmi2 : 1; - uint8_t drdyi2 : 1; - uint8_t btsi2 : 1; - uint8_t tdti2 : 1; - uint8_t wufi2 : 1; - uint8_t tpi2 : 1; + uint8_t tpi2 : 1; + uint8_t wufi2 : 1; + uint8_t tdti2 : 1; + uint8_t btsi2 : 1; + uint8_t drdyi2 : 1; + uint8_t wmi2 : 1; + uint8_t bfi2 : 1; + uint8_t ffi2 : 1; } sfe_kx13x_inc6_t; -#define SFE_KX13X_TILT_TIMER 0x29 +typedef union +{ + uint8_t all; + sfe_kx13x_inc6_t bits; +} sfe_kx13x_inc6_bitfield_t; + +#define SFE_KX13X_TILT_TIMER 0x29 // Initial Count Registers for the tilt position state time (0 to 255 counts) // Count is calculated as 1/ODR // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t tsc : 8; + uint8_t tsc : 8; } sfe_kx13x_tilt_timer_t; -#define SFE_KX13X_TDTRC 0x2A +#define SFE_KX13X_TDTRC 0x2A // Double tap report control // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t undefined : 6; - uint8_t dtre : 1; - uint8_t stre : 1; + uint8_t stre : 1; + uint8_t dtre : 1; + uint8_t undefined : 6; } sfe_kx13x_tdtrc_t; +typedef union +{ + uint8_t all; + sfe_kx13x_tdtrc_t bits; +} sfe_kx13x_tdtrc_bitfield_t; + #define SFE_KX13X_TDTC 0x2B -// Double tap time counter - see datashet for more specifics. +// Double tap time counter - see datashet for more specifics. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t tdtc : 8; + uint8_t tdtc : 8; } sfe_kx13x_tdtc_t; #define SFE_KX13X_TTH 0x2C -// Double tap "jerk high" threshold to determine if a tap is detected. +// Double tap "jerk high" threshold to determine if a tap is detected. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t tth : 8; + uint8_t tth : 8; } sfe_kx13x_tth_t; #define SFE_KX13X_TTL 0x2D -// Double tap "jerk low" threshold to determine if a tap is detected. +// Double tap "jerk low" threshold to determine if a tap is detected. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t ttl : 8; + uint8_t ttl : 8; } sfe_kx13x_ttl_t; #define SFE_KX13X_FTD 0x2E -// This register contains counter information for any single tap event. +// This register contains counter information for any single tap event. // These settings can be changed on the fly - no need to put IC in stand-by. // Check datasheet for conversion information. typedef struct { - uint8_t ftdh : 5; //Default high limit is .05 seconds - uint8_t ftdl : 3; //Default low limits is .05 seconds + uint8_t ftdl : 3; // Default low limits is .05 seconds + uint8_t ftdh : 5; // Default high limit is .05 seconds } sfe_kx13x_ftd_t; #define SFE_KX13X_STD 0x2F -// This register contains counter information for any double tap event. +// This register contains counter information for any double tap event. // These settings can be changed on the fly - no need to put IC in stand-by. // Check datasheet for conversion information. typedef struct { - uint8_t std: 8; + uint8_t std : 8; } sfe_kx13x_std_t; #define SFE_KX13X_TLT 0x30 -// This register contains counter information for a tap event. +// This register contains counter information for a tap event. // These settings can be changed on the fly - no need to put IC in stand-by. // Check datasheet for conversion information. typedef struct { - uint8_t tlt : 8; + uint8_t tlt : 8; } sfe_kx13x_tlt_t; #define SFE_KX13X_TWS 0x31 -// This register contains counter information for of single and double taps. +// This register contains counter information for of single and double taps. // These settings can be changed on the fly - no need to put IC in stand-by. // Check datasheet for conversion information. typedef struct { - uint8_t tws : 8; + uint8_t tws : 8; } sfe_kx13x_tws_t; #define SFE_KX13X_FFTH 0x32 -// This register configures the threshold for free fall detection. +// This register configures the threshold for free fall detection. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t ffth : 8; + uint8_t ffth : 8; } sfe_kx13x_ffth_t; #define SFE_KX13X_FFC 0x33 @@ -498,20 +571,20 @@ typedef struct // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t ffc : 8; + uint8_t ffc : 8; } sfe_kx13x_ffc_t; #define SFE_KX13X_FFCNTL 0x34 -// This register configures the "main control" of the free fall engine i.e. -// engine enable, free fall latch, debouce, etc. +// This register configures the "main control" of the free fall engine i.e. +// engine enable, free fall latch, debouce, etc. // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t ffie : 1; - uint8_t ulmode : 1; - uint8_t ffdc : 2; - uint8_t dcrm : 1; - uint8_t offl : 3; + uint8_t offi : 3; + uint8_t dcrm : 1; + uint8_t ffdc : 2; + uint8_t ulmode : 1; + uint8_t ffie : 1; } sfe_kx13x_ffcntl_t; #define SFE_KX13X_TILT_ANGLE_LL 0x37 @@ -519,7 +592,7 @@ typedef struct // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t ll : 8; + uint8_t ll : 8; } sfe_kx13x_ll_t; #define SFE_KX13X_TILT_ANGLE_HL 0x38 @@ -527,67 +600,67 @@ typedef struct // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t hl : 8; + uint8_t hl : 8; } sfe_kx13x_hl_t; #define SFE_KX13X_HYST_SET 0x39 -// This register sets hysteresis that is placed in between the Screen Rotation states. +// This register sets hysteresis that is placed in between the Screen Rotation states. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t reserved : 2; - uint8_t hyst : 6; + uint8_t hyst : 6; + uint8_t reserved : 2; } sfe_kx13x_hyst_t; #define SFE_KX13X_LP_CNTL1 0x3A // This register sets the Averging Filter Contrl which determines both - // the number of internal aceleration samples to be averaged in low power mode -// and the number of internal acceleration samples to be averaged for digital engines +// and the number of internal acceleration samples to be averaged for digital engines // operation: tap, double tap. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t reserved_one : 1; - uint8_t avc : 3; - uint8_t reserved_two : 4; + uint8_t reserved_one : 4; + uint8_t avc : 3; + uint8_t reserved_two : 1; } sfe_kx13x_lp_cntl1_t; #define SFE_KX13X_LP_CNTL2 0x3B -// This register controls the advanced low power settings which can reduce +// This register controls the advanced low power settings which can reduce // the power consumption even more than low power and stand-by modes. // To change these settings make sure IC is in "stand-by" mode: PC1 bit in CNTL1. typedef struct { - uint8_t reserved : 7; - uint8_t lpstpsel : 1; + uint8_t lpstpsel : 1; + uint8_t reserved : 7; } sfe_kx13x_lpcntl2_t; #define SFE_KX13X_WUFTH 0x49 -// This register sets seven of the ten bits for the wake up threshold. +// This register sets seven of the ten bits for the wake up threshold. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t wufth : 8; + uint8_t wufth : 8; } sfe_kx13x_wufth_t; #define SFE_KX13X_BTSWUFTH 0x4A -// This register contains final three of the ten bits of the back to sleep the threshold and -// the final three of ten bits of the wakup threshold. +// This register contains final three of the ten bits of the back to sleep the threshold and +// the final three of ten bits of the wakup threshold. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t undefined_one : 1; - uint8_t btsth : 3; - uint8_t undefined_two : 1; - uint8_t wufth : 3; + uint8_t wufth : 3; + uint8_t undefined_one : 1; + uint8_t btsth : 3; + uint8_t undefined_two : 1; } sfe_kx13x_btswufth_t; #define SFE_KX13X_BTSTH 0x4B -// This register sets seven of the ten bits for the back to sleep threshold. +// This register sets seven of the ten bits for the back to sleep threshold. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t btsth : 8; + uint8_t btsth : 8; } sfe_kx13x_btsth_t; #define SFE_KX13X_BTSC 0x4C @@ -595,7 +668,7 @@ typedef struct // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t btsc : 8; + uint8_t btsc : 8; } sfe_kx13x_btsc_t; #define SFE_KX13X_WUFC 0x4D @@ -603,7 +676,7 @@ typedef struct // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t wufc : 8; + uint8_t wufc : 8; } sfe_kx13x_wufc_t; #define SFE_KX13X_SELF_TEST 0x5D @@ -611,181 +684,187 @@ typedef struct // Check datasheet for more information. typedef struct { - uint8_t self_test : 8; + uint8_t self_test : 8; } sfe_kx13x_self_test_t; #define SFE_KX13X_BUF_CNTL1 0x5E -// This register controls the buffer sample threshold. +// This register controls the buffer sample threshold. // The total samples set in this register is dependent on the "BRES" bits in // BUF_CNTL2. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t smp_th : 8; + uint8_t smp_th : 8; } sfe_kx13x_buf_cntl1_t; #define SFE_KX13X_BUF_CNTL2 0x5F -// This register controls the buffer sample operation. +// This register controls the buffer sample operation. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t bufe : 1; // Activation of sample buffer - uint8_t bres : 1; // Resolution - 8 or 16 bit samples - uint8_t bfie : 1; // Full interrupt enable bit - uint8_t undefined : 3; - uint8_t bm : 2; //FIFO, Stream, Trigger + uint8_t bm : 2; // FIFO, Stream, Trigger + uint8_t undefined : 3; + uint8_t bfie : 1; // Full interrupt enable bit + uint8_t bres : 1; // Resolution - 8 or 16 bit samples + uint8_t bufe : 1; // Activation of sample buffer } sfe_kx13x_buf_cntl2_t; +typedef union +{ + uint8_t all; + sfe_kx13x_buf_cntl2_t bits; +} sfe_kx13x_buf_cntl2_bitfield_t; + #define SFE_KX13X_BUF_STATUS_1 0x60 -// The buffer status registers (buff status one and two) report the number of +// The buffer status registers (buff status one and two) report the number of // data bytes in the sample buffer. // The smp_lev word is 10 bits, you can find the remaining three bits in buf_status2. typedef struct { - uint8_t smp_lev : 8; + uint8_t smp_lev : 8; } sfe_kx13x_buf_status1_t; #define SFE_KX13X_BUF_STATUS_2 0x61 -// The buffer status registers (buf_status_1/2) report the number of +// The buffer status registers (buf_status_1/2) report the number of // data bytes in the sample buffer. -// The smp_lev word is 10 bits, you can find the remaining first seven bits in +// The smp_lev word is 10 bits, you can find the remaining first seven bits in // buf_status1. typedef struct { - uint8_t buf_trig : 1; - uint8_t undefined : 5; - uint8_t smp_lev : 2; + uint8_t smp_lev : 2; + uint8_t undefined : 5; + uint8_t buf_trig : 1; } sfe_kx13x_buf_status2_t; #define SFE_KX13X_BUF_CLEAR 0x62 -// This register clears the sample level bits found in the previous buf_status_1/2 +// This register clears the sample level bits found in the previous buf_status_1/2 // register. This can be done by writing anything to this register. // These settings can be changed on the fly - no need to put IC in stand-by. typedef struct { - uint8_t buf_clear : 8; + uint8_t buf_clear : 8; } sfe_kx13x_buf_clear_t; #define SFE_KX13X_BUF_READ 0x63 // Buffer Output Register, data is in 2's copmlement format typedef struct { - uint8_t buf_read : 8; + uint8_t buf_read : 8; } sfe_kx13x_buf_read_t; #define SFE_KX13X_ADP_CNTL1 0x64 // This register sets the ODR of the Advanced Data Path and number of samples -// used to calculate RMS output. -typedef struct +// used to calculate RMS output. +typedef struct { - uint8_t reserved : 1; - uint8_t rms_avc : 3; - uint8_t oadp : 3; + uint8_t oadp : 4; + uint8_t rms_avc : 3; + uint8_t reserved : 1; } sfe_kx13x_adp_cntl1_t; #define SFE_KX13X_ADP_CNTL2 0x65 // This register controls route of data path, wake-up/back-to-sleep, -// filter bypass amongst others. -typedef struct -{ - uint8_t adp_buf_sel : 1; - uint8_t adp_wb_isel : 1; - uint8_t rms_wb_osel : 1; - uint8_t adp_flt2_byp : 1; - uint8_t adp_flt1_byp : 1; - uint8_t undefined : 1; - uint8_t adp_rms_osel : 1; - uint8_t adp_f2_hp : 1; +// filter bypass amongst others. +typedef struct +{ + uint8_t adp_f2_hp : 1; + uint8_t adp_rms_osel : 1; + uint8_t undefined : 1; + uint8_t adp_flt1_byp : 1; + uint8_t adp_flt2_byp : 1; + uint8_t rms_wb_osel : 1; + uint8_t adp_wb_isel : 1; + uint8_t adp_buf_sel : 1; } sfe_kx13x_adp_cntl2_t; #define SFE_KX13X_ADP_CNTL3 0x66 // Sets ADP filter-1 coefficient (1/A) -typedef struct +typedef struct { - uint8_t adp_f1_1a : 8; + uint8_t adp_f1_1a : 8; } sfe_kx13x_adp_cntl3_t; #define SFE_KX13X_ADP_CNTL4 0x67 // Sets the ADP filter-1 coefficient (B/A) // Bits [7:0] -typedef struct +typedef struct { - uint8_t adp_f1_ba : 8; + uint8_t adp_f1_ba : 8; } sfe_kx13x_adp_cntl4_t; #define SFE_KX13X_ADP_CNTL5 0x68 // Sets the ADP filter-1 coefficient (B/A) // Bits [15:8] -typedef struct +typedef struct { - uint8_t adp_f1_ba : 8; + uint8_t adp_f1_ba : 8; } sfe_kx13x_adp_cntl5_t; #define SFE_KX13X_ADP_CNTL6 0x69 // Sets the ADP filter-1 coefficient (B/A) // Bits [22:16] -typedef struct +typedef struct { - uint8_t undefined : 1; - uint8_t adp_f1_ba : 7; + uint8_t adp_f1_ba : 7; + uint8_t undefined : 1; } sfe_kx13x_adp_cntl6_t; #define SFE_KX13X_ADP_CNTL7 0x6A // Sets the ADP filter-1 coefficient (C/A) // Bits [7:0] -typedef struct +typedef struct { - uint8_t adp_f1_ca : 8; + uint8_t adp_f1_ca : 8; } sfe_kx13x_adp_cntl7_t; #define SFE_KX13X_ADP_CNTL8 0x6B // Sets the ADP filter-1 coefficient (C/A) // Bits [15:8] -typedef struct +typedef struct { - uint8_t adp_f1_ca : 8; + uint8_t adp_f1_ca : 8; } sfe_kx13x_adp_cntl8_t; #define SFE_KX13X_ADP_CNTL9 0x6C // Sets the ADP filter-1 coefficient (C/A) // Bits [22:16] -typedef struct +typedef struct { - uint8_t undefined : 1; - uint8_t adp_f1_ca : 7; + uint8_t adp_f1_ca : 7; + uint8_t undefined : 1; } sfe_kx13x_adp_cntl9_t; #define SFE_KX13X_ADP_CNTL10 0x6D // Sets the ADP filter-1 input scale shift -typedef struct +typedef struct { - uint8_t undefined : 3; - uint8_t adp_f1_ish : 5; + uint8_t adp_f1_ish : 5; + uint8_t undefined : 3; } sfe_kx13x_adp_cntl10_t; #define SFE_KX13X_ADP_CNTL11 0x6E // Sets the ADP filter-2 coefficient (1/A) -typedef struct +typedef struct { - uint8_t adp_f2_osh : 1; - uint8_t adp_f2_1a : 7; + uint8_t adp_f2_1a : 7; + uint8_t adp_f1_osh : 1; } sfe_kx13x_adp_cntl11_t; #define SFE_KX13X_ADP_CNTL12 0x6F // Sets the ADP filter-2 coefficient (B/A) // Bits [7:0] -typedef struct +typedef struct { - uint8_t adp_f2_ba : 1; + uint8_t adp_f2_ba : 8; } sfe_kx13x_adp_cntl12_t; #define SFE_KX13X_ADP_CNTL13 0x70 // Sets the ADP filter-2 coefficient (B/A) // Bits [14:8] -typedef struct +typedef struct { - uint8_t undefined : 1; - uint8_t adp_f2_ba : 1; + uint8_t adp_f2_ba : 7; + uint8_t undefined : 1; } sfe_kx13x_adp_cntl13_t; //---------------------------------- Set to Zero by Manufacturer vv ---- @@ -797,24 +876,23 @@ typedef struct #define SFE_KX13X_ADP_CNTL18 0x75 // Sets the ADP filter-2 input scale shift -typedef struct +typedef struct { - uint8_t undefined : 3; - uint8_t adp_f1_ish : 5; + uint8_t adp_f2_ish : 5; + uint8_t undefined : 3; } sfe_kx13x_adp_cntl18_t; #define SFE_KX13X_ADP_CNTL19 0x76 // Sets the ADP filter-2 output scale shift -typedef struct +typedef struct { - uint8_t undefined : 3; - uint8_t adp_f1_osh : 5; + uint8_t adp_f2_osh : 5; + uint8_t undefined : 3; } sfe_kx13x_adp_cntl19_t; typedef struct { - uint8_t SFE_KX13X_SUCCESS = 0x00; + uint8_t SFE_KX13X_SUCCESS = 0x00; uint8_t SFE_KX13X_GENERAL_ERROR = 0x01; uint8_t SFE_KX13X_I2C_ERROR = 0x03; } sfe_error_code_t; - diff --git a/src/SparkFun_Qwiic_KX13X.cpp b/src/SparkFun_Qwiic_KX13X.cpp index 47d6c92..51e92dc 100644 --- a/src/SparkFun_Qwiic_KX13X.cpp +++ b/src/SparkFun_Qwiic_KX13X.cpp @@ -1,15 +1,14 @@ #include "SparkFun_Qwiic_KX13X.h" - uint8_t QwDevKX13X::getUniqueID() { - uint8_t tempVal; - int retVal = readRegisterRegion(SFE_KX13X_WHO_AM_I, &tempVal, 1); + uint8_t tempVal; + int retVal = readRegisterRegion(SFE_KX13X_WHO_AM_I, &tempVal, 1); - if( retVal != 0 ) - return 0; + if (retVal != 0) + return 0; - return tempVal; + return tempVal; } //////////////////////////////////////////////////////////////////////////////////// @@ -17,13 +16,13 @@ uint8_t QwDevKX13X::getUniqueID() // // Method to set the bus object that is used to communicate with the device // -// Parameter: +// Parameter: // theBus-The communication bus object // i2cAddress-I2C address for the 6DoF -void QwDevKX13X::setCommunicationBus(QwIDeviceBus &theBus, uint8_t i2cAddress) +void QwDevKX13X::setCommunicationBus(sfe_KX13X::QwIDeviceBus &theBus, uint8_t i2cAddress) { - _sfeBus = &theBus; - _i2cAddress = i2cAddress; + _sfeBus = &theBus; + _i2cAddress = i2cAddress; } //////////////////////////////////////////////////////////////////////////////////// @@ -33,10 +32,10 @@ void QwDevKX13X::setCommunicationBus(QwIDeviceBus &theBus, uint8_t i2cAddress) // // Parameter: // theBus-The communication bus object -// -void QwDevKX13X::setCommunicationBus(QwIDeviceBus &theBus) +// +void QwDevKX13X::setCommunicationBus(sfe_KX13X::QwIDeviceBus &theBus) { - _sfeBus = &theBus; + _sfeBus = &theBus; } // This function sets various register with regards to these pre-determined @@ -45,36 +44,34 @@ void QwDevKX13X::setCommunicationBus(QwIDeviceBus &theBus) bool QwDevKX13X::initialize(uint8_t settings) { - int retVal; + int retVal = 0; + + if (!enableAccel(true)) + return false; - if( !enableAccel(true) ) - return false; - - - if( settings == DEFAULT_SETTINGS ) + if (settings == DEFAULT_SETTINGS) retVal = writeRegisterByte(SFE_KX13X_CNTL1, DEFAULT_SETTINGS); - if( settings == INT_SETTINGS ) - { + if (settings == INT_SETTINGS) + { enablePhysInterrupt(); routeHardwareInterrupt(0x10); retVal = writeRegisterByte(SFE_KX13X_CNTL1, INT_SETTINGS); } - if( settings == BUFFER_SETTINGS ) - { + if (settings == BUFFER_SETTINGS) + { enablePhysInterrupt(); - routeHardwareInterrupt(0x40);//Buffer full interrupt - enableSampleBuffer(); //Enable buffer - setBufferOperationMode(0x00); //FIFO + routeHardwareInterrupt(0x40); // Buffer full interrupt + enableSampleBuffer(); // Enable buffer + setBufferOperationMode(0x00); // FIFO retVal = writeRegisterByte(SFE_KX13X_CNTL1, INT_SETTINGS); } - - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } ////////////////////////////////////////////////// @@ -85,29 +82,31 @@ bool QwDevKX13X::initialize(uint8_t settings) bool QwDevKX13X::softwareReset() { - uint8_t reset = 0x80; + sfe_kx13x_cntl2_bitfield_t cntl2; + cntl2.all = 0; + cntl2.bits.srst = 1; // This is a long winded, but definitive way of setting the software reset bit + int retVal; - retVal = writeRegisterByte(SFE_KX13X_CNTL2, reset); - - // Logic is inverted here - if we reset using I2C the - // accelerometer immediately shuts off which results - // in a NACK. - if( retVal != 0 ) - return true; + retVal = writeRegisterByte(SFE_KX13X_CNTL2, cntl2.all); - return false; + // Logic is inverted here - if we reset using I2C the + // accelerometer immediately shuts off which results + // in a NACK. + if (retVal != 0) + return true; + return false; } ////////////////////////////////////////////////// // enableAccel() // // Enables acceleromter data. In addition -// some settings can only be set when the accelerometer is +// some settings can only be set when the accelerometer is // powered down // -// Parameter: +// Parameter: // enable - enables or disables the accelerometer // // @@ -120,18 +119,20 @@ bool QwDevKX13X::enableAccel(bool enable) retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - tempVal = (tempVal | (enable << 7)); + sfe_kx13x_cntl1_bitfield_t cntl1; + cntl1.all = tempVal; + cntl1.bits.pc1 = enable; // This is a long winded but definitive way of setting/clearing the operating mode bit + tempVal = cntl1.all; retVal = writeRegisterByte(SFE_KX13X_CNTL1, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; - + return true; } ////////////////////////////////////////////////// @@ -140,18 +141,21 @@ bool QwDevKX13X::enableAccel(bool enable) // Retrieves the current operating mode - low/high power mode // -int8_t QwDevKX13X::getOperatingMode(){ +int8_t QwDevKX13X::getOperatingMode() +{ uint8_t tempVal; - int retVal; + int retVal; retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); - if( retVal != 0 ) - return retVal; + if (retVal != 0) + return retVal; - return (tempVal >> 7); + sfe_kx13x_cntl1_bitfield_t cntl1; + cntl1.all = tempVal; // This is a long winded but definitive way of getting the operating mode bit + return (cntl1.bits.pc1); // Return the operating mode bit } ////////////////////////////////////////////////// @@ -161,52 +165,65 @@ int8_t QwDevKX13X::getOperatingMode(){ // // Parameter: // range - sets the range of the accelerometer 2g - 32g depending -// on the version. +// on the version. 8g - 64g for the KX134. // bool QwDevKX13X::setRange(uint8_t range) { - int retVal; + uint8_t tempVal; + int retVal; - if( range > 3 ) + if (range > SFE_KX132_RANGE16G) // Same as SFE_KX134_RANGE64G return false; - retVal = writeRegisterByte(SFE_KX13X_CNTL1, range); + // Read - Modify - Write + retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; - + sfe_kx13x_cntl1_bitfield_t cntl1; + cntl1.all = tempVal; + cntl1.bits.gsel = range; // This is a long winded but definitive way of setting the range (g select) + tempVal = cntl1.all; + + retVal = writeRegisterByte(SFE_KX13X_CNTL1, tempVal); + + if (retVal != 0) + return false; + + return true; } ////////////////////////////////////////////////// // enableDataEngine() // -// Enables the data ready bit. +// Enables the data ready bit. // // Parameter: -// enable - enable/disables the data ready bit. +// enable - enable/disables the data ready bit. // bool QwDevKX13X::enableDataEngine(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | (enable << 5); + + sfe_kx13x_cntl1_bitfield_t cntl1; + cntl1.all = tempVal; + cntl1.bits.drdye = enable; // This is a long winded but definitive way of setting/clearing the data ready engine bit + tempVal = cntl1.all; retVal = writeRegisterByte(SFE_KX13X_CNTL1, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - - return true; + return true; } ////////////////////////////////////////////////// @@ -219,111 +236,120 @@ bool QwDevKX13X::enableDataEngine(bool enable) // bool QwDevKX13X::enableTapEngine(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | (enable << 2); + + sfe_kx13x_cntl1_bitfield_t cntl1; + cntl1.all = tempVal; + cntl1.bits.tdte = enable; // This is a long winded but definitive way of setting/clearing the tap engine bit + tempVal = cntl1.all; retVal = writeRegisterByte(SFE_KX13X_CNTL1, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } - ////////////////////////////////////////////////// // enableTiltEngine() // -// Enables the tilt detection feature. +// Enables the tilt detection feature. // // Parameter: // enable - enables the tilt feature // bool QwDevKX13X::enableTiltEngine(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | enable; + + sfe_kx13x_cntl1_bitfield_t cntl1; + cntl1.all = tempVal; + cntl1.bits.tpe = enable; // This is a long winded but definitive way of setting/clearing the tilt engine bit + tempVal = cntl1.all; retVal = writeRegisterByte(SFE_KX13X_CNTL1, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } - ////////////////////////////////////////////////// // enableWakeEngine() // -// Enables the wake detection feature. +// Enables the wake detection feature. // // Parameter: // enable - enables/disables the wake detection feature // bool QwDevKX13X::enableWakeEngine(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL4, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL4, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | (enable << 5); + + sfe_kx13x_cntl4_bitfield_t cntl4; + cntl4.all = tempVal; + cntl4.bits.wufe = enable; // This is a long winded but definitive way of setting/clearing the wake-up engine bit + tempVal = cntl4.all; retVal = writeRegisterByte(SFE_KX13X_CNTL4, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } ////////////////////////////////////////////////// // enableSleepEngine() // -// Enables the sleep feature. +// Enables the sleep feature. // // Parameter: // enable - enables/disables the sleep feature // bool QwDevKX13X::enableSleepEngine(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL4, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL4, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | (enable << 4); + + sfe_kx13x_cntl4_bitfield_t cntl4; + cntl4.all = tempVal; + cntl4.bits.btse = enable; // This is a long winded but definitive way of setting/clearing the back-to-sleep engine bit + tempVal = cntl4.all; retVal = writeRegisterByte(SFE_KX13X_CNTL4, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } - ////////////////////////////////////////////////// // setOutputDataRate() // @@ -335,25 +361,28 @@ bool QwDevKX13X::enableSleepEngine(bool enable) bool QwDevKX13X::setOutputDataRate(uint8_t rate) { - if( rate > 15 ) + if (rate > 15) return false; - uint8_t tempVal; + uint8_t tempVal; int retVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL1, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_ODCNTL, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | rate; + + sfe_kx13x_odcntl_bitfield_t odcntl; + odcntl.all = tempVal; + odcntl.bits.osa = rate; // This is a long winded but definitive way of updating the ODR + tempVal = odcntl.all; retVal = writeRegisterByte(SFE_KX13X_ODCNTL, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } ////////////////////////////////////////////////// @@ -367,28 +396,30 @@ bool QwDevKX13X::setOutputDataRate(uint8_t rate) bool QwDevKX13X::setTapDataRate(uint8_t rate) { - if( rate > 7 ) + if (rate > 7) return false; - uint8_t tempVal; + uint8_t tempVal; int retVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL3, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL3, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | (rate << 3); + + sfe_kx13x_cntl3_bitfield_t cntl3; + cntl3.all = tempVal; + cntl3.bits.otdt = rate; // This is a long winded but definitive way of updating the tap ODR + tempVal = cntl3.all; retVal = writeRegisterByte(SFE_KX13X_CNTL3, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } - ////////////////////////////////////////////////// // setTiltDataRate() // @@ -400,28 +431,30 @@ bool QwDevKX13X::setTapDataRate(uint8_t rate) bool QwDevKX13X::setTiltDataRate(uint8_t rate) { - if( rate > 3 ) + if (rate > 3) return false; - uint8_t tempVal; + uint8_t tempVal; int retVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL3, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL3, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | (rate << 6); + + sfe_kx13x_cntl3_bitfield_t cntl3; + cntl3.all = tempVal; + cntl3.bits.otp = rate; // This is a long winded but definitive way of updating the tap ODR + tempVal = cntl3.all; retVal = writeRegisterByte(SFE_KX13X_CNTL3, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } - ////////////////////////////////////////////////// // setWakeDataRate() // @@ -433,46 +466,49 @@ bool QwDevKX13X::setTiltDataRate(uint8_t rate) bool QwDevKX13X::setWakeDataRate(uint8_t rate) { - if( rate > 7 ) + if (rate > 7) return false; - uint8_t tempVal; + uint8_t tempVal; int retVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL3, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL3, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - - tempVal = tempVal | rate; + + sfe_kx13x_cntl3_bitfield_t cntl3; + cntl3.all = tempVal; + cntl3.bits.owuf = rate; // This is a long winded but definitive way of updating the wake-up ODR + tempVal = cntl3.all; retVal = writeRegisterByte(SFE_KX13X_CNTL3, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } ////////////////////////////////////////////////// // getOutputDataRate() // -// Retrieves the output data rate of the acceleromter. +// Retrieves the output data rate of the accelerometer. // float QwDevKX13X::getOutputDataRate() { - int retVal; + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_ODCNTL, &tempVal, 1); - - if( retVal != 0 ) - return 0.0; - tempVal = tempVal & 0x0F; + if (retVal != 0) + return 0.0; - return (0.78 * ( pow(2,(float)tempVal))); -} + sfe_kx13x_odcntl_bitfield_t odcntl; + odcntl.all = tempVal; // This is a long winded but definitive way of getting the ODR + return (0.781 * (pow(2, (float)odcntl.bits.osa))); +} ////////////////////////////////////////////////// // configureInterruptPin() @@ -483,23 +519,23 @@ float QwDevKX13X::getOutputDataRate() // pinVal - register value to set, note that this overwrites // everything in the register. // -bool QwDevKX13X::configureInterruptPin(uint8_t pinVal){ - - int retVal; +bool QwDevKX13X::configureInterruptPin(uint8_t pinVal) +{ + + int retVal; retVal = writeRegisterByte(SFE_KX13X_INC1, pinVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } - ////////////////////////////////////////////////// // enablePhysInterrupt() // -// Enables interrupts to be routed to the interrupt pins. +// Enables interrupts to be routed to the interrupt pins. // // Parameters: // enable - Enables interrupts to report to the physical interrupt pins @@ -507,36 +543,43 @@ bool QwDevKX13X::configureInterruptPin(uint8_t pinVal){ // bool QwDevKX13X::enablePhysInterrupt(bool enable, uint8_t pin) { - int retVal; - uint8_t tempVal; - - if( pin == 1 ) - { - retVal = readRegisterRegion(SFE_KX13X_INC1, &tempVal, 1); + int retVal; + uint8_t tempVal; - if( retVal != 0 ) - return false; + if (pin > 2) + return false; - tempVal = tempVal | (enable << 5); + if (pin == 1) + { + retVal = readRegisterRegion(SFE_KX13X_INC1, &tempVal, 1); - writeRegisterByte(SFE_KX13X_INC1, tempVal); + if (retVal != 0) + return false; - } + sfe_kx13x_inc1_bitfield_t inc1; + inc1.all = tempVal; + inc1.bits.ien1 = enable; // This is a long winded but definitive way of setting/clearing the enable bit + tempVal = inc1.all; - if( pin == 2 ) - { - retVal = readRegisterRegion(SFE_KX13X_INC5, &tempVal, 1); + writeRegisterByte(SFE_KX13X_INC1, tempVal); + } - if( retVal != 0 ) - return false; + if (pin == 2) + { + retVal = readRegisterRegion(SFE_KX13X_INC5, &tempVal, 1); - tempVal = tempVal | (enable << 5); + if (retVal != 0) + return false; - writeRegisterByte(SFE_KX13X_INC5, tempVal); + sfe_kx13x_inc5_bitfield_t inc5; + inc5.all = tempVal; + inc5.bits.ien2 = enable; // This is a long winded but definitive way of setting/clearing the enable bit + tempVal = inc5.all; - } + writeRegisterByte(SFE_KX13X_INC5, tempVal); + } - return true; + return true; } ////////////////////////////////////////////////// @@ -548,172 +591,185 @@ bool QwDevKX13X::enablePhysInterrupt(bool enable, uint8_t pin) // enable - Enables interrupts to report to the physical interrupt pins // pin - This determines which pin to route the interrupts. // -bool QwDevKX13X::setPinMode(bool activeLow, uint8_t pin) +bool QwDevKX13X::setPinMode(bool activeHigh, uint8_t pin) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - if( pin > 2 ) - return false; + if (pin > 2) + return false; - if( pin == 1 ) - { - retVal = readRegisterRegion(SFE_KX13X_INC1, &tempVal, 1); + if (pin == 1) + { + retVal = readRegisterRegion(SFE_KX13X_INC1, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | (activeLow << 5); + sfe_kx13x_inc1_bitfield_t inc1; + inc1.all = tempVal; + inc1.bits.iea1 = activeHigh; // This is a long winded but definitive way of setting/clearing the level bit + tempVal = inc1.all; - writeRegisterByte(SFE_KX13X_INC1, tempVal); - } + writeRegisterByte(SFE_KX13X_INC1, tempVal); + } - if( pin == 2 ) - { - retVal = readRegisterRegion(SFE_KX13X_INC5, &tempVal, 1); + if (pin == 2) + { + retVal = readRegisterRegion(SFE_KX13X_INC5, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | (activeLow << 5); + sfe_kx13x_inc5_bitfield_t inc5; + inc5.all = tempVal; + inc5.bits.iea2 = activeHigh; // This is a long winded but definitive way of setting/clearing the level bit + tempVal = inc5.all; - writeRegisterByte(SFE_KX13X_INC5, tempVal); - } + writeRegisterByte(SFE_KX13X_INC5, tempVal); + } - return true; + return true; } ////////////////////////////////////////////////// // setLatchControl() // -// Determines whether interrupts are pulsed (default) or latched. +// Determines whether interrupts are pulsed (default) or latched. // If they are latched then the interrupt must be released by reading // the INT_REL register - clearInterrupt(); // // Parameters: -// latch - True enables latch behavior, false enables pulse behavior (default) +// latch - False enables latch behavior, True enables pulse behavior (default) // -bool QwDevKX13X::setLatchControl(bool latch, uint8_t pin) +bool QwDevKX13X::setLatchControl(bool pulsed, uint8_t pin) { - int retVal; - uint8_t tempVal; - - if( pin > 2 ) - return false; + int retVal; + uint8_t tempVal; - if( pin == 1 ) - { - retVal = readRegisterRegion(SFE_KX13X_INC1, &tempVal, 1); + if (pin > 2) + return false; - if( retVal != 0 ) - return false; + if (pin == 1) + { + retVal = readRegisterRegion(SFE_KX13X_INC1, &tempVal, 1); - tempVal = tempVal | (latch << 3); + if (retVal != 0) + return false; - writeRegisterByte(SFE_KX13X_INC1, tempVal); - } + sfe_kx13x_inc1_bitfield_t inc1; + inc1.all = tempVal; + inc1.bits.iel1 = pulsed; // This is a long winded but definitive way of setting/clearing the latch bit + tempVal = inc1.all; + writeRegisterByte(SFE_KX13X_INC1, tempVal); + } - if( pin == 2 ) - { - retVal = readRegisterRegion(SFE_KX13X_INC5, &tempVal, 1); + if (pin == 2) + { + retVal = readRegisterRegion(SFE_KX13X_INC5, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | (latch << 3); + sfe_kx13x_inc5_bitfield_t inc5; + inc5.all = tempVal; + inc5.bits.iel2 = pulsed; // This is a long winded but definitive way of setting/clearing the latch bit + tempVal = inc5.all; - writeRegisterByte(SFE_KX13X_INC5, tempVal); - } + writeRegisterByte(SFE_KX13X_INC5, tempVal); + } - return true; + return true; } ////////////////////////////////////////////////// // setPulseWidth() // -// Determines the width of the interrupt pulse +// Determines the width of the interrupt pulse // // Parameters: -// width - The width setting to be applied. -// pin - the pin to be configured. +// width - The width setting to be applied. +// pin - the pin to be configured. // bool QwDevKX13X::setPulseWidth(uint8_t width, uint8_t pin) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - if( (width > 4) | (pin > 2) ) - return false; + if ((width > 3) || (pin > 2)) + return false; - if( pin == 1 ) - { - retVal = readRegisterRegion(SFE_KX13X_INC1, &tempVal, 1); + if (pin == 1) + { + retVal = readRegisterRegion(SFE_KX13X_INC1, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | (width << 6); + sfe_kx13x_inc1_bitfield_t inc1; + inc1.all = tempVal; + inc1.bits.pw1 = width; // This is a long winded but definitive way of setting the pulse width + tempVal = inc1.all; - writeRegisterByte(SFE_KX13X_INC1, tempVal); - } + writeRegisterByte(SFE_KX13X_INC1, tempVal); + } - if( pin == 2 ) - { - retVal = readRegisterRegion(SFE_KX13X_INC5, &tempVal, 1); + if (pin == 2) + { + retVal = readRegisterRegion(SFE_KX13X_INC5, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | (width << 6); + sfe_kx13x_inc5_bitfield_t inc5; + inc5.all = tempVal; + inc5.bits.pw2 = width; // This is a long winded but definitive way of setting the pulse width + tempVal = inc5.all; - writeRegisterByte(SFE_KX13X_INC5, tempVal); - } + writeRegisterByte(SFE_KX13X_INC5, tempVal); + } - return true; + return true; } - ////////////////////////////////////////////////// -// setPulseWidth() +// routeHardwareInterrupt() // // This determines which interrupt is routed to a particular physical // interrupt pin. // // Parameters: // rdr - The selected interrupt - watermark, tap/double tap, tilt, data ready etc. -// pin - The physical hardware pin that will receive the interrupt. +// pin - The physical hardware pin that will receive the interrupt. // bool QwDevKX13X::routeHardwareInterrupt(uint8_t rdr, uint8_t pin) { int retVal; - if( pin > 2 ) - return false; + if (pin > 2) + return false; - if( pin == 1 ) - { + if (pin == 1) + { retVal = writeRegisterByte(SFE_KX13X_INC4, rdr); - if( retVal != 0 ) + if (retVal != 0) return false; } - if( pin == 2 ) - { + if (pin == 2) + { retVal = writeRegisterByte(SFE_KX13X_INC6, rdr); - if( retVal != 0 ) + if (retVal != 0) return false; - } return true; - } - ////////////////////////////////////////////////// // clearInterrupt() // @@ -721,73 +777,78 @@ bool QwDevKX13X::routeHardwareInterrupt(uint8_t rdr, uint8_t pin) // bool QwDevKX13X::clearInterrupt() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INT_REL, &tempVal, 1); - if( retVal != 0 ) - return false; - - return true; + if (retVal != 0) + return false; + + return true; } ////////////////////////////////////////////////// // enableDirecTapInterupt() // -// Enables reporting on the direction of the latest generated tap. +// Enables reporting on the direction of the latest generated tap. // -// Parameter: -// enable - enables/disables directional tap reporting. +// Parameter: +// enable - enables/disables directional tap reporting. // bool QwDevKX13X::enableDirecTapInterupt(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_TDTRC, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | enable; + sfe_kx13x_tdtrc_bitfield_t tdtrc; + tdtrc.all = tempVal; + tdtrc.bits.stre = enable; // This is a long winded but definitive way of setting/clearing the enable bit + tempVal = tdtrc.all; - retVal = writeRegisterByte(SFE_KX13X_TDTRC, tempVal); + retVal = writeRegisterByte(SFE_KX13X_TDTRC, tempVal); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - return true; + return true; } - ////////////////////////////////////////////////// // enableDirecTapInterupt() // -// Enables the double tap interrupt. +// Enables the double tap interrupt. // -// Parameter: +// Parameter: // enable - enables/disables the double tap interrupt // bool QwDevKX13X::enableDoubleTapInterrupt(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_TDTRC, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | (enable << 1); + sfe_kx13x_tdtrc_bitfield_t tdtrc; + tdtrc.all = tempVal; + tdtrc.bits.dtre = enable; // This is a long winded but definitive way of setting/clearing the enable bit + tempVal = tdtrc.all; - retVal = writeRegisterByte(SFE_KX13X_TDTRC, tempVal); + retVal = writeRegisterByte(SFE_KX13X_TDTRC, tempVal); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - return true; + return true; } ////////////////////////////////////////////////// @@ -795,24 +856,24 @@ bool QwDevKX13X::enableDoubleTapInterrupt(bool enable) // // Checks the data ready bit indicating new accelerometer data // is ready in the X/Y/Z Out regsiters. This is cleared automatically -// on read. +// on read. // // bool QwDevKX13X::dataReady() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - if( tempVal & 0x10 ) - return true; + sfe_kx13x_ins2_bitfield_t ins2; + ins2.all = tempVal; - return false; + return ins2.bits.drdy; } ////////////////////////////////////////////////// @@ -823,382 +884,372 @@ bool QwDevKX13X::dataReady() // bool QwDevKX13X::freeFall() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - if( tempVal & 0x80 ) - return true; + sfe_kx13x_ins2_bitfield_t ins2; + ins2.all = tempVal; - return false; + return ins2.bits.ffs; } - ////////////////////////////////////////////////// // bufferFull() // -// Checks the buffer full interrupt bit indicating that the -// buff is full. +// Checks the buffer full interrupt bit indicating that the +// buff is full. // bool QwDevKX13X::bufferFull() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - if( tempVal & 0x40 ) - return true; + sfe_kx13x_ins2_bitfield_t ins2; + ins2.all = tempVal; - return false; + return ins2.bits.bfi; } - ////////////////////////////////////////////////// // waterMarkReached() // // Checks the watermark interrupt bit indicating it has been reached. -// buff is full. +// buff is full. // bool QwDevKX13X::waterMarkReached() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - if( tempVal & 0x10 ) - return true; + sfe_kx13x_ins2_bitfield_t ins2; + ins2.all = tempVal; - return false; + return ins2.bits.wmi; } - ////////////////////////////////////////////////// // tapDetected() // // Checks the tap interrupt bit indicating that a tap has -// been detected. +// been detected. // bool QwDevKX13X::tapDetected() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS2, &tempVal, 1); - if( retVal != 0 ) - return false; - + if (retVal != 0) + return false; - tempVal = tempVal & 0x0C; // Three states of interest: single tap detected - // undefined, and no tap. - - if( tempVal == 0x04 ) // True if tap - not undefined or no tap. - return true; + sfe_kx13x_ins2_bitfield_t ins2; + ins2.all = tempVal; - return false; + return (ins2.bits.tdts == 0x01); // Single tap } ////////////////////////////////////////////////// // getDirection() // // If the tap direction bit is enabled, this register will report -// the direction of the detected tap. +// the direction of the detected tap. // int8_t QwDevKX13X::getDirection() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS1, &tempVal, 1); - if( retVal != 0 ) - return retVal; + if (retVal != 0) + return retVal; - return tempVal; + return tempVal; } - ////////////////////////////////////////////////// // unknowntap() // -// if the accelerometer is unsure whether it has in fact +// if the accelerometer is unsure whether it has in fact // detected a tap, it will report an "unknown" state. in that -// case this function will return true. good for error checking. -// +// case this function will return true. good for error checking. +// bool QwDevKX13X::unknownTap() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal & 0x0C; // Three states of interest: single tap detected - // undefined, and no tap. - - if( tempVal == 0x0C ) // True if undefined - return true; + sfe_kx13x_ins2_bitfield_t ins2; + ins2.all = tempVal; - return false; + return (ins2.bits.tdts == 0x03); // undefined tap event } - ////////////////////////////////////////////////// // doubleTapDetected() // -// Checks the double tap interrupt bit indicating that -// a double tap has been detected. -// +// Checks the double tap interrupt bit indicating that +// a double tap has been detected. +// bool QwDevKX13X::doubleTapDetected() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal & 0x0C; // Two states of interest: single tap detected - // and undefined. - - if( tempVal == 0x08 ) // True if tap - not undefined. - return true; + sfe_kx13x_ins2_bitfield_t ins2; + ins2.all = tempVal; - return false; + return (ins2.bits.tdts == 0x02); // Double tap } - ////////////////////////////////////////////////// // tiltChange() // -// Checks the tilt change interrupt bit indicating that -// the accelerometer has been tipped. -// +// Checks the tilt change interrupt bit indicating that +// the accelerometer has been tipped. +// bool QwDevKX13X::tiltChange() { - + int retVal; uint8_t tempVal; retVal = readRegisterRegion(SFE_KX13X_INS2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - if( tempVal == 0x01 ) - return true; + sfe_kx13x_ins2_bitfield_t ins2; + ins2.all = tempVal; - return false; + return (ins2.bits.tps); // Tilt position status } - ////////////////////////////////////////////////// // setBufferThreshold() // -// Sets the number of samples that can be held in the buffer. -// +// Sets the number of samples that can be held in the buffer. +// // Parameter: -// threshold - This value determines the number of samples that +// threshold - This value determines the number of samples that // will be store in the buffer. Can not exceed 171 for 8 bit resolution -// and 86 for 16 bit resolution. +// and 86 for 16 bit resolution. // bool QwDevKX13X::setBufferThreshold(uint8_t threshold) { int retVal; uint8_t tempVal; - uint8_t resolution; - if( threshold < 2 || threshold > 171 ) + if ((threshold < 2) || (threshold > 171)) return false; retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - resolution = (tempVal & 0x40) >> 6; // Isolate it, move it + sfe_kx13x_buf_cntl2_bitfield_t bufCntl2; + bufCntl2.all = tempVal; - if( threshold > 86 && resolution == 1 ) // 1 = 16bit resolution, max samples: 86 - threshold = 86; - - retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL1, threshold); + // BRES – determines the resolution of the acceleration data samples collected by the sample buffer. + // BRES = 0 – 8-bit samples are accumulated in the buffer + // BRES = 1 – 16-bit samples are accumulated in the buffer - if( retVal != 0 ) - return true; + if ((threshold > 86) && (bufCntl2.bits.bres == 1)) // 1 = 16bit resolution, max samples: 86 + threshold = 86; - return false; + retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL1, threshold); -} + if (retVal != 0) + return false; + return true; +} ////////////////////////////////////////////////// // setBufferOperationMode() // -// Sets the opertion mode of the Buffer: Bypass, FIFO, Stream, Trigger -// +// Sets the opertion mode of the Buffer: Bypass, FIFO, Stream, Trigger +// // Parameter: -// operationMode - Determines the operation mode to set. +// operationMode - Determines the operation mode to set. // bool QwDevKX13X::setBufferOperationMode(uint8_t operationMode) { int retVal; - uint8_t tempVal; + uint8_t tempVal; - if( operationMode > 2 ) - return false; + if (operationMode > 2) + return false; retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return true; - tempVal = tempVal | operationMode; + sfe_kx13x_buf_cntl2_bitfield_t bufCntl2; + bufCntl2.all = tempVal; + bufCntl2.bits.bm = operationMode; // This is a long winded but definitive way of setting/clearing the operating mode + tempVal = bufCntl2.all; retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL2, tempVal); - if( retVal != 0 ) + if (retVal != 0) return false; - return true; + return true; } - ////////////////////////////////////////////////// // setBufferResolution() // -// Sets the resoltuion of the data that is stored in the buffer: 8 or 16 bit. -// +// Sets the resoltuion of the data that is stored in the buffer: 8 or 16 bit. +// // Parameter: -// sixteenBit - Determines whether the resolution is 16 (true) or 8 bit (false). +// sixteenBit - Determines whether the resolution is 16 (true) or 8 bit (false). // -bool QwDevKX13X::setBufferResolution(bool sixteenBit ) +bool QwDevKX13X::setBufferResolution(bool sixteenBit) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | ((uint8_t)sixteenBit << 6); + sfe_kx13x_buf_cntl2_bitfield_t bufCntl2; + bufCntl2.all = tempVal; + bufCntl2.bits.bres = sixteenBit; // This is a long winded but definitive way of setting/clearing the resolution bit + tempVal = bufCntl2.all; - retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL2, tempVal); + retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL2, tempVal); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - return true; + return true; } - - ////////////////////////////////////////////////// // enableBufferInt() // -// Enables the buffer full interrupt bit. -// +// Enables the buffer full interrupt bit. +// // Parameter: -// enable - enable/disables the buffer full interrupt bit. +// enable - enable/disables the buffer full interrupt bit. // bool QwDevKX13X::enableBufferInt(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | (enable << 5); + sfe_kx13x_buf_cntl2_bitfield_t bufCntl2; + bufCntl2.all = tempVal; + bufCntl2.bits.bfie = enable; // This is a long winded but definitive way of setting/clearing the buffer interrupt enable bit + tempVal = bufCntl2.all; - retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL2, tempVal); + retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL2, tempVal); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - return true; + return true; } - ////////////////////////////////////////////////// // enableSampleBuffer() // // Enables use of the buffer. -// +// // Parameter: -// enable - enable/disables the buffer. +// enable - enable/disables the buffer. // bool QwDevKX13X::enableSampleBuffer(bool enable) { - int retVal; - uint8_t tempVal; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal = tempVal | ((uint8_t)enable << 7); + sfe_kx13x_buf_cntl2_bitfield_t bufCntl2; + bufCntl2.all = tempVal; + bufCntl2.bits.bufe = enable; // This is a long winded but definitive way of setting/clearing the buffer enable bit + tempVal = bufCntl2.all; - retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL2, tempVal); + retVal = writeRegisterByte(SFE_KX13X_BUF_CNTL2, tempVal); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - return true; + return true; } - - ////////////////////////////////////////////////// // getSampleLevel() // -// Gets the number of samples in the Buffer. +// Gets the number of samples in the Buffer. // uint16_t QwDevKX13X::getSampleLevel() { - int retVal; - uint8_t tempVal[2] = {0}; - uint16_t numSamples; + int retVal; + uint8_t tempVal[2] = {0}; + uint16_t numSamples; - retVal = readRegisterRegion(SFE_KX13X_BUF_STATUS_1, tempVal, 2); + retVal = readRegisterRegion(SFE_KX13X_BUF_STATUS_1, tempVal, 2); - if( retVal != 0 ) - return 0; + if (retVal != 0) + return 0; - numSamples = tempVal[0]; - numSamples = numSamples | ((tempVal[1] & 0x03) << 8); + numSamples = tempVal[0]; + numSamples |= (((uint16_t)tempVal[1] & 0x03) << 8); - return numSamples; + return numSamples; } - ////////////////////////////////////////////////// // clearBuffer() // @@ -1206,93 +1257,206 @@ uint16_t QwDevKX13X::getSampleLevel() // bool QwDevKX13X::clearBuffer() { - int retVal; - uint8_t clear = 1; + int retVal; + uint8_t clear = 1; - retVal = writeRegisterByte(SFE_KX13X_BUF_CLEAR, clear); + retVal = writeRegisterByte(SFE_KX13X_BUF_CLEAR, clear); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - return true; + return true; } ////////////////////////////////////////////////// // runCommandTest() // -// Runs the command test which verifies the circuitry connected to +// Runs the command test which verifies the circuitry connected to // the accelerometer. // bool QwDevKX13X::runCommandTest() { - + uint8_t tempVal; int retVal; retVal = readRegisterRegion(SFE_KX13X_CNTL2, &tempVal, 1); - if( retVal != 0 ) + if (retVal != 0) return false; - tempVal = tempVal | 0x40; + sfe_kx13x_cntl2_bitfield_t cntl2; + cntl2.all = tempVal; + cntl2.bits.cotc = 1; // This is a long winded, but definitive way of setting the COTC bit + tempVal = cntl2.all; - // Going to assume that communication is working at this point. + // Going to assume that communication is working at this point. writeRegisterByte(SFE_KX13X_CNTL2, tempVal); readRegisterRegion(SFE_KX13X_COTR, &tempVal, 1); - if( tempVal != 0xAA ) + if (tempVal != 0xAA) return false; - + readRegisterRegion(SFE_KX13X_CNTL2, &tempVal, 1); - if( tempVal != 0 ) - return false; - + cntl2.all = tempVal; + if (cntl2.bits.cotc != 0) + return false; + readRegisterRegion(SFE_KX13X_COTR, &tempVal, 1); - if( tempVal != 0x55 ) + if (tempVal != 0x55) return false; - return true; + return true; } - ////////////////////////////////////////////////// // getRawAccelData() // -// Retrieves the raw register values representing accelerometer data. -// -// Paramater: -// *rawAccelData - a pointer to the data struct that holds acceleromter X/Y/Z data. +// Retrieves the raw register or buffer values representing accelerometer data. +// +// This method is 'slow' in that it checks first if the buffer is being used - every time - +// and then calls the appropriate method to read data from the buffer or the regular +// output registers. You can speed up the read by calling the read method directly, +// if you already know if the buffer is being used or not. // -bool QwDevKX13X::getRawAccelData(rawOutputData *rawAccelData){ +// Note: these methods do not check if the buffer / registers contain valid data. +// The user needs to do that externally by calling getSampleLevel or dataReady +// or using the INT pins to indicate that data is ready. +// +// Parameter: +// *rawAccelData - a pointer to the data struct that holds acceleromter X/Y/Z data. +// +bool QwDevKX13X::getRawAccelData(rawOutputData *rawAccelData) +{ - int retVal; uint8_t tempVal; - uint8_t tempRegData[6] = {0}; - // Check if buffer is enabled - retVal = readRegisterRegion(SFE_KX13X_INC4, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); // bufCntl2.bits.bufe indicates if the buffer is enabled - if( retVal != 0 ) + if (retVal != 0) return false; - if( tempVal & 0x40 )// If Buffer is enabled, read there. - retVal = readRegisterRegion(SFE_KX13X_BUF_READ, tempRegData, 6); + sfe_kx13x_buf_cntl2_bitfield_t bufCntl2; + bufCntl2.all = tempVal; + + if (bufCntl2.bits.bufe) // If Buffer is enabled, read there. + return (getRawAccelBufferData(rawAccelData, (int)bufCntl2.bits.bres)); else - retVal = readRegisterRegion(SFE_KX13X_XOUT_L, tempRegData, 6); + return (getRawAccelRegisterData(rawAccelData)); +} + +////////////////////////////////////////////////// +// getRawAccelRegisterData() +// +// Retrieves the raw register values representing accelerometer data. +// +// Note: this method does not check if the registers contain valid data. +// The user needs to do that externally by calling dataReady +// or using the INT pins to indicate that data is ready. +// +// Parameter: +// *rawAccelData - a pointer to the data struct that holds acceleromter X/Y/Z data. +// +bool QwDevKX13X::getRawAccelRegisterData(rawOutputData *rawAccelData) +{ + + int retVal; + uint8_t tempRegData[6] = {0}; + + retVal = readRegisterRegion(SFE_KX13X_XOUT_L, tempRegData, TOTAL_ACCEL_DATA_16BIT); // Read 3 * 16-bit - if( retVal != 0 ) + if (retVal != 0) return false; - rawAccelData->xData = tempRegData[XLSB]; - rawAccelData->xData |= (uint16_t)((tempRegData[XMSB]) << 8); - rawAccelData->yData = tempRegData[YLSB]; - rawAccelData->yData |= (uint16_t)((tempRegData[YMSB]) << 8); - rawAccelData->zData = tempRegData[ZLSB]; - rawAccelData->zData |= ((uint16_t)(tempRegData[ZMSB]) << 8); + rawAccelData->xData = tempRegData[XLSB]; + rawAccelData->xData |= (uint16_t)tempRegData[XMSB] << 8; + rawAccelData->yData = tempRegData[YLSB]; + rawAccelData->yData |= (uint16_t)tempRegData[YMSB] << 8; + rawAccelData->zData = tempRegData[ZLSB]; + rawAccelData->zData |= (uint16_t)tempRegData[ZMSB] << 8; + + return true; +} + +////////////////////////////////////////////////// +// getRawAccelBufferData() +// +// Retrieves the raw buffer values representing accelerometer data. +// +// If sixteenBit is -1 (the default), the code reads the Buffer Control Register 2 bres +// bit to determine if the buffer data is 8-bit or 16-bit. You can speed up the code +// by setting sixteenBit to: 0 for 8-bit data; 1 for 16-bit data. +// +// Note: theis method does not check if the buffer contains valid data. +// The user needs to do that externally by calling getSampleLevel +// or using the INT pins to indicate that data is ready. +// +// Parameter: +// *rawAccelData - a pointer to the data struct that holds acceleromter X/Y/Z data. +// sixteenBit - defaults to -1. Set to 0 to read 8-bit data. Set to 1 to read 16-bit data. +// +bool QwDevKX13X::getRawAccelBufferData(rawOutputData *rawAccelData, int sixteenBit) +{ + + int retVal; + uint8_t tempRegData[6] = {0}; + bool is16bit; + + if (sixteenBit == 0) // Do we know the data is 8-bit? + { + is16bit = false; + } + else if (sixteenBit == 1) // Do we know the data is 16-bit? + { + is16bit = true; + } + else if (sixteenBit == -1) // Need to manually check the resolution + { + uint8_t tempVal; + retVal = readRegisterRegion(SFE_KX13X_BUF_CNTL2, &tempVal, 1); + + if (retVal != 0) + return false; + + sfe_kx13x_buf_cntl2_bitfield_t bufCntl2; + bufCntl2.all = tempVal; + is16bit = bufCntl2.bits.bres; // bufCntl2.bits.bufe indicates if the buffer is enabled + } + else + { + return false; // Can't determine the resolution + } + + if (is16bit) // If the buffer contains 16-bit samples + retVal = readRegisterRegion(SFE_KX13X_BUF_READ, tempRegData, TOTAL_ACCEL_DATA_16BIT); // Read 3 * 16-bit + else + retVal = readRegisterRegion(SFE_KX13X_BUF_READ, tempRegData, TOTAL_ACCEL_DATA_8BIT); // Read 3 * 8-bit + + if (retVal != 0) + return false; + + if (is16bit) // Process buffer 8-bit samples + { + rawAccelData->xData = tempRegData[XLSB]; + rawAccelData->xData |= (uint16_t)tempRegData[XMSB] << 8; + rawAccelData->yData = tempRegData[YLSB]; + rawAccelData->yData |= (uint16_t)tempRegData[YMSB] << 8; + rawAccelData->zData = tempRegData[ZLSB]; + rawAccelData->zData |= (uint16_t)tempRegData[ZMSB] << 8; + } + else + { + rawAccelData->xData = 0; + rawAccelData->xData |= (uint16_t)tempRegData[0] << 8; // Convert 8-bit signed to 16-bit signed + rawAccelData->yData = 0; + rawAccelData->yData |= (uint16_t)tempRegData[1] << 8; + rawAccelData->zData = 0; + rawAccelData->zData |= (uint16_t)tempRegData[2] << 8; + } return true; } @@ -1301,52 +1465,56 @@ bool QwDevKX13X::getRawAccelData(rawOutputData *rawAccelData){ // forceSleep() // // Forces the accelerometer into a sleep state. -// +// bool QwDevKX13X::forceSleep() { - int retVal; - uint8_t tempVal; - uint8_t forceSleep = 0x01; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL5, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL5, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal |= forceSleep; + sfe_kx13x_cntl5_bitfield_t cntl5; + cntl5.all = tempVal; + cntl5.bits.man_sleep = 1; // Set the manual sleep bit + tempVal = cntl5.all; - retVal = writeRegisterByte(SFE_KX13X_CNTL5, tempVal); + retVal = writeRegisterByte(SFE_KX13X_CNTL5, tempVal); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - return true; + return true; } ////////////////////////////////////////////////// // forceWake() // // Forces the accelerometer into a sleep state. -// +// bool QwDevKX13X::forceWake() { - int retVal; - uint8_t tempVal; - uint8_t forceWake = 0x02; + int retVal; + uint8_t tempVal; - retVal = readRegisterRegion(SFE_KX13X_CNTL5, &tempVal, 1); + retVal = readRegisterRegion(SFE_KX13X_CNTL5, &tempVal, 1); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - tempVal |= forceWake; + sfe_kx13x_cntl5_bitfield_t cntl5; + cntl5.all = tempVal; + cntl5.bits.man_wake = 1; // Set the manual wake bit + tempVal = cntl5.all; - retVal = writeRegisterByte(SFE_KX13X_CNTL5, tempVal); + retVal = writeRegisterByte(SFE_KX13X_CNTL5, tempVal); - if( retVal != 0 ) - return false; + if (retVal != 0) + return false; - return true; + return true; } ////////////////////////////////////////////////////////////////////////////////// @@ -1354,7 +1522,7 @@ bool QwDevKX13X::forceWake() // // Calls sfebus read function. // -// Parameter: +// Parameter: // reg- register to read from // data- array to store data in // length- Size of data in bytes (8 bits): 2 bytes = length of two @@ -1362,7 +1530,7 @@ bool QwDevKX13X::forceWake() // int QwDevKX13X::readRegisterRegion(uint8_t reg, uint8_t *data, uint16_t len) { - return (int)_sfeBus->readRegisterRegion(_i2cAddress, reg, data, len); + return (int)_sfeBus->readRegisterRegion(_i2cAddress, reg, data, len); } ////////////////////////////////////////////////////////////////////////////////// @@ -1370,7 +1538,7 @@ int QwDevKX13X::readRegisterRegion(uint8_t reg, uint8_t *data, uint16_t len) // // Calls sfebus write function. // -// Parameter: +// Parameter: // reg- register to read from // data- array to store data in // length- Size of data in bytes (8 bits): 2 bytes = length of two @@ -1378,7 +1546,7 @@ int QwDevKX13X::readRegisterRegion(uint8_t reg, uint8_t *data, uint16_t len) // int QwDevKX13X::writeRegisterRegion(uint8_t reg, uint8_t *data, uint16_t len) { - return (int)_sfeBus->writeRegisterRegion(_i2cAddress, reg, data, len); + return (int)_sfeBus->writeRegisterRegion(_i2cAddress, reg, data, len); } ////////////////////////////////////////////////////////////////////////////////// @@ -1386,7 +1554,7 @@ int QwDevKX13X::writeRegisterRegion(uint8_t reg, uint8_t *data, uint16_t len) // // Calls sfebus write function. // -// Parameter: +// Parameter: // reg- register to read from // data- array to store data in // length- Size of data in bytes (8 bits): 2 bytes = length of two @@ -1394,102 +1562,103 @@ int QwDevKX13X::writeRegisterRegion(uint8_t reg, uint8_t *data, uint16_t len) // int QwDevKX13X::writeRegisterByte(uint8_t reg, uint8_t data) { - return (int)_sfeBus->writeRegisterByte(_i2cAddress, reg, data); + return (int)_sfeBus->writeRegisterByte(_i2cAddress, reg, data); } - //***************************************** KX132 ********************************************************* - ////////////////////////////////////////////////////////////////////////////////// // init() // -// Ensures that communication is established with the accelerometer by pinging its +// Ensures that communication is established with the accelerometer by pinging its // address and retrieving its device ID. // bool QwDevKX132::init(void) { - if( !_sfeBus->ping(_i2cAddress) ) - return false; + if (!_sfeBus->ping(_i2cAddress)) + return false; - if( getUniqueID() != KX132_WHO_AM_I ) - return false; + if (getUniqueID() != KX132_WHO_AM_I) + return false; - return true; + return true; } - ////////////////////////////////////////////////////////////////////////////////// // getAccelData() // // Retrieves the raw accelerometer data and calls a conversion function to convert the raw values. -// -// Paramater: +// +// Parameter: // *userData - a pointer to the user's data struct that will hold acceleromter data. // -bool QwDevKX132::getAccelData(outputData *userData){ - - bool retVal; +bool QwDevKX132::getAccelData(outputData *userData) +{ + + bool retVal; retVal = getRawAccelData(&rawAccelData); - if( !retVal ) - return false; + if (!retVal) + return false; - retVal = convAccelData(userData, &rawAccelData); + retVal = convAccelData(userData, &rawAccelData); - if( !retVal ) - return false; + if (!retVal) + return false; - return true; + return true; } ////////////////////////////////////////////////////////////////////////////////// // convAccelData() // // Converts raw acceleromter data with the current accelerometer's range settings. -// -// Paramater: +// +// Parameter: // *userData - a pointer to the user's data struct that will hold acceleromter data. -// *rawAccelData - a pointer to the data struct that holds acceleromter X/Y/Z data. +// *rawAccelData - a pointer to the data struct that holds acceleromter X/Y/Z data. // -bool QwDevKX132::convAccelData(outputData *userAccel, rawOutputData *rawAccelData){ - +bool QwDevKX132::convAccelData(outputData *userAccel, rawOutputData *rawAccelData) +{ uint8_t regVal; - uint8_t range; + uint8_t range; int retVal; retVal = readRegisterRegion(SFE_KX13X_CNTL1, ®Val, 1); - if( retVal != 0 ) - return false; - - range = (regVal & 0x18) >> 3; - - - switch( range ) { - case SFE_KX132_RANGE2G: - userAccel->xData = (float)rawAccelData->xData * convRange2G; - userAccel->yData = (float)rawAccelData->yData * convRange2G; - userAccel->zData = (float)rawAccelData->zData * convRange2G; - break; - case SFE_KX132_RANGE4G: - userAccel->xData = (float)rawAccelData->xData * convRange4G; - userAccel->yData = (float)rawAccelData->yData * convRange4G; - userAccel->zData = (float)rawAccelData->zData * convRange4G; - break; - case SFE_KX132_RANGE8G: - userAccel->xData = (float)rawAccelData->xData * convRange8G; - userAccel->yData = (float)rawAccelData->yData * convRange8G; - userAccel->zData = (float)rawAccelData->zData * convRange8G; - break; - case SFE_KX132_RANGE16G: - userAccel->xData = (float)rawAccelData->xData * convRange16G; - userAccel->yData = (float)rawAccelData->yData * convRange16G; - userAccel->zData = (float)rawAccelData->zData * convRange16G; - break; - default: - return false; + if (retVal != 0) + return false; + + sfe_kx13x_cntl1_bitfield_t cntl1; + cntl1.all = regVal; + + range = cntl1.bits.gsel; + + switch (range) + { + case SFE_KX132_RANGE2G: + userAccel->xData = (float)rawAccelData->xData * convRange2G; + userAccel->yData = (float)rawAccelData->yData * convRange2G; + userAccel->zData = (float)rawAccelData->zData * convRange2G; + break; + case SFE_KX132_RANGE4G: + userAccel->xData = (float)rawAccelData->xData * convRange4G; + userAccel->yData = (float)rawAccelData->yData * convRange4G; + userAccel->zData = (float)rawAccelData->zData * convRange4G; + break; + case SFE_KX132_RANGE8G: + userAccel->xData = (float)rawAccelData->xData * convRange8G; + userAccel->yData = (float)rawAccelData->yData * convRange8G; + userAccel->zData = (float)rawAccelData->zData * convRange8G; + break; + case SFE_KX132_RANGE16G: + userAccel->xData = (float)rawAccelData->xData * convRange16G; + userAccel->yData = (float)rawAccelData->yData * convRange16G; + userAccel->zData = (float)rawAccelData->zData * convRange16G; + break; + default: + return false; } return true; @@ -1500,98 +1669,96 @@ bool QwDevKX132::convAccelData(outputData *userAccel, rawOutputData *rawAccelDat ////////////////////////////////////////////////////////////////////////////////// // init() // -// Ensures that communication is established with the accelerometer by pinging its +// Ensures that communication is established with the accelerometer by pinging its // address and retrieving its device ID. // bool QwDevKX134::init(void) { - if( !_sfeBus->ping(_i2cAddress) ) - return false; + if (!_sfeBus->ping(_i2cAddress)) + return false; - if( getUniqueID() != KX134_WHO_AM_I ) - return false; + if (getUniqueID() != KX134_WHO_AM_I) + return false; - return true; + return true; } - ////////////////////////////////////////////////////////////////////////////////// // getAccelData() // // Retrieves the raw accelerometer data and calls a conversion function to convert the raw values. -// -// Paramater: +// +// Parameter: // *userData - a pointer to the user's data struct that will hold acceleromter data. // bool QwDevKX134::getAccelData(outputData *userData) { - - bool retVal; + + bool retVal; retVal = getRawAccelData(&rawAccelData); - if( !retVal ) - return false; + if (!retVal) + return false; - retVal = convAccelData(userData, &rawAccelData); + retVal = convAccelData(userData, &rawAccelData); - if( !retVal ) - return false; + if (!retVal) + return false; - return true; + return true; } ////////////////////////////////////////////////////////////////////////////////// // convAccelData() // // Converts raw acceleromter data with the current accelerometer's range settings. -// -// Paramater: +// +// Parameter: // *userData - a pointer to the user's data struct that will hold acceleromter data. -// *rawAccelData - a pointer to the data struct that holds acceleromter X/Y/Z data. +// *rawAccelData - a pointer to the data struct that holds acceleromter X/Y/Z data. // bool QwDevKX134::convAccelData(outputData *userAccel, rawOutputData *rawAccelData) { - uint8_t regVal; - uint8_t range; + uint8_t range; int retVal; retVal = readRegisterRegion(SFE_KX13X_CNTL1, ®Val, 1); - if( retVal != 0 ) - return false; - - range = (regVal & 0x18) >> 3; - - - switch( range ) { - case SFE_KX134_RANGE8G: - userAccel->xData = (float)rawAccelData->xData * convRange8G; - userAccel->yData = (float)rawAccelData->yData * convRange8G; - userAccel->zData = (float)rawAccelData->zData * convRange8G; - break; - case SFE_KX134_RANGE16G: - userAccel->xData = (float)rawAccelData->xData * convRange16G; - userAccel->yData = (float)rawAccelData->yData * convRange16G; - userAccel->zData = (float)rawAccelData->zData * convRange16G; - break; - case SFE_KX134_RANGE32G: - userAccel->xData = (float)rawAccelData->xData * convRange32G; - userAccel->yData = (float)rawAccelData->yData * convRange32G; - userAccel->zData = (float)rawAccelData->zData * convRange32G; - break; - case SFE_KX134_RANGE64G: - userAccel->xData = (float)rawAccelData->xData * convRange64G; - userAccel->yData = (float)rawAccelData->yData * convRange64G; - userAccel->zData = (float)rawAccelData->zData * convRange64G; - break; - default: - return false; + if (retVal != 0) + return false; + sfe_kx13x_cntl1_bitfield_t cntl1; + cntl1.all = regVal; + + range = cntl1.bits.gsel; + + switch (range) + { + case SFE_KX134_RANGE8G: + userAccel->xData = (float)rawAccelData->xData * convRange8G; + userAccel->yData = (float)rawAccelData->yData * convRange8G; + userAccel->zData = (float)rawAccelData->zData * convRange8G; + break; + case SFE_KX134_RANGE16G: + userAccel->xData = (float)rawAccelData->xData * convRange16G; + userAccel->yData = (float)rawAccelData->yData * convRange16G; + userAccel->zData = (float)rawAccelData->zData * convRange16G; + break; + case SFE_KX134_RANGE32G: + userAccel->xData = (float)rawAccelData->xData * convRange32G; + userAccel->yData = (float)rawAccelData->yData * convRange32G; + userAccel->zData = (float)rawAccelData->zData * convRange32G; + break; + case SFE_KX134_RANGE64G: + userAccel->xData = (float)rawAccelData->xData * convRange64G; + userAccel->yData = (float)rawAccelData->yData * convRange64G; + userAccel->zData = (float)rawAccelData->zData * convRange64G; + break; + default: + return false; } return true; } - - diff --git a/src/SparkFun_Qwiic_KX13X.h b/src/SparkFun_Qwiic_KX13X.h index c840415..848c92e 100644 --- a/src/SparkFun_Qwiic_KX13X.h +++ b/src/SparkFun_Qwiic_KX13X.h @@ -9,7 +9,7 @@ // Written by Elias Santistevan @ SparkFun Electronics, October 2022 // // Product: -//SparkFun Triple Axis Accelerometer - KX132/KX134 (Qwiic) +// SparkFun Triple Axis Accelerometer - KX132/KX134 (Qwiic) // * KX132 - https://www.sparkfun.com/products/17871 // * KX134 - https://www.sparkfun.com/products/17589 // @@ -39,11 +39,9 @@ // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - // The following class implements the methods to set, get, and read from the SparkFun Triple // Axis Acceleromter - KX132/KX134. - #pragma once #include @@ -54,20 +52,23 @@ #define KX13X_ADDRESS_HIGH 0x1F #define KX13X_ADDRESS_LOW 0x1E -#define KX132_WHO_AM_I 0x3D -#define KX134_WHO_AM_I 0x46 +#define KX132_WHO_AM_I 0x3D +#define KX134_WHO_AM_I 0x46 -#define SFE_KX132_RANGE2G 0x00 -#define SFE_KX132_RANGE4G 0x01 -#define SFE_KX132_RANGE8G 0x02 +// CNTL1 GSEL<1:0> +#define SFE_KX132_RANGE2G 0x00 +#define SFE_KX132_RANGE4G 0x01 +#define SFE_KX132_RANGE8G 0x02 #define SFE_KX132_RANGE16G 0x03 -#define SFE_KX134_RANGE8G 0x00 +// CNTL1 GSEL<1:0> +#define SFE_KX134_RANGE8G 0x00 #define SFE_KX134_RANGE16G 0x01 #define SFE_KX134_RANGE32G 0x02 #define SFE_KX134_RANGE64G 0x03 -#define TOTAL_ACCEL_DATA_8BIT 3 +#define TOTAL_ACCEL_DATA_8BIT 3 +#define TOTAL_ACCEL_DATA_16BIT 6 #define XLSB 0 #define XMSB 1 @@ -78,143 +79,140 @@ #define SPI_READ 0x80 // OR'ed at most sig BIT with register address -#define DEFAULT_SETTINGS 0xC0 -#define INT_SETTINGS 0xE0 -#define SOFT_INT_SETTINGS 0xE1 -#define BUFFER_SETTINGS 0xE2 -#define TILT_SETTINGS 0xE3 +#define DEFAULT_SETTINGS 0xC0 +#define INT_SETTINGS 0xE0 +#define SOFT_INT_SETTINGS 0xE1 +#define BUFFER_SETTINGS 0xE2 +#define TILT_SETTINGS 0xE3 -struct outputData { +struct outputData +{ float xData; float yData; float zData; }; -struct rawOutputData { +struct rawOutputData +{ int16_t xData; int16_t yData; int16_t zData; }; - class QwDevKX13X { - public: - - QwDevKX13X() : _i2cAddress{0}, _cs{0} {}; - - int writeRegisterRegion(uint8_t reg, uint8_t *data, uint16_t length); - int writeRegisterByte(uint8_t reg, uint8_t data); - int readRegisterRegion(uint8_t reg, uint8_t *data, uint16_t length); - void setCommunicationBus(QwIDeviceBus &theBus, uint8_t i2cAddress); - void setCommunicationBus(QwIDeviceBus &theBus); - - uint8_t getUniqueID(); - bool initialize(uint8_t settings = DEFAULT_SETTINGS); - - // General Settings - bool enableAccel(bool enable = true); - bool softwareReset(); - int8_t getOperatingMode(); - bool setRange(uint8_t); - bool setInterruptPin(bool enable, uint8_t polarity = 0, uint8_t pulseWidth = 0, bool latchControl = false); - bool enableDataEngine(bool enable = true); - bool setOutputDataRate(uint8_t); - float getOutputDataRate(); - bool dataReady(); - bool runCommandTest(); - uint8_t readAccelState(); - bool getRawAccelData(rawOutputData*); - float readOutputDataRate(); - - // Tap/Double settings - bool enableTapEngine(bool enable = true); - bool setTapDataRate(uint8_t rate); - bool enableDirecTapInterupt(bool enable = true); - bool enableDoubleTapInterrupt(bool enable = true); - - // Tilt Settings - bool enableTiltEngine(bool enable = true); - bool setTiltDataRate(uint8_t rate); - - // Wake/Sleep Settings - bool setWakeDataRate(uint8_t rate); - bool enableSleepEngine(bool enable = true); - bool enableWakeEngine(bool enable = true); - bool forceWake(); - bool forceSleep(); - - // Interrupt Settings - bool configureInterruptPin(uint8_t pinVal); - bool routeHardwareInterrupt(uint8_t, uint8_t pin = 1); - bool enablePhysInterrupt(bool enable = true, uint8_t pin = 1); - bool setPinMode(bool activeLow = true, uint8_t pin = 1); - bool setLatchControl(bool latch = true, uint8_t pin = 1); - bool setPulseWidth(uint8_t width, uint8_t pin = 1); - bool clearInterrupt(); - bool tapDetected(); - int8_t getDirection(); - bool unknownTap(); - bool waterMarkReached(); - bool bufferFull(); - bool freeFall(); - bool doubleTapDetected(); - bool tiltChange(); - - // Buffer Setttings - bool setBufferThreshold(uint8_t); - bool setBufferOperationMode(uint8_t operationMode); - bool setBufferResolution(bool sixteenBit = true); - bool enableBufferInt(bool enable = true); - bool enableSampleBuffer(bool enable = true); - uint16_t getSampleLevel(); - bool clearBuffer(); - - - rawOutputData rawAccelData; - - - protected: - - QwIDeviceBus *_sfeBus; - uint8_t _i2cAddress; - uint8_t _cs; +public: + QwDevKX13X() : _i2cAddress{0}, _cs{0} {}; + + int writeRegisterRegion(uint8_t reg, uint8_t *data, uint16_t length); + int writeRegisterByte(uint8_t reg, uint8_t data); + int readRegisterRegion(uint8_t reg, uint8_t *data, uint16_t length); + void setCommunicationBus(sfe_KX13X::QwIDeviceBus &theBus, uint8_t i2cAddress); + void setCommunicationBus(sfe_KX13X::QwIDeviceBus &theBus); + + uint8_t getUniqueID(); + bool initialize(uint8_t settings = DEFAULT_SETTINGS); + + // General Settings + bool enableAccel(bool enable = true); + bool softwareReset(); + int8_t getOperatingMode(); + bool setRange(uint8_t); + bool setInterruptPin(bool enable, uint8_t polarity = 0, uint8_t pulseWidth = 0, bool latchControl = false); + bool enableDataEngine(bool enable = true); + bool setOutputDataRate(uint8_t); + float getOutputDataRate(); + bool dataReady(); + bool runCommandTest(); + uint8_t readAccelState(); + bool getRawAccelData(rawOutputData *); + bool getRawAccelRegisterData(rawOutputData *); + bool getRawAccelBufferData(rawOutputData *, int sixteenBit = -1); // Set sixteenBit to 0 to read 8-bit data. Set to 1 to read 16-bit data. + float readOutputDataRate(); + + // Tap/Double settings + bool enableTapEngine(bool enable = true); + bool setTapDataRate(uint8_t rate); + bool enableDirecTapInterupt(bool enable = true); + bool enableDoubleTapInterrupt(bool enable = true); + + // Tilt Settings + bool enableTiltEngine(bool enable = true); + bool setTiltDataRate(uint8_t rate); + + // Wake/Sleep Settings + bool setWakeDataRate(uint8_t rate); + bool enableSleepEngine(bool enable = true); + bool enableWakeEngine(bool enable = true); + bool forceWake(); + bool forceSleep(); + + // Interrupt Settings + bool configureInterruptPin(uint8_t pinVal); + bool routeHardwareInterrupt(uint8_t, uint8_t pin = 1); + bool enablePhysInterrupt(bool enable = true, uint8_t pin = 1); + bool setPinMode(bool activeHigh = true, uint8_t pin = 1); + bool setLatchControl(bool pulsed = true, uint8_t pin = 1); + bool setPulseWidth(uint8_t width, uint8_t pin = 1); + bool clearInterrupt(); + bool tapDetected(); + int8_t getDirection(); + bool unknownTap(); + bool waterMarkReached(); + bool bufferFull(); + bool freeFall(); + bool doubleTapDetected(); + bool tiltChange(); + + // Buffer Setttings + bool setBufferThreshold(uint8_t); + bool setBufferOperationMode(uint8_t operationMode); + bool setBufferResolution(bool sixteenBit = true); + bool enableBufferInt(bool enable = true); + bool enableSampleBuffer(bool enable = true); + uint16_t getSampleLevel(); + bool clearBuffer(); + + rawOutputData rawAccelData; + +protected: + sfe_KX13X::QwIDeviceBus *_sfeBus; + uint8_t _i2cAddress; + uint8_t _cs; }; - + class QwDevKX132 : public QwDevKX13X { - public: +public: + QwDevKX132(){}; - QwDevKX132() {}; + bool init(void); + bool getAccelData(outputData *userData); + bool convAccelData(outputData *userAccel, rawOutputData *rawAccelData); - bool init(void); - bool getAccelData(outputData *userData); - bool convAccelData(outputData *userAccel, rawOutputData *rawAccelData); + // KX132 conversion values - all 16 bit resolution + const double convRange2G = .000061; + const double convRange4G = .000122; + const double convRange8G = .000244; + const double convRange16G = .000488; - //KX132 conversion values - all 16 bit resolution - const double convRange2G = .00006; - const double convRange4G = .00012; - const double convRange8G = .00024; - const double convRange16G = .00048; - - private: +private: }; class QwDevKX134 : public QwDevKX13X { - public: - - QwDevKX134() {}; +public: + QwDevKX134(){}; - bool init(void); - bool getAccelData(outputData *userData); - bool convAccelData(outputData *userAccel, rawOutputData *rawAccelData); + bool init(void); + bool getAccelData(outputData *userData); + bool convAccelData(outputData *userAccel, rawOutputData *rawAccelData); - //KX134 conversion values - all 16 bit resolution - const double convRange8G = .00024; - const double convRange16G = .00049; - const double convRange32G = .00098; - const double convRange64G = .00195; + // KX134 conversion values - all 16 bit resolution + const double convRange8G = .000244; + const double convRange16G = .000488; + const double convRange32G = .000977; + const double convRange64G = .001953; - private: +private: }; diff --git a/src/sfe_bus.cpp b/src/sfe_bus.cpp index 32b1aca..28287b5 100644 --- a/src/sfe_bus.cpp +++ b/src/sfe_bus.cpp @@ -48,6 +48,9 @@ #include "sfe_bus.h" #include +namespace sfe_KX13X +{ + #define kMaxTransferBuffer 32 #define SPI_READ 0x80 @@ -363,3 +366,5 @@ int SfeSPI::readRegisterRegion(uint8_t addr, uint8_t reg, uint8_t *data, uint16_ return 0; } + +} \ No newline at end of file diff --git a/src/sfe_bus.h b/src/sfe_bus.h index 0d2a976..8373eac 100644 --- a/src/sfe_bus.h +++ b/src/sfe_bus.h @@ -52,6 +52,8 @@ #include #include +namespace sfe_KX13X +{ // The following abstract class is used an interface for upstream implementation. class QwIDeviceBus @@ -123,3 +125,4 @@ class SfeSPI : public QwIDeviceBus uint8_t _cs; }; +}; \ No newline at end of file