From f2dcb9b87bc4e6e1bd647fceddb6fe9492b4a651 Mon Sep 17 00:00:00 2001 From: Carlo Parata Date: Tue, 26 Jan 2021 16:43:40 +0100 Subject: [PATCH] Add begin and end APIs and SPI support --- README.md | 34 ++++-- .../DISCO_IOT_6DOrientation.ino | 27 ++--- .../DISCO_IOT_DoubleTap.ino | 15 ++- .../DISCO_IOT_FreeFall/DISCO_IOT_FreeFall.ino | 15 ++- .../DISCO_IOT_LSM6DSL_DataLog_Terminal.ino | 17 ++- .../DISCO_IOT_MultiEvent.ino | 39 +++--- .../DISCO_IOT_Pedometer.ino | 19 ++- examples/DISCO_IOT_Tap/DISCO_IOT_Tap.ino | 15 ++- examples/DISCO_IOT_Tilt/DISCO_IOT_Tilt.ino | 15 ++- .../DISCO_IOT_WakeUp/DISCO_IOT_WakeUp.ino | 15 ++- keywords.txt | 2 + library.properties | 4 +- src/LSM6DSLSensor.cpp | 113 +++++++++--------- src/LSM6DSLSensor.h | 90 +++++++++++--- 14 files changed, 240 insertions(+), 180 deletions(-) diff --git a/README.md b/README.md index eef9912..20bc257 100644 --- a/README.md +++ b/README.md @@ -3,23 +3,39 @@ Arduino library to support the LSM6DSL 3D accelerometer and 3D gyroscope ## API -This sensor uses I2C to communicate. It is then required to create a TwoWire interface before accessing to the sensors: +This sensor uses I2C or SPI to communicate. +For I2C it is then required to create a TwoWire interface before accessing to the sensors: - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + TwoWire dev_i2c(I2C_SDA, I2C_SCL); + dev_i2c.begin(); -An instance can be created and enabled following the procedure below: +For SPI it is then required to create a SPI interface before accessing to the sensors: - AccGyr = new LSM6DSLSensor(dev_i2c); - AccGyr->Enable_X(); - AccGyr->Enable_G(); + SPIClass dev_spi(SPI_MOSI, SPI_MISO, SPI_SCK); + dev_spi.begin(); + +An instance can be created and enabled when the I2C bus is used following the procedure below: + + LSM6DSLSensor AccGyr(&dev_i2c); + AccGyr.begin(); + AccGyr.Enable_X(); + AccGyr.Enable_G(); + +An instance can be created and enabled when the SPI bus is used following the procedure below: + + LSM6DSLSensor AccGyr(&dev_spi, CS_PIN); + AccGyr.begin(); + AccGyr.Enable_X(); + AccGyr.Enable_G(); The access to the sensor values is done as explained below: Read accelerometer and gyroscope. - AccGyr->Get_X_Axes(accelerometer); - AccGyr->Get_G_Axes(gyroscope); + int32_t accelerometer[3]; + int32_t gyroscope[3]; + AccGyr.Get_X_Axes(accelerometer); + AccGyr.Get_G_Axes(gyroscope); ## Documentation diff --git a/examples/DISCO_IOT_6DOrientation/DISCO_IOT_6DOrientation.ino b/examples/DISCO_IOT_6DOrientation/DISCO_IOT_6DOrientation.ino index 09f1baf..79ae3ad 100644 --- a/examples/DISCO_IOT_6DOrientation/DISCO_IOT_6DOrientation.ino +++ b/examples/DISCO_IOT_6DOrientation/DISCO_IOT_6DOrientation.ino @@ -49,8 +49,8 @@ #define INT1 PD11 // Components. -LSM6DSLSensor *AccGyr; -TwoWire *dev_i2c; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); //Interrupts. volatile int mems_event = 0; @@ -68,18 +68,17 @@ void setup() { SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); //Interrupts. attachInterrupt(INT1, INT1Event_cb, RISING); // Initlialize Components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); + AccGyr.begin(); + AccGyr.Enable_X(); // Enable 6D Orientation. - AccGyr->Enable_6D_Orientation(); + AccGyr.Enable_6D_Orientation(); } void loop() { @@ -87,7 +86,7 @@ void loop() { { mems_event = 0; LSM6DSL_Event_Status_t status; - AccGyr->Get_Event_Status(&status); + AccGyr.Get_Event_Status(&status); if (status.D6DOrientationStatus) { // Send 6D Orientation @@ -115,12 +114,12 @@ void sendOrientation() uint8_t zl = 0; uint8_t zh = 0; - AccGyr->Get_6D_Orientation_XL(&xl); - AccGyr->Get_6D_Orientation_XH(&xh); - AccGyr->Get_6D_Orientation_YL(&yl); - AccGyr->Get_6D_Orientation_YH(&yh); - AccGyr->Get_6D_Orientation_ZL(&zl); - AccGyr->Get_6D_Orientation_ZH(&zh); + AccGyr.Get_6D_Orientation_XL(&xl); + AccGyr.Get_6D_Orientation_XH(&xh); + AccGyr.Get_6D_Orientation_YL(&yl); + AccGyr.Get_6D_Orientation_YH(&yh); + AccGyr.Get_6D_Orientation_ZL(&zl); + AccGyr.Get_6D_Orientation_ZH(&zh); if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 1 && zh == 0 ) { diff --git a/examples/DISCO_IOT_DoubleTap/DISCO_IOT_DoubleTap.ino b/examples/DISCO_IOT_DoubleTap/DISCO_IOT_DoubleTap.ino index a747f85..d9488f9 100644 --- a/examples/DISCO_IOT_DoubleTap/DISCO_IOT_DoubleTap.ino +++ b/examples/DISCO_IOT_DoubleTap/DISCO_IOT_DoubleTap.ino @@ -49,8 +49,8 @@ #define INT1 PD11 // Components. -LSM6DSLSensor *AccGyr; -TwoWire *dev_i2c; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); //Interrupts. volatile int mems_event = 0; @@ -65,25 +65,24 @@ void setup() { SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); //Interrupts. attachInterrupt(INT1, INT1Event_cb, RISING); // Initlialize Components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); + AccGyr.begin(); + AccGyr.Enable_X(); // Enable Double Tap Detection. - AccGyr->Enable_Double_Tap_Detection(); + AccGyr.Enable_Double_Tap_Detection(); } void loop() { if (mems_event) { mems_event = 0; LSM6DSL_Event_Status_t status; - AccGyr->Get_Event_Status(&status); + AccGyr.Get_Event_Status(&status); if (status.DoubleTapStatus) { // Led blinking. diff --git a/examples/DISCO_IOT_FreeFall/DISCO_IOT_FreeFall.ino b/examples/DISCO_IOT_FreeFall/DISCO_IOT_FreeFall.ino index f2432a7..e5d679d 100644 --- a/examples/DISCO_IOT_FreeFall/DISCO_IOT_FreeFall.ino +++ b/examples/DISCO_IOT_FreeFall/DISCO_IOT_FreeFall.ino @@ -49,8 +49,8 @@ #define INT1 PD11 // Components. -LSM6DSLSensor *AccGyr; -TwoWire *dev_i2c; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); //Interrupts. volatile int mems_event = 0; @@ -65,25 +65,24 @@ void setup() { SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); //Interrupts. attachInterrupt(INT1, INT1Event_cb, RISING); // Initlialize Components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); + AccGyr.begin(); + AccGyr.Enable_X(); // Enable Free Fall Detection. - AccGyr->Enable_Free_Fall_Detection(); + AccGyr.Enable_Free_Fall_Detection(); } void loop() { if (mems_event) { mems_event = 0; LSM6DSL_Event_Status_t status; - AccGyr->Get_Event_Status(&status); + AccGyr.Get_Event_Status(&status); if (status.FreeFallStatus) { // Led blinking. diff --git a/examples/DISCO_IOT_LSM6DSL_DataLog_Terminal/DISCO_IOT_LSM6DSL_DataLog_Terminal.ino b/examples/DISCO_IOT_LSM6DSL_DataLog_Terminal/DISCO_IOT_LSM6DSL_DataLog_Terminal.ino index 8ac46de..35c77b1 100644 --- a/examples/DISCO_IOT_LSM6DSL_DataLog_Terminal/DISCO_IOT_LSM6DSL_DataLog_Terminal.ino +++ b/examples/DISCO_IOT_LSM6DSL_DataLog_Terminal/DISCO_IOT_LSM6DSL_DataLog_Terminal.ino @@ -47,8 +47,8 @@ #define I2C2_SDA PB11 // Components. -LSM6DSLSensor *AccGyr; -TwoWire *dev_i2c; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); void setup() { // Led. @@ -57,13 +57,12 @@ void setup() { SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); // Initlialize components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); - AccGyr->Enable_G(); + AccGyr.begin(); + AccGyr.Enable_X(); + AccGyr.Enable_G(); } void loop() { @@ -76,8 +75,8 @@ void loop() { // Read accelerometer and gyroscope. int32_t accelerometer[3]; int32_t gyroscope[3]; - AccGyr->Get_X_Axes(accelerometer); - AccGyr->Get_G_Axes(gyroscope); + AccGyr.Get_X_Axes(accelerometer); + AccGyr.Get_G_Axes(gyroscope); // Output data. SerialPort.print("Acc[mg]: "); diff --git a/examples/DISCO_IOT_MultiEvent/DISCO_IOT_MultiEvent.ino b/examples/DISCO_IOT_MultiEvent/DISCO_IOT_MultiEvent.ino index 387423f..f2596fb 100644 --- a/examples/DISCO_IOT_MultiEvent/DISCO_IOT_MultiEvent.ino +++ b/examples/DISCO_IOT_MultiEvent/DISCO_IOT_MultiEvent.ino @@ -56,7 +56,8 @@ #define INT1 PD11 // Components. -LSM6DSLSensor *AccGyr; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); //Interrupts. volatile int mems_event = 0; @@ -66,30 +67,28 @@ char report[256]; void INT1Event_cb(); void sendOrientation(); -TwoWire *dev_i2c; void setup() { // Initialize serial for output. SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); //Interrupts. attachInterrupt(INT1, INT1Event_cb, RISING); // Initlialize Components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); + AccGyr.begin(); + AccGyr.Enable_X(); // Enable all HW events. - AccGyr->Enable_Pedometer(); - AccGyr->Enable_Tilt_Detection(); - AccGyr->Enable_Free_Fall_Detection(); - AccGyr->Enable_Single_Tap_Detection(); - AccGyr->Enable_Double_Tap_Detection(); - AccGyr->Enable_6D_Orientation(); + AccGyr.Enable_Pedometer(); + AccGyr.Enable_Tilt_Detection(); + AccGyr.Enable_Free_Fall_Detection(); + AccGyr.Enable_Single_Tap_Detection(); + AccGyr.Enable_Double_Tap_Detection(); + AccGyr.Enable_6D_Orientation(); } void loop() { @@ -97,12 +96,12 @@ void loop() { { mems_event = 0; LSM6DSL_Event_Status_t status; - AccGyr->Get_Event_Status(&status); + AccGyr.Get_Event_Status(&status); if (status.StepStatus) { // New step detected, so print the step counter - AccGyr->Get_Step_Counter(&step_count); + AccGyr.Get_Step_Counter(&step_count); snprintf(report, sizeof(report), "Step counter: %d", step_count); SerialPort.println(report); } @@ -153,12 +152,12 @@ void sendOrientation() uint8_t zl = 0; uint8_t zh = 0; - AccGyr->Get_6D_Orientation_XL(&xl); - AccGyr->Get_6D_Orientation_XH(&xh); - AccGyr->Get_6D_Orientation_YL(&yl); - AccGyr->Get_6D_Orientation_YH(&yh); - AccGyr->Get_6D_Orientation_ZL(&zl); - AccGyr->Get_6D_Orientation_ZH(&zh); + AccGyr.Get_6D_Orientation_XL(&xl); + AccGyr.Get_6D_Orientation_XH(&xh); + AccGyr.Get_6D_Orientation_YL(&yl); + AccGyr.Get_6D_Orientation_YH(&yh); + AccGyr.Get_6D_Orientation_ZL(&zl); + AccGyr.Get_6D_Orientation_ZH(&zh); if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 1 && zh == 0 ) { diff --git a/examples/DISCO_IOT_Pedometer/DISCO_IOT_Pedometer.ino b/examples/DISCO_IOT_Pedometer/DISCO_IOT_Pedometer.ino index 30d6c9c..0943496 100644 --- a/examples/DISCO_IOT_Pedometer/DISCO_IOT_Pedometer.ino +++ b/examples/DISCO_IOT_Pedometer/DISCO_IOT_Pedometer.ino @@ -49,8 +49,8 @@ #define INT1 PD11 // Components. -LSM6DSLSensor *AccGyr; -TwoWire *dev_i2c; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); //Interrupts. volatile int mems_event = 0; @@ -70,18 +70,17 @@ void setup() { SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); //Interrupts. attachInterrupt(INT1, INT1Event_cb, RISING); // Initlialize Components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); + AccGyr.begin(); + AccGyr.Enable_X(); // Enable Pedometer. - AccGyr->Enable_Pedometer(); + AccGyr.Enable_Pedometer(); previous_tick = millis(); } @@ -91,11 +90,11 @@ void loop() { { mems_event = 0; LSM6DSL_Event_Status_t status; - AccGyr->Get_Event_Status(&status); + AccGyr.Get_Event_Status(&status); if (status.StepStatus) { // New step detected, so print the step counter - AccGyr->Get_Step_Counter(&step_count); + AccGyr.Get_Step_Counter(&step_count); snprintf(report, sizeof(report), "Step counter: %d", step_count); SerialPort.println(report); @@ -110,7 +109,7 @@ void loop() { current_tick = millis(); if((current_tick - previous_tick) >= 3000) { - AccGyr->Get_Step_Counter(&step_count); + AccGyr.Get_Step_Counter(&step_count); snprintf(report, sizeof(report), "Step counter: %d", step_count); SerialPort.println(report); previous_tick = millis(); diff --git a/examples/DISCO_IOT_Tap/DISCO_IOT_Tap.ino b/examples/DISCO_IOT_Tap/DISCO_IOT_Tap.ino index 66815cd..375d011 100644 --- a/examples/DISCO_IOT_Tap/DISCO_IOT_Tap.ino +++ b/examples/DISCO_IOT_Tap/DISCO_IOT_Tap.ino @@ -49,8 +49,8 @@ #define INT1 PD11 // Components. -LSM6DSLSensor *AccGyr; -TwoWire *dev_i2c; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); //Interrupts. volatile int mems_event = 0; @@ -65,25 +65,24 @@ void setup() { SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); //Interrupts. attachInterrupt(INT1, INT1Event_cb, RISING); // Initlialize Components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); + AccGyr.begin(); + AccGyr.Enable_X(); // Enable Single Tap Detection. - AccGyr->Enable_Single_Tap_Detection(); + AccGyr.Enable_Single_Tap_Detection(); } void loop() { if (mems_event) { mems_event = 0; LSM6DSL_Event_Status_t status; - AccGyr->Get_Event_Status(&status); + AccGyr.Get_Event_Status(&status); if (status.TapStatus) { // Led blinking. diff --git a/examples/DISCO_IOT_Tilt/DISCO_IOT_Tilt.ino b/examples/DISCO_IOT_Tilt/DISCO_IOT_Tilt.ino index 013a755..6656b9c 100644 --- a/examples/DISCO_IOT_Tilt/DISCO_IOT_Tilt.ino +++ b/examples/DISCO_IOT_Tilt/DISCO_IOT_Tilt.ino @@ -49,8 +49,8 @@ #define INT1 PD11 // Components. -LSM6DSLSensor *AccGyr; -TwoWire *dev_i2c; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); //Interrupts. volatile int mems_event = 0; @@ -65,25 +65,24 @@ void setup() { SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); //Interrupts. attachInterrupt(INT1, INT1Event_cb, RISING); // Initlialize Components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); + AccGyr.begin(); + AccGyr.Enable_X(); // Enable Tilt Detection. - AccGyr->Enable_Tilt_Detection(); + AccGyr.Enable_Tilt_Detection(); } void loop() { if (mems_event) { mems_event = 0; LSM6DSL_Event_Status_t status; - AccGyr->Get_Event_Status(&status); + AccGyr.Get_Event_Status(&status); if (status.TiltStatus) { // Led blinking. diff --git a/examples/DISCO_IOT_WakeUp/DISCO_IOT_WakeUp.ino b/examples/DISCO_IOT_WakeUp/DISCO_IOT_WakeUp.ino index 268f64d..6cc5699 100644 --- a/examples/DISCO_IOT_WakeUp/DISCO_IOT_WakeUp.ino +++ b/examples/DISCO_IOT_WakeUp/DISCO_IOT_WakeUp.ino @@ -49,8 +49,8 @@ #define INT1 PD11 // Components. -LSM6DSLSensor *AccGyr; -TwoWire *dev_i2c; +TwoWire dev_i2c(I2C2_SDA, I2C2_SCL); +LSM6DSLSensor AccGyr(&dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); //Interrupts. volatile int mems_event = 0; @@ -65,25 +65,24 @@ void setup() { SerialPort.begin(9600); // Initialize I2C bus. - dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); - dev_i2c->begin(); + dev_i2c.begin(); //Interrupts. attachInterrupt(INT1, INT1Event_cb, RISING); // Initlialize Components. - AccGyr = new LSM6DSLSensor(dev_i2c, LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW); - AccGyr->Enable_X(); + AccGyr.begin(); + AccGyr.Enable_X(); // Enable Wake Up Detection. - AccGyr->Enable_Wake_Up_Detection(LSM6DSL_INT1_PIN); + AccGyr.Enable_Wake_Up_Detection(LSM6DSL_INT1_PIN); } void loop() { if (mems_event) { mems_event = 0; LSM6DSL_Event_Status_t status; - AccGyr->Get_Event_Status(&status); + AccGyr.Get_Event_Status(&status); if (status.WakeUpStatus) { // Led blinking. diff --git a/keywords.txt b/keywords.txt index dc1b13d..84c7f50 100644 --- a/keywords.txt +++ b/keywords.txt @@ -12,6 +12,8 @@ LSM6DSLSensor KEYWORD1 # Methods and Functions (KEYWORD2) ####################################### +begin KEYWORD2 +end KEYWORD2 Enable_X KEYWORD2 Enable_G KEYWORD2 Disable_X KEYWORD2 diff --git a/library.properties b/library.properties index b8edca6..7527fba 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=STM32duino LSM6DSL -version=1.0.4 +version=2.0.0 author=AST, Wi6Labs maintainer=stm32duino sentence=3D accelerometer and 3D gyroscope. paragraph=This library provides Arduino support for the 3D accelerometer and 3D gyroscope LSM6DSL for STM32 boards. category=Sensors url=https://github.com/stm32duino/LSM6DSL -architectures=stm32 +architectures=stm32, avr, sam diff --git a/src/LSM6DSLSensor.cpp b/src/LSM6DSLSensor.cpp index 3aecbc1..066c735 100644 --- a/src/LSM6DSLSensor.cpp +++ b/src/LSM6DSLSensor.cpp @@ -45,56 +45,84 @@ /* Class Implementation ------------------------------------------------------*/ - /** Constructor * @param i2c object of an helper class which handles the I2C peripheral * @param address the address of the component's instance */ -LSM6DSLSensor::LSM6DSLSensor(TwoWire *i2c) : dev_i2c(i2c) +LSM6DSLSensor::LSM6DSLSensor(TwoWire *i2c, uint8_t address) : dev_i2c(i2c), address(address) +{ + dev_spi = NULL; + X_isEnabled = 0; + G_isEnabled = 0; +} + +/** Constructor + * @param spi object of an helper class which handles the SPI peripheral + * @param cs_pin the chip select pin + * @param spi_speed the SPI speed + */ +LSM6DSLSensor::LSM6DSLSensor(SPIClass *spi, int cs_pin, uint32_t spi_speed) : dev_spi(spi), cs_pin(cs_pin), spi_speed(spi_speed) { - address = LSM6DSL_ACC_GYRO_I2C_ADDRESS_HIGH; + dev_i2c = NULL; + address = 0; + X_isEnabled = 0U; + G_isEnabled = 0U; +} + +/** + * @brief Configure the sensor in order to be used + * @retval 0 in case of success, an error code otherwise + */ +LSM6DSLStatusTypeDef LSM6DSLSensor::begin() +{ + if(dev_spi) + { + // Configure CS pin + pinMode(cs_pin, OUTPUT); + digitalWrite(cs_pin, HIGH); + } /* Enable register address automatically incremented during a multiple byte access with a serial interface. */ if ( LSM6DSL_ACC_GYRO_W_IF_Addr_Incr( (void *)this, LSM6DSL_ACC_GYRO_IF_INC_ENABLED ) == MEMS_ERROR ) { - return; + return LSM6DSL_STATUS_ERROR; } /* Enable BDU */ if ( LSM6DSL_ACC_GYRO_W_BDU( (void *)this, LSM6DSL_ACC_GYRO_BDU_BLOCK_UPDATE ) == MEMS_ERROR ) { - return; + return LSM6DSL_STATUS_ERROR; } /* FIFO mode selection */ if ( LSM6DSL_ACC_GYRO_W_FIFO_MODE( (void *)this, LSM6DSL_ACC_GYRO_FIFO_MODE_BYPASS ) == MEMS_ERROR ) { - return; + return LSM6DSL_STATUS_ERROR; } /* Output data rate selection - power down. */ if ( LSM6DSL_ACC_GYRO_W_ODR_XL( (void *)this, LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN ) == MEMS_ERROR ) { - return; + return LSM6DSL_STATUS_ERROR; } /* Full scale selection. */ if ( Set_X_FS( 2.0f ) == LSM6DSL_STATUS_ERROR ) { - return; + return LSM6DSL_STATUS_ERROR; } /* Output data rate selection - power down */ if ( LSM6DSL_ACC_GYRO_W_ODR_G( (void *)this, LSM6DSL_ACC_GYRO_ODR_G_POWER_DOWN ) == MEMS_ERROR ) { - return; + return LSM6DSL_STATUS_ERROR; } /* Full scale selection. */ if ( Set_G_FS( 2000.0f ) == LSM6DSL_STATUS_ERROR ) { - return; + return LSM6DSL_STATUS_ERROR; } X_Last_ODR = 104.0f; @@ -104,65 +132,36 @@ LSM6DSLSensor::LSM6DSLSensor(TwoWire *i2c) : dev_i2c(i2c) G_Last_ODR = 104.0f; G_isEnabled = 0; -}; -/** Constructor - * @param i2c object of an helper class which handles the I2C peripheral - * @param address the address of the component's instance + return LSM6DSL_STATUS_OK; +} + +/** + * @brief Disable the sensor and relative resources + * @retval 0 in case of success, an error code otherwise */ -LSM6DSLSensor::LSM6DSLSensor(TwoWire *i2c, uint8_t address) : dev_i2c(i2c), address(address) +LSM6DSLStatusTypeDef LSM6DSLSensor::end() { - /* Enable register address automatically incremented during a multiple byte - access with a serial interface. */ - if ( LSM6DSL_ACC_GYRO_W_IF_Addr_Incr( (void *)this, LSM6DSL_ACC_GYRO_IF_INC_ENABLED ) == MEMS_ERROR ) + /* Disable both acc and gyro */ + if (Disable_X() != LSM6DSL_STATUS_OK) { - return; - } - - /* Enable BDU */ - if ( LSM6DSL_ACC_GYRO_W_BDU( (void *)this, LSM6DSL_ACC_GYRO_BDU_BLOCK_UPDATE ) == MEMS_ERROR ) - { - return; - } - - /* FIFO mode selection */ - if ( LSM6DSL_ACC_GYRO_W_FIFO_MODE( (void *)this, LSM6DSL_ACC_GYRO_FIFO_MODE_BYPASS ) == MEMS_ERROR ) - { - return; - } - - /* Output data rate selection - power down. */ - if ( LSM6DSL_ACC_GYRO_W_ODR_XL( (void *)this, LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN ) == MEMS_ERROR ) - { - return; - } - - /* Full scale selection. */ - if ( Set_X_FS( 2.0f ) == LSM6DSL_STATUS_ERROR ) - { - return; + return LSM6DSL_STATUS_ERROR; } - /* Output data rate selection - power down */ - if ( LSM6DSL_ACC_GYRO_W_ODR_G( (void *)this, LSM6DSL_ACC_GYRO_ODR_G_POWER_DOWN ) == MEMS_ERROR ) + if (Disable_G() != LSM6DSL_STATUS_OK) { - return; + return LSM6DSL_STATUS_ERROR; } - /* Full scale selection. */ - if ( Set_G_FS( 2000.0f ) == LSM6DSL_STATUS_ERROR ) + /* Reset CS configuration */ + if(dev_spi) { - return; + // Configure CS pin + pinMode(cs_pin, INPUT); } - X_Last_ODR = 104.0f; - - X_isEnabled = 0; - - G_Last_ODR = 104.0f; - - G_isEnabled = 0; -}; + return LSM6DSL_STATUS_OK; +} /** * @brief Enable LSM6DSL Accelerator diff --git a/src/LSM6DSLSensor.h b/src/LSM6DSLSensor.h index 7f6de00..955f32d 100644 --- a/src/LSM6DSLSensor.h +++ b/src/LSM6DSLSensor.h @@ -46,6 +46,7 @@ /* Includes ------------------------------------------------------------------*/ #include "Wire.h" +#include "SPI.h" #include "LSM6DSL_ACC_GYRO_Driver.h" /* Defines -------------------------------------------------------------------*/ @@ -130,8 +131,10 @@ typedef struct class LSM6DSLSensor { public: - LSM6DSLSensor (TwoWire *i2c); - LSM6DSLSensor (TwoWire *i2c, uint8_t address); + LSM6DSLSensor (TwoWire *i2c, uint8_t address=LSM6DSL_ACC_GYRO_I2C_ADDRESS_HIGH); + LSM6DSLSensor (SPIClass *spi, int cs_pin, uint32_t spi_speed=2000000); + LSM6DSLStatusTypeDef begin (void); + LSM6DSLStatusTypeDef end (void); LSM6DSLStatusTypeDef Enable_X (void); LSM6DSLStatusTypeDef Enable_G (void); LSM6DSLStatusTypeDef Disable_X (void); @@ -199,20 +202,43 @@ class LSM6DSLSensor */ uint8_t IO_Read(uint8_t* pBuffer, uint8_t RegisterAddr, uint16_t NumByteToRead) { - dev_i2c->beginTransmission(((uint8_t)(((address) >> 1) & 0x7F))); - dev_i2c->write(RegisterAddr); - dev_i2c->endTransmission(false); + if (dev_spi) { + dev_spi->beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3)); - dev_i2c->requestFrom(((uint8_t)(((address) >> 1) & 0x7F)), (byte) NumByteToRead); + digitalWrite(cs_pin, LOW); - int i=0; - while (dev_i2c->available()) - { - pBuffer[i] = dev_i2c->read(); - i++; + /* Write Reg Address */ + dev_spi->transfer(RegisterAddr | 0x80); + /* Read the data */ + for (uint16_t i=0; itransfer(0x00); + } + + digitalWrite(cs_pin, HIGH); + + dev_spi->endTransaction(); + + return 0; + } + + if (dev_i2c) { + dev_i2c->beginTransmission(((uint8_t)(((address) >> 1) & 0x7F))); + dev_i2c->write(RegisterAddr); + dev_i2c->endTransmission(false); + + dev_i2c->requestFrom(((uint8_t)(((address) >> 1) & 0x7F)), (byte) NumByteToRead); + + int i=0; + while (dev_i2c->available()) + { + pBuffer[i] = dev_i2c->read(); + i++; + } + + return 0; } - return 0; + return 1; } /** @@ -224,15 +250,38 @@ class LSM6DSLSensor */ uint8_t IO_Write(uint8_t* pBuffer, uint8_t RegisterAddr, uint16_t NumByteToWrite) { - dev_i2c->beginTransmission(((uint8_t)(((address) >> 1) & 0x7F))); + if (dev_spi) { + dev_spi->beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3)); + + digitalWrite(cs_pin, LOW); - dev_i2c->write(RegisterAddr); - for (int i = 0 ; i < NumByteToWrite ; i++) - dev_i2c->write(pBuffer[i]); + /* Write Reg Address */ + dev_spi->transfer(RegisterAddr); + /* Write the data */ + for (uint16_t i=0; itransfer(pBuffer[i]); + } - dev_i2c->endTransmission(true); + digitalWrite(cs_pin, HIGH); + + dev_spi->endTransaction(); + + return 0; + } + + if (dev_i2c) { + dev_i2c->beginTransmission(((uint8_t)(((address) >> 1) & 0x7F))); - return 0; + dev_i2c->write(RegisterAddr); + for (int i = 0 ; i < NumByteToWrite ; i++) + dev_i2c->write(pBuffer[i]); + + dev_i2c->endTransmission(true); + + return 0; + } + + return 1; } private: @@ -243,9 +292,12 @@ class LSM6DSLSensor /* Helper classes. */ TwoWire *dev_i2c; - + SPIClass *dev_spi; + /* Configuration */ uint8_t address; + int cs_pin; + uint32_t spi_speed; uint8_t X_isEnabled; float X_Last_ODR;