Browse Source

Refactor Accelerometer/Magnetometer code to enable new drivers

master
Joe Finney 4 years ago
parent
commit
ff29f2133e
28 changed files with 3280 additions and 2159 deletions
  1. +1
    -0
      .gitignore
  2. +3
    -0
      inc/core/MicroBitComponent.h
  3. +61
    -0
      inc/core/MicroBitUtil.h
  4. +240
    -0
      inc/drivers/FXOS8700.h
  5. +152
    -0
      inc/drivers/LSM303Accelerometer.h
  6. +139
    -0
      inc/drivers/LSM303Magnetometer.h
  7. +134
    -0
      inc/drivers/MAG3110.h
  8. +128
    -0
      inc/drivers/MMA8653.h
  9. +262
    -364
      inc/drivers/MicroBitAccelerometer.h
  10. +241
    -467
      inc/drivers/MicroBitCompass.h
  11. +29
    -0
      inc/drivers/MicroBitI2C.h
  12. +3
    -1
      inc/drivers/MicroBitIO.h
  13. +166
    -0
      inc/types/CoordinateSystem.h
  14. +0
    -67
      inc/types/MicroBitCoordinateSystem.h
  15. +7
    -0
      source/CMakeLists.txt
  16. +0
    -293
      source/asm/CortexContextSwitch.s
  17. +65
    -0
      source/core/MicroBitUtil.cpp
  18. +285
    -0
      source/drivers/FXOS8700.cpp
  19. +193
    -0
      source/drivers/LSM303Accelerometer.cpp
  20. +165
    -0
      source/drivers/LSM303Magnetometer.cpp
  21. +199
    -0
      source/drivers/MAG3110.cpp
  22. +215
    -0
      source/drivers/MMA8653.cpp
  23. +133
    -341
      source/drivers/MicroBitAccelerometer.cpp
  24. +271
    -620
      source/drivers/MicroBitCompass.cpp
  25. +9
    -4
      source/drivers/MicroBitCompassCalibrator.cpp
  26. +55
    -0
      source/drivers/MicroBitI2C.cpp
  27. +4
    -2
      source/drivers/MicroBitIO.cpp
  28. +120
    -0
      source/types/CoordinateSystem.cpp

+ 1
- 0
.gitignore View File

@ -3,4 +3,5 @@ build
yotta_modules
yotta_targets
*.swp
*~
Makefile

+ 3
- 0
inc/core/MicroBitComponent.h View File

@ -68,6 +68,9 @@ DEALINGS IN THE SOFTWARE.
#define MICROBIT_ID_MULTIBUTTON_ATTACH 31
#define MICROBIT_ID_SERIAL 32
#define MICROBIT_ID_IO_INT1 33 //INT1
#define MICROBIT_ID_IO_INT2 34 //INT2
#define MICROBIT_ID_MESSAGE_BUS_LISTENER 1021 // Message bus indication that a handler for a given ID has been registered.
#define MICROBIT_ID_NOTIFY_ONE 1022 // Notfication channel, for general purpose synchronisation
#define MICROBIT_ID_NOTIFY 1023 // Notfication channel, for general purpose synchronisation


+ 61
- 0
inc/core/MicroBitUtil.h View File

@ -0,0 +1,61 @@
/*
The MIT License (MIT)
Copyright (c) 2017 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN 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.
*/
/**
* This file contains functions used to maintain compatability and portability.
* It also contains constants that are used elsewhere in the DAL.
*/
#ifndef MICROBIT_UTIL_H
#define MICROBIT_UTIL_H
#include "MicroBitConfig.h"
#define CREATE_KEY_VALUE_TABLE(NAME, PAIRS) const KeyValueTable NAME { PAIRS, sizeof(PAIRS) / sizeof(KeyValueTableEntry) };
/**
* Provides a simple key/value pair lookup table with range lookup support.
* Normally stored in FLASH to reduce RAM usage. Keys should be pre-sorted
* in ascending order.
*/
struct KeyValueTableEntry
{
const uint32_t key;
const uint32_t value;
};
struct KeyValueTable
{
const KeyValueTableEntry *data;
const int length;
KeyValueTableEntry* find(const uint32_t key) const;
uint32_t get(const uint32_t key) const;
uint32_t getKey(const uint32_t key) const;
bool hasKey(const uint32_t key) const;
};
#endif

+ 240
- 0
inc/drivers/FXOS8700.h View File

@ -0,0 +1,240 @@
/*
The MIT License (MIT)
Copyright (c) 2017 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN 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.
*/
#ifndef FXOS8700_H
#define FXOS8700_H
#include "MicroBitConfig.h"
#include "MicroBitComponent.h"
#include "MicroBitPin.h"
#include "MicroBitI2C.h"
#include "MicroBitAccelerometer.h"
#include "MicroBitCompass.h"
#include "CoordinateSystem.h"
#include "MicroBitUtil.h"
/**
* I2C constants
*/
#define FXOS8700_DEFAULT_ADDR 0x3C
/**
* FXOS8700 Register map
*/
#define FXOS8700_STATUS_REG 0x00
#define FXOS8700_OUT_X_MSB 0x01
#define FXOS8700_OUT_X_LSB 0x02
#define FXOS8700_OUT_Y_MSB 0x03
#define FXOS8700_OUT_Y_LSB 0x04
#define FXOS8700_OUT_Z_MSB 0x05
#define FXOS8700_OUT_Z_LSB 0x06
#define FXOS8700_F_SETUP 0x09
#define FXOS8700_TRIG_CFG 0x0A
#define FXOS8700_SYSMOD 0x0B
#define FXOS8700_INT_SOURCE 0x0C
#define FXOS8700_WHO_AM_I 0x0D
#define FXOS8700_XYZ_DATA_CFG 0x0E
#define FXOS8700_HP_FILTER_CUTOFF 0x0F
#define FXOS8700_PL_STATUS 0x10
#define FXOS8700_PL_CFG 0x11
#define FXOS8700_PL_COUNT 0x12
#define FXOS8700_PL_BF_ZCOMP 0x13
#define FXOS8700_PL_THS_REG 0x14
#define FXOS8700_A_FFMT_CFG 0x15
#define FXOS8700_A_FFMT_SRC 0x16
#define FXOS8700_A_FFMT_THS 0x17
#define FXOS8700_A_FFMT_COUNT 0x18
#define FXOS8700_TRANSIENT_CFG 0x1D
#define FXOS8700_TRANSIENT_SRC 0x1E
#define FXOS8700_TRANSIENT_THS 0x1F
#define FXOS8700_TRANSIENT_COUNT 0x20
#define FXOS8700_PULSE_CFG 0x21
#define FXOS8700_PULSE_SRC 0x22
#define FXOS8700_PULSE_THSX 0x23
#define FXOS8700_PULSE_THSY 0x24
#define FXOS8700_PULSE_THSZ 0x25
#define FXOS8700_PULSE_TMLT 0x26
#define FXOS8700_PULSE_LTCY 0x27
#define FXOS8700_PULSE_WIND 0x28
#define FXOS8700_ASLP_COUNT 0x29
#define FXOS8700_CTRL_REG1 0x2A
#define FXOS8700_CTRL_REG2 0x2B
#define FXOS8700_CTRL_REG3 0x2C
#define FXOS8700_CTRL_REG4 0x2D
#define FXOS8700_CTRL_REG5 0x2E
#define FXOS8700_OFF_X 0x2F
#define FXOS8700_OFF_Y 0x30
#define FXOS8700_OFF_Z 0x31
#define FXOS8700_M_DR_STATUS 0x32
#define FXOS8700_M_OUT_X_MSB 0x33
#define FXOS8700_M_OUT_X_LSB 0x34
#define FXOS8700_M_OUT_Y_MSB 0x35
#define FXOS8700_M_OUT_Y_LSB 0x36
#define FXOS8700_M_OUT_Z_MSB 0x37
#define FXOS8700_M_OUT_Z_LSB 0x38
#define FXOS8700_CMP_X_MSB 0x39
#define FXOS8700_CMP_X_LSB 0x3A
#define FXOS8700_CMP_Y_MSB 0x3B
#define FXOS8700_CMP_Y_LSB 0x3C
#define FXOS8700_CMP_Z_MSB 0x3D
#define FXOS8700_CMP_Z_LSB 0x3E
#define FXOS8700_M_OFF_X_MSB 0x3F
#define FXOS8700_M_OFF_X_LSB 0x40
#define FXOS8700_M_OFF_Y_MSB 0x41
#define FXOS8700_M_OFF_Y_LSB 0x42
#define FXOS8700_M_OFF_Z_MSB 0x43
#define FXOS8700_M_OFF_Z_LSB 0x44
#define FXOS8700_MAX_X_MSB 0x45
#define FXOS8700_MAX_X_LSB 0x46
#define FXOS8700_MAX_Y_MSB 0x47
#define FXOS8700_MAX_Y_LSB 0x48
#define FXOS8700_MAX_Z_MSB 0x49
#define FXOS8700_MAX_Z_LSB 0x4A
#define FXOS8700_MIN_X_MSB 0x4B
#define FXOS8700_MIN_X_LSB 0x4C
#define FXOS8700_MIN_Y_MSB 0x4D
#define FXOS8700_MIN_Y_LSB 0x4E
#define FXOS8700_MIN_Z_MSB 0x4F
#define FXOS8700_MIN_Z_LSB 0x50
#define FXOS8700_TEMP 0x51
#define FXOS8700_M_THS_CFG 0x52
#define FXOS8700_M_THS_SRC 0x53
#define FXOS8700_M_THS_X_MSB 0x54
#define FXOS8700_M_THS_X_LSB 0x55
#define FXOS8700_M_THS_Y_MSB 0x56
#define FXOS8700_M_THS_Y_LSB 0x57
#define FXOS8700_M_THS_Z_MSB 0x58
#define FXOS8700_M_THS_Z_LSB 0x59
#define FXOS8700_M_THS_COUNT 0x5A
#define FXOS8700_M_CTRL_REG1 0x5B
#define FXOS8700_M_CTRL_REG2 0x5C
#define FXOS8700_M_CTRL_REG3 0x5D
#define FXOS8700_M_INT_SRC 0x5E
#define FXOS8700_A_VECM_CFG 0x5F
#define FXOS8700_A_VECM_THS_MSB 0x60
#define FXOS8700_A_VECM_THS_LSB 0x61
#define FXOS8700_A_VECM_CNT 0x62
#define FXOS8700_A_VECM_INITX_MSB 0x63
#define FXOS8700_A_VECM_INITX_LSB 0x64
#define FXOS8700_A_VECM_INITY_MSB 0x65
#define FXOS8700_A_VECM_INITY_LSB 0x66
#define FXOS8700_A_VECM_INITZ_MSB 0x67
#define FXOS8700_A_VECM_INITZ_LSB 0x68
#define FXOS8700_M_VECM_CFG 0x69
#define FXOS8700_M_VECM_THS_MSB 0x6A
#define FXOS8700_M_VECM_THS_LSB 0x6B
#define FXOS8700_M_VECM_CNT 0x6C
#define FXOS8700_M_VECM_INITX_MSB 0x6D
#define FXOS8700_M_VECM_INITX_LSB 0x6E
#define FXOS8700_M_VECM_INITY_MSB 0x6F
#define FXOS8700_M_VECM_INITY_LSB 0x70
#define FXOS8700_M_VECM_INITZ_MSB 0x71
#define FXOS8700_M_VECM_INITZ_LSB 0x72
#define FXOS8700_A_FFMT_THS_X_MSB 0x73
#define FXOS8700_A_FFMT_THS_X_LSB 0x74
#define FXOS8700_A_FFMT_THS_Y_MSB 0x75
#define FXOS8700_A_FFMT_THS_Y_LSB 0x76
#define FXOS8700_A_FFMT_THS_Z_MSB 0x77
#define FXOS8700_A_FFMT_THS_Z_LSB 0x78
/**
* FXOS8700 constants
*/
#define FXOS8700_WHOAMI_VAL 0xC7
/**
* Class definition for an FXSO8700 hybrid Accelerometer/Magnetometer
*/
class FXOS8700 : public MicroBitAccelerometer, public MicroBitCompass
{
MicroBitI2C& i2c; // The I2C interface to use.
MicroBitPin &int1; // Data ready interrupt.
uint16_t address; // I2C address of this accelerometer.
public:
/**
* Constructor.
* Create a software abstraction of an accelerometer.
*
* @param _i2c an instance of I2C used to communicate with the onboard accelerometer.
* @param _int1 a pin connected to the INT1 interrupt source of the sensor.
* @param address the default I2C address of the accelerometer. Defaults to: FXOS8700_DEFAULT_ADDR.
*
*/
FXOS8700(MicroBitI2C &_i2c, MicroBitPin &_int1, CoordinateSpace &coordinateSpace, uint16_t address = FXOS8700_DEFAULT_ADDR, uint16_t aid = MICROBIT_ID_ACCELEROMETER, uint16_t cid = MICROBIT_ID_COMPASS);
/**
* Configures the accelerometer for G range and sample rate defined
* in this object. The nearest values are chosen to those defined
* that are supported by the hardware. The instance variables are then
* updated to reflect reality.
*
* @return DEVICE_OK on success, DEVICE_I2C_ERROR if the accelerometer could not be configured.
*/
int configure();
/**
* Reads the acceleration data from the accelerometer, and stores it in our buffer.
* This only happens if the accelerometer indicates that it has new data via int1.
*
* On first use, this member function will attempt to add this component to the
* list of fiber components in order to constantly update the values stored
* by this object.
*
* This technique is called lazy instantiation, and it means that we do not
* obtain the overhead from non-chalantly adding this component to fiber components.
*
* @return DEVICE_OK on success, DEVICE_I2C_ERROR if the read request fails.
*/
virtual int requestUpdate();
/**
* Attempts to read the 8 bit ID from the accelerometer, this can be used for
* validation purposes.
*
* @return the 8 bit ID returned by the accelerometer, or DEVICE_I2C_ERROR if the request fails.
*
* @code
* accelerometer.whoAmI();
* @endcode
*/
int whoAmI();
/**
* A periodic callback invoked by the fiber scheduler idle thread.
*
* Internally calls updateSample().
*/
virtual void idleCallback();
/**
* Destructor.
*/
~FXOS8700();
};
#endif

+ 152
- 0
inc/drivers/LSM303Accelerometer.h View File

@ -0,0 +1,152 @@
/*
The MIT License (MIT)
Copyright (c) 2017 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN 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.
*/
#ifndef LSM303_A_H
#define LSM303_A_H
#include "MicroBitConfig.h"
#include "MicroBitComponent.h"
#include "CoordinateSystem.h"
#include "MicroBitAccelerometer.h"
#include "MicroBitI2C.h"
#include "MicroBitUtil.h"
/**
* I2C constants
*/
#define LSM303_A_DEFAULT_ADDR 0x32
/**
* LSM303 Register map (partial)
*/
#define LSM303_STATUS_REG_AUX_A 0x07
#define LSM303_OUT_TEMP_L_A 0x0C
#define LSM303_OUT_TEMP_H_A 0x0D
#define LSM303_INT_COUNTER_REG_A 0x0E
#define LSM303_WHO_AM_I_A 0x0F
#define LSM303_TEMP_CFG_REG_A 0x1F
#define LSM303_CTRL_REG1_A 0x20
#define LSM303_CTRL_REG2_A 0x21
#define LSM303_CTRL_REG3_A 0x22
#define LSM303_CTRL_REG4_A 0x23
#define LSM303_CTRL_REG5_A 0x24
#define LSM303_CTRL_REG6_A 0x25
#define LSM303_DATACAPTURE_A 0x26
#define LSM303_STATUS_REG_A 0x27
#define LSM303_OUT_X_L_A 0x28
#define LSM303_OUT_X_H_A 0x29
#define LSM303_OUT_Y_L_A 0x2A
#define LSM303_OUT_Y_H_A 0x2B
#define LSM303_OUT_Z_L_A 0x2C
#define LSM303_OUT_Z_H_A 0x2D
#define LSM303_FIFO_CTRL_REG_A 0x2E
#define LSM303_FIFO_SRC_REG_A 0x2F
#define LSM303_INT1_CFG_A 0x30
#define LSM303_INT1_SRC_A 0x31
#define LSM303_INT1_THS_A 0x32
#define LSM303_INT1_DURATION_A 0x33
#define LSM303_INT2_CFG_A 0x34
#define LSM303_INT2_SRC_A 0x35
#define LSM303_INT2_THS_A 0x36
#define LSM303_INT2_DURATION_A 0x37
#define LSM303_CLICK_CFG_A 0x38
#define LSM303_CLICK_SRC_A 0x39
#define LSM303_CLICK_THS_A 0x3A
#define LSM303_TIME_LIMIT_A 0x3B
#define LSM303_TIME_LATENCY_A 0x3C
#define LSM303_TIME_WINDOW_A 0x3D
#define LSM303_ACT_THS_A 0x3E
#define LSM303_ACT_DUR_A 0x3F
/**
* LSM303_A constants
*/
#define LSM303_A_WHOAMI_VAL 0x33
/**
* Class definition for LSM303Accelerometer.
* This class provides a simple wrapper between the hybrid FXOS8700 accelerometer and higher level accelerometer funcitonality.
*/
class LSM303Accelerometer : public MicroBitAccelerometer
{
MicroBitI2C& i2c; // The I2C interface to use.
MicroBitPin& int1; // Data ready interrupt.
uint16_t address; // I2C address of this accelerometer.
public:
/**
* Constructor.
* Create a software abstraction of an accelerometer.
*
* @param coordinateSpace The orientation of the sensor. Defaults to: SIMPLE_CARTESIAN
* @param id The unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER
*
*/
LSM303Accelerometer(MicroBitI2C& _i2c, MicroBitPin &_int1, CoordinateSpace &coordinateSpace, uint16_t address = LSM303_A_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_ACCELEROMETER);
/**
* Configures the accelerometer for G range and sample rate defined
* in this object. The nearest values are chosen to those defined
* that are supported by the hardware. The instance variables are then
* updated to reflect reality.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured.
*
* @note This method should be overidden by the hardware driver to implement the requested
* changes in hardware.
*/
virtual int configure();
/**
* Poll to see if new data is available from the hardware. If so, update it.
* n.b. it is not necessary to explicitly call this funciton to update data
* (it normally happens in the background when the scheduler is idle), but a check is performed
* if the user explicitly requests up to date data.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the update fails.
*
* @note This method should be overidden by the hardware driver to implement the requested
* changes in hardware.
*/
virtual int requestUpdate();
/**
* A periodic callback invoked by the fiber scheduler idle thread.
*
* Internally calls updateSample().
*/
virtual void idleCallback();
/**
* Destructor.
*/
~LSM303Accelerometer();
};
#endif

+ 139
- 0
inc/drivers/LSM303Magnetometer.h View File

@ -0,0 +1,139 @@
/*
The MIT License (MIT)
Copyright (c) 2017 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN 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.
*/
#ifndef LSM303_M_H
#define LSM303_M_H
#include "MicroBitConfig.h"
#include "MicroBitComponent.h"
#include "CoordinateSystem.h"
#include "MicroBitCompass.h"
#include "MicroBitI2C.h"
#include "MicroBitUtil.h"
/**
* Term to convert sample data into SI units.
* TODO: Write this, if necessary
*/
#define LSM303_M_NORMALIZE_SAMPLE(x) ((int)x)
/**
* LSM303_M MAGIC ID value
* Returned from the MAG_WHO_AM_I register for ID purposes.
*/
#define LSM303_M_WHOAMI_VAL 0x20
/**
* I2C constants
*/
#define LSM303_M_DEFAULT_ADDR 0x3C
/**
* LSM303_M Register map
*/
#define LSM303_OFFSET_X_REG_L_M 0x45
#define LSM303_OFFSET_X_REG_H_M 0x46
#define LSM303_OFFSET_Y_REG_L_M 0x47
#define LSM303_OFFSET_Y_REG_H_M 0x48
#define LSM303_OFFSET_Z_REG_L_M 0x49
#define LSM303_OFFSET_Z_REG_H_M 0x4A
#define LSM303_WHO_AM_I_M 0x4F
#define LSM303_CFG_REG_A_M 0x60
#define LSM303_CFG_REG_B_M 0x61
#define LSM303_CFG_REG_C_M 0x62
#define LSM303_INT_CRTL_REG_M 0x63
#define LSM303_INT_SOURCE_REG_M 0x64
#define LSM303_INT_THS_L_REG_M 0x65
#define LSM303_INT_THS_H_REG_M 0x66
#define LSM303_STATUS_REG_M 0x67
#define LSM303_OUTX_L_REG_M 0x68
#define LSM303_OUTX_H_REG_M 0x69
#define LSM303_OUTY_L_REG_M 0x6A
#define LSM303_OUTY_H_REG_M 0x6B
#define LSM303_OUTZ_L_REG_M 0x6C
#define LSM303_OUTZ_H_REG_M 0x6D
/**
* Class definition for LSM303_M.
*
* This class provides the low level driver implementation for the LSM303_M Magnetometer
*
*/
class LSM303Magnetometer : public MicroBitCompass
{
MicroBitI2C& i2c; // The I2C interface to use.
MicroBitPin& int1; // Data ready interrupt.
uint16_t address; // I2C address of this compass.
public:
/**
* Constructor.
* Create a software abstraction of an compass.
*
* @param coordinateSpace The orientation of the sensor. Defaults to: SIMPLE_CARTESIAN
* @param id The unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER
*
*/
LSM303Magnetometer(MicroBitI2C& _i2c, MicroBitPin &_int1, CoordinateSpace &coordinateSpace, uint16_t address = LSM303_M_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS);
/**
* Configures the compass for the sample rate defined in this object.
* The nearest values are chosen to those defined
* that are supported by the hardware. The instance variables are then
* updated to reflect reality.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the compass could not be configured.
*/
virtual int configure();
/**
* Poll to see if new data is available from the hardware. If so, update it.
* n.b. it is not necessary to explicitly call this function to update data
* (it normally happens in the background when the scheduler is idle), but a check is performed
* if the user explicitly requests up to date data.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the update fails.
*/
virtual int requestUpdate();
/**
* A periodic callback invoked by the fiber scheduler idle thread.
*
* Internally calls updateSample().
*/
virtual void idleCallback();
/**
* Destructor.
*/
~LSM303Magnetometer();
};
#endif

+ 134
- 0
inc/drivers/MAG3110.h View File

@ -0,0 +1,134 @@
/*
The MIT License (MIT)
Copyright (c) 2017 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN 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.
*/
#ifndef MAG3110_H
#define MAG3110_H
#include "MicroBitConfig.h"
#include "MicroBitComponent.h"
#include "CoordinateSystem.h"
#include "MicroBitCompass.h"
#include "MicroBitI2C.h"
#include "MicroBitUtil.h"
/**
* Term to convert sample data into SI units
*/
#define MAG3110_NORMALIZE_SAMPLE(x) (100 * (int)x)
/**
* MAG3110 MAGIC ID value
* Returned from the MAG_WHO_AM_I register for ID purposes.
*/
#define MAG3110_WHOAMI_VAL 0xC4
/**
* I2C constants
*/
#define MAG3110_DEFAULT_ADDR 0x1D
/**
* MAG3110 Register map
*/
#define MAG_DR_STATUS 0x00
#define MAG_OUT_X_MSB 0x01
#define MAG_OUT_X_LSB 0x02
#define MAG_OUT_Y_MSB 0x03
#define MAG_OUT_Y_LSB 0x04
#define MAG_OUT_Z_MSB 0x05
#define MAG_OUT_Z_LSB 0x06
#define MAG_WHOAMI 0x07
#define MAG_SYSMOD 0x08
#define MAG_OFF_X_MSB 0x09
#define MAG_OFF_X_LSB 0x0A
#define MAG_OFF_Y_MSB 0x0B
#define MAG_OFF_Y_LSB 0x0C
#define MAG_OFF_Z_MSB 0x0D
#define MAG_OFF_Z_LSB 0x0E
#define MAG_DIE_TEMP 0x0F
#define MAG_CTRL_REG1 0x10
#define MAG_CTRL_REG2 0x11
/**
* Class definition for MAG3110.
*
* This class provides the low level driver implementation for the MAG3110 Magnetometer
*
*/
class MAG3110 : public MicroBitCompass
{
MicroBitI2C& i2c; // The I2C interface to use.
MicroBitPin& int1; // Data ready interrupt.
uint16_t address; // I2C address of this compass.
public:
/**
* Constructor.
* Create a software abstraction of an compass.
*
* @param coordinateSpace The orientation of the sensor. Defaults to: SIMPLE_CARTESIAN
* @param id The unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER
*
*/
MAG3110(MicroBitI2C& _i2c, MicroBitPin &_int1, CoordinateSpace &coordinateSpace, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS);
/**
* Configures the compass for the sample rate defined in this object.
* The nearest values are chosen to those defined
* that are supported by the hardware. The instance variables are then
* updated to reflect reality.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the compass could not be configured.
*/
virtual int configure();
/**
* Poll to see if new data is available from the hardware. If so, update it.
* n.b. it is not necessary to explicitly call this function to update data
* (it normally happens in the background when the scheduler is idle), but a check is performed
* if the user explicitly requests up to date data.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the update fails.
*/
virtual int requestUpdate();
/**
* A periodic callback invoked by the fiber scheduler idle thread.
*
* Internally calls updateSample().
*/
virtual void idleCallback();
/**
* Destructor.
*/
~MAG3110();
};
#endif

+ 128
- 0
inc/drivers/MMA8653.h View File

@ -0,0 +1,128 @@
/*
The MIT License (MIT)
Copyright (c) 2017 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN 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.
*/
#ifndef MMA8653_H
#define MMA8653_H
#include "MicroBitConfig.h"
#include "MicroBitComponent.h"
#include "CoordinateSystem.h"
#include "MicroBitAccelerometer.h"
#include "MicroBitI2C.h"
#include "MicroBitUtil.h"
/**
* Relevant pin assignments
*/
#define MICROBIT_PIN_ACCEL_DATA_READY P0_28
/**
* I2C constants
*/
#define MMA8653_DEFAULT_ADDR 0x3A
/**
* MMA8653 Register map (partial)
*/
#define MMA8653_STATUS 0x00
#define MMA8653_OUT_X_MSB 0x01
#define MMA8653_WHOAMI 0x0D
#define MMA8653_XYZ_DATA_CFG 0x0E
#define MMA8653_CTRL_REG1 0x2A
#define MMA8653_CTRL_REG2 0x2B
#define MMA8653_CTRL_REG3 0x2C
#define MMA8653_CTRL_REG4 0x2D
#define MMA8653_CTRL_REG5 0x2E
/**
* MMA8653 constants
*/
#define MMA8653_WHOAMI_VAL 0x5A
/**
* Class definition for MMA8653.
* This class provides a simple wrapper between the hybrid FXOS8700 accelerometer and higher level accelerometer funcitonality.
*/
class MMA8653 : public MicroBitAccelerometer
{
MicroBitI2C& i2c; // The I2C interface to use.
MicroBitPin& int1; // Data ready interrupt.
uint16_t address; // I2C address of this accelerometer.
public:
/**
* Constructor.
* Create a software abstraction of an accelerometer.
*
* @param coordinateSpace The orientation of the sensor. Defaults to: SIMPLE_CARTESIAN
* @param id The unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER
*
*/
MMA8653(MicroBitI2C& _i2c, MicroBitPin &_int1, CoordinateSpace &coordinateSpace, uint16_t address = MMA8653_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_ACCELEROMETER);
/**
* Configures the accelerometer for G range and sample rate defined
* in this object. The nearest values are chosen to those defined
* that are supported by the hardware. The instance variables are then
* updated to reflect reality.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured.
*
* @note This method should be overidden by the hardware driver to implement the requested
* changes in hardware.
*/
virtual int configure();
/**
* Poll to see if new data is available from the hardware. If so, update it.
* n.b. it is not necessary to explicitly call this funciton to update data
* (it normally happens in the background when the scheduler is idle), but a check is performed
* if the user explicitly requests up to date data.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the update fails.
*
* @note This method should be overidden by the hardware driver to implement the requested
* changes in hardware.
*/
virtual int requestUpdate();
/**
* A periodic callback invoked by the fiber scheduler idle thread.
*
* Internally calls updateSample().
*/
virtual void idleCallback();
/**
* Destructor.
*/
~MMA8653();
};
#endif

+ 262
- 364
inc/drivers/MicroBitAccelerometer.h View File

@ -1,8 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016 British Broadcasting Corporation.
This software is provided by Lancaster University by arrangement with the BBC.
Copyright (c) 2017 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,61 +22,28 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef MICROBIT_ACCELEROMETER_H
#define MICROBIT_ACCELEROMETER_H
#ifndef MICROBIT_ACCELEROMTER_H
#define MICROBIT_ACCELEROMTER_H
#include "mbed.h"
#include "MicroBitConfig.h"
#include "MicroBitComponent.h"
#include "MicroBitCoordinateSystem.h"
#include "MicroBitI2C.h"
#include "MicroBitPin.h"
#include "CoordinateSystem.h"
/**
* Relevant pin assignments
*/
#define MICROBIT_PIN_ACCEL_DATA_READY P0_28
/**
* Status flags
*/
#define MICROBIT_ACCEL_PITCH_ROLL_VALID 0x02
#define MICROBIT_ACCEL_ADDED_TO_IDLE 0x04
/**
* I2C constants
*/
#define MMA8653_DEFAULT_ADDR 0x3A
/**
* MMA8653 Register map (partial)
*/
#define MMA8653_STATUS 0x00
#define MMA8653_OUT_X_MSB 0x01
#define MMA8653_WHOAMI 0x0D
#define MMA8653_XYZ_DATA_CFG 0x0E
#define MMA8653_CTRL_REG1 0x2A
#define MMA8653_CTRL_REG2 0x2B
#define MMA8653_CTRL_REG3 0x2C
#define MMA8653_CTRL_REG4 0x2D
#define MMA8653_CTRL_REG5 0x2E
/**
* MMA8653 constants
*/
#define MMA8653_WHOAMI_VAL 0x5A
#define MMA8653_SAMPLE_RANGES 3
#define MMA8653_SAMPLE_RATES 8
* Status flags
*/
#define MICROBIT_ACCELEROMETER_IMU_DATA_VALID 0x02
#define MICROBIT_ACCEL_ADDED_TO_IDLE 0x04
/**
* Accelerometer events
*/
* Accelerometer events
*/
#define MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE 1
/**
* Gesture events
*/
* Gesture events
*/
#define MICROBIT_ACCELEROMETER_EVT_NONE 0
#define MICROBIT_ACCELEROMETER_EVT_TILT_UP 1
#define MICROBIT_ACCELEROMETER_EVT_TILT_DOWN 2
@ -92,8 +58,8 @@ DEALINGS IN THE SOFTWARE.
#define MICROBIT_ACCELEROMETER_EVT_SHAKE 11
/**
* Gesture recogniser constants
*/
* Gesture recogniser constants
*/
#define MICROBIT_ACCELEROMETER_REST_TOLERANCE 200
#define MICROBIT_ACCELEROMETER_TILT_TOLERANCE 200
#define MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE 400
@ -102,39 +68,16 @@ DEALINGS IN THE SOFTWARE.
#define MICROBIT_ACCELEROMETER_6G_TOLERANCE 6144
#define MICROBIT_ACCELEROMETER_8G_TOLERANCE 8192
#define MICROBIT_ACCELEROMETER_GESTURE_DAMPING 5
#define MICROBIT_ACCELEROMETER_SHAKE_DAMPING 10
#define MICROBIT_ACCELEROMETER_SHAKE_DAMPING 10
#define MICROBIT_ACCELEROMETER_SHAKE_RTX 30
#define MICROBIT_ACCELEROMETER_REST_THRESHOLD (MICROBIT_ACCELEROMETER_REST_TOLERANCE * MICROBIT_ACCELEROMETER_REST_TOLERANCE)
#define MICROBIT_ACCELEROMETER_FREEFALL_THRESHOLD (MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE * MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE)
#define MICROBIT_ACCELEROMETER_3G_THRESHOLD (MICROBIT_ACCELEROMETER_3G_TOLERANCE * MICROBIT_ACCELEROMETER_3G_TOLERANCE)
#define MICROBIT_ACCELEROMETER_6G_THRESHOLD (MICROBIT_ACCELEROMETER_6G_TOLERANCE * MICROBIT_ACCELEROMETER_6G_TOLERANCE)
#define MICROBIT_ACCELEROMETER_8G_THRESHOLD (MICROBIT_ACCELEROMETER_8G_TOLERANCE * MICROBIT_ACCELEROMETER_8G_TOLERANCE)
#define MICROBIT_ACCELEROMETER_FREEFALL_THRESHOLD ((uint32_t)MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE * (uint32_t)MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE)
#define MICROBIT_ACCELEROMETER_3G_THRESHOLD ((uint32_t)MICROBIT_ACCELEROMETER_3G_TOLERANCE * (uint32_t)MICROBIT_ACCELEROMETER_3G_TOLERANCE)
#define MICROBIT_ACCELEROMETER_6G_THRESHOLD ((uint32_t)MICROBIT_ACCELEROMETER_6G_TOLERANCE * (uint32_t)MICROBIT_ACCELEROMETER_6G_TOLERANCE)
#define MICROBIT_ACCELEROMETER_8G_THRESHOLD ((uint32_t)MICROBIT_ACCELEROMETER_8G_TOLERANCE * (uint32_t)MICROBIT_ACCELEROMETER_8G_TOLERANCE)
#define MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD 4
struct MMA8653Sample
{
int16_t x;
int16_t y;
int16_t z;
};
struct MMA8653SampleRateConfig
{
uint32_t sample_period;
uint8_t ctrl_reg1;
};
struct MMA8653SampleRangeConfig
{
uint8_t sample_range;
uint8_t xyz_data_cfg;
};
extern const MMA8653SampleRangeConfig MMA8653SampleRange[];
extern const MMA8653SampleRateConfig MMA8653SampleRate[];
struct ShakeHistory
{
uint16_t shaken:1,
@ -151,302 +94,257 @@ struct ShakeHistory
};
/**
* Class definition for MicroBit Accelerometer.
*
* Represents an implementation of the Freescale MMA8653 3 axis accelerometer
* Also includes basic data caching and on demand activation.
* Class definition for MicroBitAccelerometer.
*/
class MicroBitAccelerometer : public MicroBitComponent
{
uint16_t address; // I2C address of this accelerometer.
uint16_t samplePeriod; // The time between samples, in milliseconds.
uint8_t sampleRange; // The sample range of the accelerometer in g.
MMA8653Sample sample; // The last sample read.
DigitalIn int1; // Data ready interrupt.
float pitch; // Pitch of the device, in radians.
MicroBitI2C& i2c; // The I2C interface to use.
float roll; // Roll of the device, in radians.
uint8_t sigma; // the number of ticks that the instantaneous gesture has been stable.
uint8_t impulseSigma; // the number of ticks since an impulse event has been generated.
uint16_t lastGesture; // the last, stable gesture recorded.
uint16_t currentGesture; // the instantaneous, unfiltered gesture detected.
ShakeHistory shake; // State information needed to detect shake events.
protected:
uint16_t samplePeriod; // The time between samples, in milliseconds.
uint8_t sampleRange; // The sample range of the accelerometer in g.
Sample3D sample; // The last sample read, in the coordinate system specified by the coordinateSpace variable.
Sample3D sampleENU; // The last sample read, in raw ENU format (stored in case requests are made for data in other coordinate spaces)
CoordinateSpace &coordinateSpace; // The coordinate space transform (if any) to apply to the raw data from the hardware.
float pitch; // Pitch of the device, in radians.
float roll; // Roll of the device, in radians.
uint8_t sigma; // the number of ticks that the instantaneous gesture has been stable.
uint8_t impulseSigma; // the number of ticks since an impulse event has been generated.
uint16_t lastGesture; // the last, stable gesture recorded.
uint16_t currentGesture; // the instantaneous, unfiltered gesture detected.
ShakeHistory shake; // State information needed to detect shake events.
public:
/**
* Constructor.
* Create a software abstraction of an accelerometer.
*
* @param _i2c an instance of MicroBitI2C used to communicate with the onboard accelerometer.
*
* @param address the default I2C address of the accelerometer. Defaults to: MMA8653_DEFAULT_ADDR.
*
* @param id the unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER
*
* @code
* MicroBitI2C i2c = MicroBitI2C(I2C_SDA0, I2C_SCL0);
*
* MicroBitAccelerometer accelerometer = MicroBitAccelerometer(i2c);
* @endcode
*/
MicroBitAccelerometer(MicroBitI2C &_i2c, uint16_t address = MMA8653_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_ACCELEROMETER);
/**
* Configures the accelerometer for G range and sample rate defined
* in this object. The nearest values are chosen to those defined
* that are supported by the hardware. The instance variables are then
* updated to reflect reality.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured.
*/
int configure();
/**
* Reads the acceleration data from the accelerometer, and stores it in our buffer.
* This only happens if the accelerometer indicates that it has new data via int1.
*
* On first use, this member function will attempt to add this component to the
* list of fiber components in order to constantly update the values stored
* by this object.
*
* This technique is called lazy instantiation, and it means that we do not
* obtain the overhead from non-chalantly adding this component to fiber components.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the read request fails.
*/
int updateSample();
/**
* Attempts to set the sample rate of the accelerometer to the specified value (in ms).
*
* @param period the requested time between samples, in milliseconds.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails.
*
* @code
* // sample rate is now 20 ms.
* accelerometer.setPeriod(20);
* @endcode
*
* @note The requested rate may not be possible on the hardware. In this case, the
* nearest lower rate is chosen.
*/
int setPeriod(int period);
/**
* Reads the currently configured sample rate of the accelerometer.
*
* @return The time between samples, in milliseconds.
*/
int getPeriod();
/**
* Attempts to set the sample range of the accelerometer to the specified value (in g).
*
* @param range The requested sample range of samples, in g.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails.
*
* @code
* // the sample range of the accelerometer is now 8G.
* accelerometer.setRange(8);
* @endcode
*
* @note The requested range may not be possible on the hardware. In this case, the
* nearest lower range is chosen.
*/
int setRange(int range);
/**
* Reads the currently configured sample range of the accelerometer.
*
* @return The sample range, in g.
*/
int getRange();
/**
* Attempts to read the 8 bit ID from the accelerometer, this can be used for
* validation purposes.
*
* @return the 8 bit ID returned by the accelerometer, or MICROBIT_I2C_ERROR if the request fails.
*
* @code
* accelerometer.whoAmI();
* @endcode
*/
int whoAmI();
/**
* Reads the value of the X axis from the latest update retrieved from the accelerometer.
*
* @param system The coordinate system to use. By default, a simple cartesian system is provided.
*
* @return The force measured in the X axis, in milli-g.
*
* @code
* accelerometer.getX();
* @endcode
*/
int getX(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
/**
* Reads the value of the Y axis from the latest update retrieved from the accelerometer.
*
* @return The force measured in the Y axis, in milli-g.
*
* @code
* accelerometer.getY();
* @endcode
*/
int getY(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
/**
* Reads the value of the Z axis from the latest update retrieved from the accelerometer.
*
* @return The force measured in the Z axis, in milli-g.
*
* @code
* accelerometer.getZ();
* @endcode
*/
int getZ(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
/**
* Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer.
*
* @return The pitch of the device, in degrees.
*
* @code
* accelerometer.getPitch();
* @endcode
*/
int getPitch();
/**
* Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer.
*
* @return The pitch of the device, in radians.
*
* @code
* accelerometer.getPitchRadians();
* @endcode
*/
float getPitchRadians();
/**
* Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer.
*
* @return The roll of the device, in degrees.
*
* @code
* accelerometer.getRoll();
* @endcode
*/
int getRoll();
/**
* Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer.
*
* @return The roll of the device, in radians.
*
* @code
* accelerometer.getRollRadians();
* @endcode
*/
float getRollRadians();
/**
* Retrieves the last recorded gesture.
*
* @return The last gesture that was detected.
*
* Example:
* @code
* MicroBitDisplay display;
*
* if (accelerometer.getGesture() == SHAKE)
* display.scroll("SHAKE!");
* @endcode
*/
uint16_t getGesture();
/**
* A periodic callback invoked by the fiber scheduler idle thread.
*
* Internally calls updateSample().
*/
virtual void idleTick();
/**
* Destructor for MicroBitButton, where we deregister this instance from the array of fiber components.
*/
~MicroBitAccelerometer();
/**
* Constructor.
* Create a software abstraction of an accelerometer.
*
* @param coordinateSpace the orientation of the sensor. Defaults to: SIMPLE_CARTESIAN
* @param id the unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER
*
*/
MicroBitAccelerometer(CoordinateSpace &coordinateSpace, uint16_t id = MICROBIT_ID_ACCELEROMETER);
/**
* Attempts to set the sample rate of the accelerometer to the specified value (in ms).
*
* @param period the requested time between samples, in milliseconds.
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails.
*
* @note The requested rate may not be possible on the hardware. In this case, the
* nearest lower rate is chosen.
*
* @note This method should be overriden (if supported) by specific accelerometer device drivers.
*/
virtual int setPeriod(int period);
/**
* Reads the currently configured sample rate of the accelerometer.
*
* @return The time between samples, in milliseconds.
*/
virtual int getPeriod();
/**
* Attempts to set the sample range of the accelerometer to the specified value (in g).
*
* @param range The requested sample range of samples, in g.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails.
*
* @note The requested range may not be possible on the hardware. In this case, the
* nearest lower range is chosen.
*
* @note This method should be overriden (if supported) by specific accelerometer device drivers.
*/
virtual int setRange(int range);
/**
* Reads the currently configured sample range of the accelerometer.
*
* @return The sample range, in g.
*/
virtual int getRange();
/**
* Configures the accelerometer for G range and sample rate defined
* in this object. The nearest values are chosen to those defined
* that are supported by the hardware. The instance variables are then
* updated to reflect reality.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured.
*
* @note This method should be overidden by the hardware driver to implement the requested
* changes in hardware.
*/
virtual int configure();
/**
* Poll to see if new data is available from the hardware. If so, update it.
* n.b. it is not necessary to explicitly call this funciton to update data
* (it normally happens in the background when the scheduler is idle), but a check is performed
* if the user explicitly requests up to date data.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the update fails.
*
* @note This method should be overidden by the hardware driver to implement the requested
* changes in hardware.
*/
virtual int requestUpdate();
/**
* Stores data from the accelerometer sensor in our buffer, and perform gesture tracking.
*
* On first use, this member function will attempt to add this component to the
* list of fiber components in order to constantly update the values stored
* by this object.
*
* This lazy instantiation means that we do not
* obtain the overhead from non-chalantly adding this component to fiber components.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the read request fails.
*/
virtual int update();
/**
* Reads the last accelerometer value stored, and provides it in the coordinate system requested.
*
* @param coordinateSpace The coordinate system to use.
* @return The force measured in each axis, in milli-g.
*/
Sample3D getSample(CoordinateSystem coordinateSystem);
/**
* Reads the last accelerometer value stored, and in the coordinate system defined in the constructor.
* @return The force measured in each axis, in milli-g.
*/
Sample3D getSample();
/**
* reads the value of the x axis from the latest update retrieved from the accelerometer,
* using the default coordinate system as specified in the constructor.
*
* @return the force measured in the x axis, in milli-g.
*/
int getX();
/**
* reads the value of the y axis from the latest update retrieved from the accelerometer,
* using the default coordinate system as specified in the constructor.
*
* @return the force measured in the y axis, in milli-g.
*/
int getY();
/**
* reads the value of the z axis from the latest update retrieved from the accelerometer,
* using the default coordinate system as specified in the constructor.
*
* @return the force measured in the z axis, in milli-g.
*/
int getZ();
/**
* Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer.
*
* @return The pitch of the device, in degrees.
*
* @code
* accelerometer.getPitch();
* @endcode
*/
int getPitch();
/**
* Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer.
*
* @return The pitch of the device, in radians.
*
* @code
* accelerometer.getPitchRadians();
* @endcode
*/
float getPitchRadians();
/**
* Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer.
*
* @return The roll of the device, in degrees.
*
* @code
* accelerometer.getRoll();
* @endcode
*/
int getRoll();
/**
* Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer.
*
* @return The roll of the device, in radians.
*
* @code
* accelerometer.getRollRadians();
* @endcode
*/
float getRollRadians();
/**
* Retrieves the last recorded gesture.
*
* @return The last gesture that was detected.
*
* Example:
* @code
*
* if (accelerometer.getGesture() == SHAKE)
* display.scroll("SHAKE!");
* @endcode
*/
uint16_t getGesture();
/**
* Destructor.
*/
~MicroBitAccelerometer();
private:
/**
* Issues a standard, 2 byte I2C command write to the accelerometer.
*
* Blocks the calling thread until complete.
*
* @param reg The address of the register to write to.
*
* @param value The value to write.
*
* @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed.
*/
int writeCommand(uint8_t reg, uint8_t value);
/**
* Issues a read command, copying data into the specified buffer.
*
* Blocks the calling thread until complete.
*
* @param reg The address of the register to access.
*
* @param buffer Memory area to read the data into.
*
* @param length The number of bytes to read.
*
* @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed.
*/
int readCommand(uint8_t reg, uint8_t* buffer, int length);
/**
* Recalculate roll and pitch values for the current sample.
*
* @note We only do this at most once per sample, as the necessary trigonemteric functions are rather
* heavyweight for a CPU without a floating point unit.
*/
void recalculatePitchRoll();
/**
* Updates the basic gesture recognizer. This performs instantaneous pose recognition, and also some low pass filtering to promote
* stability.
*/
void updateGesture();
/**
* A service function.
* It calculates the current scalar acceleration of the device (x^2 + y^2 + z^2).
* It does not, however, square root the result, as this is a relatively high cost operation.
*
* This is left to application code should it be needed.
*
* @return the sum of the square of the acceleration of the device across all axes.
*/
int instantaneousAccelerationSquared();
/**
* Service function.
* Determines a 'best guess' posture of the device based on instantaneous data.
*
* This makes no use of historic data, and forms this input to the filter implemented in updateGesture().
*
* @return A 'best guess' of the current posture of the device, based on instanataneous data.
*/
uint16_t instantaneousPosture();
/**
* Recalculate roll and pitch values for the current sample.
*
* @note We only do this at most once per sample, as the necessary trigonemteric functions are rather
* heavyweight for a CPU without a floating point unit.
*/
void recalculatePitchRoll();
/**
* Updates the basic gesture recognizer. This performs instantaneous pose recognition, and also some low pass filtering to promote
* stability.
*/
void updateGesture();
/**
* A service function.
* It calculates the current scalar acceleration of the device (x^2 + y^2 + z^2).
* It does not, however, square root the result, as this is a relatively high cost operation.
*
* This is left to application code should it be needed.
*
* @return the sum of the square of the acceleration of the device across all axes.
*/
uint32_t instantaneousAccelerationSquared();
/**
* Service function.
* Determines a 'best guess' posture of the device based on instantaneous data.
*
* This makes no use of historic data, and forms this input to the filter implemented in updateGesture().
*
* @return A 'best guess' of the current posture of the device, based on instanataneous data.
*/
uint16_t instantaneousPosture();
};
#endif

+ 241
- 467
inc/drivers/MicroBitCompass.h View File

@ -1,8 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016 British Broadcasting Corporation.
This software is provided by Lancaster University by arrangement with the BBC.
Copyright (c) 2017 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,491 +22,266 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef MICROBIT_COMPASS_H
#define MICROBIT_COMPASS_H
#ifndef MICROBIT_COMPASS
#define MICROBIT_COMPASS
#include "mbed.h"
#include "MicroBitConfig.h"
#include "MicroBitComponent.h"
#include "MicroBitCoordinateSystem.h"
#include "CoordinateSystem.h"
#include "MicroBitAccelerometer.h"
#include "MicroBitStorage.h"
/**
* Relevant pin assignments
*/
#define MICROBIT_PIN_COMPASS_DATA_READY P0_29
/**
* I2C constants
*/
#define MAG3110_DEFAULT_ADDR 0x1D
/**
* MAG3110 Register map
*/
#define MAG_DR_STATUS 0x00
#define MAG_OUT_X_MSB 0x01
#define MAG_OUT_X_LSB 0x02
#define MAG_OUT_Y_MSB 0x03
#define MAG_OUT_Y_LSB 0x04
#define MAG_OUT_Z_MSB 0x05
#define MAG_OUT_Z_LSB 0x06
#define MAG_WHOAMI 0x07
#define MAG_SYSMOD 0x08
#define MAG_OFF_X_MSB 0x09
#define MAG_OFF_X_LSB 0x0A
#define MAG_OFF_Y_MSB 0x0B
#define MAG_OFF_Y_LSB 0x0C
#define MAG_OFF_Z_MSB 0x0D
#define MAG_OFF_Z_LSB 0x0E
#define MAG_DIE_TEMP 0x0F
#define MAG_CTRL_REG1 0x10
#define MAG_CTRL_REG2 0x11
/**
* Configuration options
*/
struct MAG3110SampleRateConfig
{