microbit-dal: Initial Commit
This is the first commit of the microbit-dal on GitHub. This repository contains the runtime, which is a light weight operating system developed by Lancaster University.
This commit is contained in:
commit
538e1c48bd
51 changed files with 9353 additions and 0 deletions
104
inc/DynamicPwm.h
Normal file
104
inc/DynamicPwm.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
#include "mbed.h"
|
||||
|
||||
#ifndef MICROBIT_DYNAMIC_PWM_H
|
||||
#define MICROBIT_DYNAMIC_PWM_H
|
||||
|
||||
#define NO_PWMS 3
|
||||
#define MICROBIT_DISPLAY_PWM_PERIOD 1000
|
||||
|
||||
enum PwmPersistence
|
||||
{
|
||||
PWM_PERSISTENCE_TRANSIENT = 1,
|
||||
PWM_PERSISTENCE_PERSISTENT = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Class definition for DynamicPwm.
|
||||
*
|
||||
* This class addresses a few issues found in the underlying libraries.
|
||||
* This provides the ability for a neat, clean swap between PWM channels.
|
||||
*/
|
||||
class DynamicPwm : public PwmOut
|
||||
{
|
||||
private:
|
||||
static DynamicPwm* pwms[NO_PWMS];
|
||||
static uint8_t lastUsed;
|
||||
uint8_t flags;
|
||||
|
||||
|
||||
/**
|
||||
* An internal constructor used when allocating a new DynamicPwm representation
|
||||
* @param pin the name of the pin for the pwm to target
|
||||
* @param persistance the level of persistence for this pin PWM_PERSISTENCE_PERSISTENT (can not be replaced until freed, should only be used for system services really.)
|
||||
* or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
|
||||
* @param period the frequency of the pwm channel in us.
|
||||
*/
|
||||
DynamicPwm(PinName pin, PwmPersistence persistence = PWM_PERSISTENCE_TRANSIENT, int period = MICROBIT_DISPLAY_PWM_PERIOD);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Redirects the pwm channel to point at a different pin.
|
||||
* @param pin the new pin to direct PWM at.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
|
||||
* pwm->redirect(PinName n2); // pwm is now produced on n2
|
||||
* @endcode
|
||||
*/
|
||||
void redirect(PinName pin);
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a pointer to the first available free pwm channel - or the first one that can be reallocated.
|
||||
* @param pin the name of the pin for the pwm to target
|
||||
* @param persistance the level of persistence for this pin PWM_PERSISTENCE_PERSISTENT (can not be replaced until freed, should only be used for system services really.)
|
||||
* or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
|
||||
* @param period the frequency of the pwm channel in us.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
|
||||
* @endcode
|
||||
*/
|
||||
static DynamicPwm* allocate(PinName pin, PwmPersistence persistence = PWM_PERSISTENCE_TRANSIENT, int period = MICROBIT_DISPLAY_PWM_PERIOD);
|
||||
|
||||
/**
|
||||
* Frees this DynamicPwm instance if the pointer is valid.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* DynamicPwm* pwm = DynamicPwm::allocate();
|
||||
* pwm->free();
|
||||
* @endcode
|
||||
*/
|
||||
void free();
|
||||
|
||||
/**
|
||||
* Retreives the pin name associated with this DynamicPwm instance.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
|
||||
* pwm->getPinName(); // equal to n
|
||||
* @endcode
|
||||
*/
|
||||
PinName getPinName();
|
||||
|
||||
/**
|
||||
* Sets the period used by the WHOLE PWM module. Any changes to the period will AFFECT ALL CHANNELS.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
|
||||
* pwm->setPeriodUs(1000); // period now is 1ms
|
||||
* @endcode
|
||||
*
|
||||
* @note The display uses the pwm module, if you change this value the display may flicker.
|
||||
*/
|
||||
void setPeriodUs(int period);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
15
inc/ErrorNo.h
Normal file
15
inc/ErrorNo.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef ERROR_NO_H
|
||||
#define ERROR_NO_H
|
||||
|
||||
/**
|
||||
* Error codes using in the Micro:bit runtime.
|
||||
*/
|
||||
enum Error{
|
||||
MICROBIT_INVALID_VALUE = -1, // currently only used in MicroBit.cpp rand function when the max is less or equal to 0.
|
||||
MICROBIT_IO_OP_NA = -2, // used in MicroBitPin.cpp for when a pin cannot perform a transition. (microbit io operation not allowed)
|
||||
MICROBIT_COMPASS_IS_CALIBRATING = -3, // used in MicroBitPin.cpp for when a pin cannot perform a transition. (microbit io operation not allowed)
|
||||
MICROBIT_COMPASS_CALIBRATE_REQUIRED = -4,
|
||||
MICROBIT_OOM = 20, // the MicroBit Out of memory error code...
|
||||
MICROBIT_I2C_LOCKUP = 10 // the MicroBit I2C bus has locked up
|
||||
};
|
||||
#endif
|
8
inc/ExternalEvents.h
Normal file
8
inc/ExternalEvents.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef EXTERNAL_EVENTS_H
|
||||
#define EXTERNAL_EVENTS_H
|
||||
|
||||
#define MICROBIT_ID_BLE 1000
|
||||
|
||||
#include "MESEvents.h"
|
||||
|
||||
#endif
|
82
inc/MESEvents.h
Normal file
82
inc/MESEvents.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
#ifndef MES_EVENTS_H
|
||||
#define MES_EVENTS_H
|
||||
|
||||
//
|
||||
// MicroBit Event Service Event ID's and values
|
||||
//
|
||||
|
||||
//
|
||||
// Events that master devices respond to:
|
||||
//
|
||||
#define MES_REMOTE_CONTROL_ID 1001
|
||||
#define MES_REMOTE_CONTROL_EVT_PLAY 0
|
||||
#define MES_REMOTE_CONTROL_EVT_PAUSE 1
|
||||
#define MES_REMOTE_CONTROL_EVT_STOP 2
|
||||
#define MES_REMOTE_CONTROL_EVT_NEXTTRACK 3
|
||||
#define MES_REMOTE_CONTROL_EVT_PREVTRACK 4
|
||||
#define MES_REMOTE_CONTROL_EVT_FORWARD 5
|
||||
#define MES_REMOTE_CONTROL_EVT_REWIND 6
|
||||
#define MES_REMOTE_CONTROL_EVT_VOLUMEUP 7
|
||||
#define MES_REMOTE_CONTROL_EVT_VOLUMEDOWN 8
|
||||
|
||||
|
||||
#define MES_CAMERA_ID 1002
|
||||
#define MES_CAMERA_EVT_LAUNCH_PHOTO_MODE 0
|
||||
#define MES_CAMERA_EVT_LAUNCH_VIDEO_MODE 1
|
||||
#define MES_CAMERA_EVT_TAKE_PHOTO 2
|
||||
#define MES_CAMERA_EVT_START_VIDEO_CAPTURE 3
|
||||
#define MES_CAMERA_EVT_STOP_VIDEO_CAPTURE 4
|
||||
#define MES_CAMERA_EVT_STOP_PHOTO_MODE 5
|
||||
#define MES_CAMERA_EVT_STOP_VIDEO_MODE 6
|
||||
#define MES_CAMERA_EVT_TOGGLE_FRONT_REAR 7
|
||||
|
||||
|
||||
#define MES_AUDIO_RECORDER_ID 1003
|
||||
#define MES_AUDIO_RECORDER_EVT_LAUNCH 0
|
||||
#define MES_AUDIO_RECORDER_EVT_START_CAPTURE 1
|
||||
#define MES_AUDIO_RECORDER_EVT_STOP_CAPTURE 2
|
||||
#define MES_AUDIO_RECORDER_EVT_STOP 3
|
||||
|
||||
|
||||
#define MES_ALERTS_ID 1004
|
||||
#define MES_ALERT_EVT_DISPLAY_TOAST 0
|
||||
#define MES_ALERT_EVT_VIBRATE 1
|
||||
#define MES_ALERT_EVT_PLAY_SOUND 2
|
||||
#define MES_ALERT_EVT_PLAY_RINGTONE 3
|
||||
#define MES_ALERT_EVT_FIND_MY_PHONE 4
|
||||
#define MES_ALERT_EVT_ALARM1 5
|
||||
#define MES_ALERT_EVT_ALARM2 6
|
||||
#define MES_ALERT_EVT_ALARM3 7
|
||||
#define MES_ALERT_EVT_ALARM4 8
|
||||
#define MES_ALERT_EVT_ALARM5 9
|
||||
#define MES_ALERT_EVT_ALARM6 10
|
||||
|
||||
//
|
||||
// Events that master devices generate:
|
||||
//
|
||||
#define MES_SIGNAL_STRENGTH_ID 1101
|
||||
#define MES_SIGNAL_STRENGTH_EVT_NO_BAR 0
|
||||
#define MES_SIGNAL_STRENGTH_EVT_ONE_BAR 1
|
||||
#define MES_SIGNAL_STRENGTH_EVT_TWO_BAR 2
|
||||
#define MES_SIGNAL_STRENGTH_EVT_THREE_BAR 3
|
||||
#define MES_SIGNAL_STRENGTH_EVT_FOUR_BAR 4
|
||||
|
||||
#define MES_PLAY_CONTROLLER_ID 1102
|
||||
#define MES_BUTTON_UP 0
|
||||
#define MES_BUTTON_DOWN 1
|
||||
#define MES_BUTTON_RIGHT 2
|
||||
#define MES_BUTTON_LEFT 3
|
||||
#define MES_BUTTON_A 4
|
||||
#define MES_BUTTON_B 5
|
||||
#define MES_BUTTON_C 6
|
||||
#define MES_BUTTON_D 7
|
||||
|
||||
#define MES_DEVICE_INFO_ID 1103
|
||||
#define MES_DEVICE_ORIENTATION_LANDSCAPE 0
|
||||
#define MES_DEVICE_ORIENTATION_PORTRAIT 1
|
||||
#define MES_DEVICE_GESTURE_NONE 2
|
||||
#define MES_DEVICE_GESTURE_DEVICE_SHAKEN 3
|
||||
#define MES_DEVICE_DISPLAY_OFF 4
|
||||
#define MES_DEVICE_DISPLAY_ON 5
|
||||
|
||||
#endif
|
306
inc/ManagedString.h
Normal file
306
inc/ManagedString.h
Normal file
|
@ -0,0 +1,306 @@
|
|||
#ifndef MANAGED_STRING_H
|
||||
#define MANAGED_STRING_H
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
/**
|
||||
* Class definition for a ManagedString.
|
||||
*
|
||||
* Uses basic reference counting to implement a copy-assignable, immutable string.
|
||||
* This maps closely to the constructs found in many high level application languages,
|
||||
* such as Touch Develop.
|
||||
*
|
||||
* Written from first principles here, for several reasons:
|
||||
* 1) std::shared_ptr is not yet availiable on the ARMCC compiler
|
||||
* 2) to reduce memory footprint - we don't need many of the other features in the std library
|
||||
* 3) it makes an interestin case study for anyone interested in seeing how it works!
|
||||
*/
|
||||
class ManagedString
|
||||
{
|
||||
// Internally we record the string as a char *, but control access to this to proide immutability
|
||||
// and reference counting.
|
||||
char *data;
|
||||
int16_t *ref;
|
||||
int16_t len;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a managed string from a pointer to an 8-bit character buffer.
|
||||
* The buffer is copied to ensure sage memory management (the supplied
|
||||
* character buffer may be decalred on the stack for instance).
|
||||
*
|
||||
* @param str The character array on which to base the new ManagedString.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcdefg");
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString(const char *str);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a managed string from a given integer.
|
||||
*
|
||||
* @param value The integer from which to create the ManagedString
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s(20);
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString(const int value);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a managed string from a given char.
|
||||
*
|
||||
* @param value The char from which to create the ManagedString
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s('a');
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString(const char value);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a managed string from a pointer to an 8-bit character buffer of a given length.
|
||||
* The buffer is copied to ensure sane memory management (the supplied
|
||||
* character buffer may be declared on the stack for instance).
|
||||
*
|
||||
* @param str The character array on which to base the new ManagedString.
|
||||
* @param length The length of the character array
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcdefg",7); // this is generally used for substring... why not use a normal char * constructor?
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString(const char *str, const int16_t length);
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* Makes a new ManagedString identical to the one supplied.
|
||||
* Shares the character buffer and reference count with the supplied ManagedString.
|
||||
*
|
||||
* @param s The ManagedString to copy.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcdefg");
|
||||
* ManagedString p(s);
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString(const ManagedString &s);
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
* Create an empty ManagedString.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s();
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*
|
||||
* Free this ManagedString, and decrement the reference count to the
|
||||
* internal character buffer. If we're holding the last reference,
|
||||
* also free the character buffer and reference counter.
|
||||
*/
|
||||
~ManagedString();
|
||||
|
||||
/**
|
||||
* Copy assign operation.
|
||||
*
|
||||
* Called when one ManagedString is assigned the value of another.
|
||||
* If the ManagedString being assigned is already refering to a character buffer,
|
||||
* decrement the reference count and free up the buffer as necessary.
|
||||
* Then, update our character buffer to refer to that of the supplied ManagedString,
|
||||
* and increase its reference count.
|
||||
*
|
||||
* @param s The ManagedString to copy.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcd");
|
||||
* ManagedString p("efgh");
|
||||
* p = s // p now points to s, s' ref is incremented
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString& operator = (const ManagedString& s);
|
||||
|
||||
/**
|
||||
* Equality operation.
|
||||
*
|
||||
* Called when one ManagedString is tested to be equal to another using the '==' operator.
|
||||
*
|
||||
* @param s The ManagedString to test ourselves against.
|
||||
* @return true if this ManagedString is identical to the one supplied, false otherwise.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcd");
|
||||
* ManagedString p("efgh");
|
||||
*
|
||||
* if(p==s)
|
||||
* print("We are the same!");
|
||||
* else
|
||||
* print("We are different!"); //p is not equal to s - this will be called
|
||||
* @endcode
|
||||
*/
|
||||
bool operator== (const ManagedString& s);
|
||||
|
||||
/**
|
||||
* Inequality operation.
|
||||
*
|
||||
* Called when one ManagedString is tested to be less than another using the '<' operator.
|
||||
*
|
||||
* @param s The ManagedString to test ourselves against.
|
||||
* @return true if this ManagedString is alphabetically less than to the one supplied, false otherwise.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("a");
|
||||
* ManagedString p("b");
|
||||
*
|
||||
* if(s<p)
|
||||
* print("a is before b!"); //a is before b
|
||||
* else
|
||||
* print("b is before a!");
|
||||
* @endcode
|
||||
*/
|
||||
bool operator< (const ManagedString& s);
|
||||
|
||||
/**
|
||||
* Inequality operation.
|
||||
*
|
||||
* Called when one ManagedString is tested to be greater than another using the '>' operator.
|
||||
*
|
||||
* @param s The ManagedString to test ourselves against.
|
||||
* @return true if this ManagedString is alphabetically greater than to the one supplied, false otherwise.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("a");
|
||||
* ManagedString p("b");
|
||||
*
|
||||
* if(p>a)
|
||||
* print("b is after a!"); //b is after a
|
||||
* else
|
||||
* print("a is after b!");
|
||||
* @endcode
|
||||
*/
|
||||
bool operator> (const ManagedString& s);
|
||||
|
||||
/**
|
||||
* Extracts a ManagedString from this string, at the position provided.
|
||||
*
|
||||
* @param start The index of the first character to extract, indexed from zero.
|
||||
* @param length The number of characters to extract from the start position
|
||||
* @return a ManagedString representing the requested substring.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcdefg");
|
||||
*
|
||||
* print(s.substring(0,2)) // prints "ab"
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString substring(int16_t start, int16_t length);
|
||||
|
||||
/**
|
||||
* Concatenates this string with the one provided.
|
||||
*
|
||||
* @param s The ManagedString to concatenate.
|
||||
* @return a new ManagedString representing the joined strings.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcd");
|
||||
* ManagedString p("efgh")
|
||||
*
|
||||
* print(s + p) // prints "abcdefgh"
|
||||
* @endcode
|
||||
*/
|
||||
ManagedString operator+ (ManagedString& s);
|
||||
|
||||
/**
|
||||
* Provides a character value at a given position in the string, indexed from zero.
|
||||
*
|
||||
* @param index The position of the character to return.
|
||||
* @return the character at posisiton index, zero if index is invalid.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcd");
|
||||
*
|
||||
* print(s.charAt(1)) // prints "b"
|
||||
* @endcode
|
||||
*/
|
||||
char charAt(int16_t index);
|
||||
|
||||
|
||||
/**
|
||||
* Provides an immutable 8 bit wide haracter buffer representing this string.
|
||||
*
|
||||
* @return a pointer to the character buffer.
|
||||
*/
|
||||
const char *toCharArray();
|
||||
|
||||
/**
|
||||
* Determines the length of this ManagedString in characters.
|
||||
*
|
||||
* @return the length of the string in characters.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ManagedString s("abcd");
|
||||
*
|
||||
* print(s.length()) // prints "4"
|
||||
* @endcode
|
||||
*/
|
||||
int16_t length();
|
||||
|
||||
/**
|
||||
* Empty String constant
|
||||
*/
|
||||
static ManagedString EmptyString;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Internal constructor helper.
|
||||
* Configures this ManagedString to refer to the static EmptyString
|
||||
*/
|
||||
void initEmpty();
|
||||
|
||||
/**
|
||||
* Internal constructor helper.
|
||||
* creates this ManagedString based on a given null terminated char array.
|
||||
*/
|
||||
void initString(const char *str);
|
||||
|
||||
/**
|
||||
* Private Constructor.
|
||||
* Create a managed string based on a concat of two strings.
|
||||
* The buffer is copied to ensure sane memory management (the supplied
|
||||
* character buffer may be decalred on the stack for instance).
|
||||
*
|
||||
* @param str1 The first string on which to base the new ManagedString
|
||||
* @param str2 The second string on which to base the new ManagedString
|
||||
*/
|
||||
ManagedString(const ManagedString &s1, const ManagedString &s2);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
162
inc/ManagedType.h
Normal file
162
inc/ManagedType.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
#ifndef MICROBIT_MANAGED_TYPE
|
||||
#define MICROBIT_MANAGED_TYPE
|
||||
|
||||
/**
|
||||
* Class definition for a Generic Managed Type.
|
||||
*
|
||||
* Represents a reference counted object.
|
||||
*
|
||||
* @info When the destructor is called delete is called on the object - implicitly calling the given objects destructor.
|
||||
*/
|
||||
template <class T>
|
||||
class ManagedType
|
||||
{
|
||||
private:
|
||||
|
||||
int *ref;
|
||||
|
||||
public:
|
||||
|
||||
T *object;
|
||||
|
||||
/**
|
||||
* Constructor for the managed type, given a class space T.
|
||||
* @param object the object that you would like to be ref counted - of class T
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* T object = new T();
|
||||
* ManagedType<T> mt(t);
|
||||
* @endcode
|
||||
*/
|
||||
ManagedType(T* object);
|
||||
|
||||
/**
|
||||
* Default constructor for the managed type, given a class space T.
|
||||
*/
|
||||
ManagedType();
|
||||
|
||||
/**
|
||||
* Copy constructor for the managed type, given a class space T.
|
||||
* @param t another managed type instance of class type T.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* T* object = new T();
|
||||
* ManagedType<T> mt(t);
|
||||
* ManagedType<T> mt1(mt);
|
||||
* @endcode
|
||||
*/
|
||||
ManagedType(const ManagedType<T> &t);
|
||||
|
||||
/**
|
||||
* Destructor for the managed type, given a class space T.
|
||||
*/
|
||||
~ManagedType();
|
||||
|
||||
/**
|
||||
* Copy-assign member function for the managed type, given a class space.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* T* object = new T();
|
||||
* ManagedType<T> mt(t);
|
||||
* ManagedType<T> mt1 = mt;
|
||||
* @endcode
|
||||
*/
|
||||
ManagedType<T>& operator = (const ManagedType<T>&i);
|
||||
|
||||
/**
|
||||
* Returns the references to this ManagedType
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* T* object = new T();
|
||||
* ManagedType<T> mt(t);
|
||||
* ManagedType<T> mt1(mt);
|
||||
*
|
||||
* mt.getReferences // this will be 2!
|
||||
* @endcode
|
||||
*/
|
||||
int getReferences();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor for the managed type, given a class space.
|
||||
*/
|
||||
template<typename T>
|
||||
ManagedType<T>::ManagedType(T* object)
|
||||
{
|
||||
this->object = object;
|
||||
ref = (int *)malloc(sizeof(int));
|
||||
*ref = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for the managed type, given a class space.
|
||||
*/
|
||||
template<typename T>
|
||||
ManagedType<T>::ManagedType()
|
||||
{
|
||||
this->object = NULL;
|
||||
ref = (int *)malloc(sizeof(int));
|
||||
*ref = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor for the managed type, given a class space.
|
||||
*/
|
||||
template<typename T>
|
||||
ManagedType<T>::ManagedType(const ManagedType<T> &t)
|
||||
{
|
||||
this->object = t.object;
|
||||
this->ref = t.ref;
|
||||
(*ref)++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for the managed type, given a class space.
|
||||
*/
|
||||
template<typename T>
|
||||
ManagedType<T>::~ManagedType()
|
||||
{
|
||||
if (--(*ref) == 0)
|
||||
{
|
||||
delete object;
|
||||
free(ref);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy-assign member function for the managed type, given a class space.
|
||||
*/
|
||||
template<typename T>
|
||||
ManagedType<T>& ManagedType<T>::operator = (const ManagedType<T>&t)
|
||||
{
|
||||
if (this == &t)
|
||||
return *this;
|
||||
|
||||
if (--(*ref) == 0)
|
||||
{
|
||||
delete object;
|
||||
free(ref);
|
||||
}
|
||||
|
||||
object = t.object;
|
||||
ref = t.ref;
|
||||
|
||||
(*ref)++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the references to this ManagedType
|
||||
*/
|
||||
template<typename T>
|
||||
int ManagedType<T>::getReferences()
|
||||
{
|
||||
return (*ref);
|
||||
}
|
||||
#endif
|
279
inc/MicroBit.h
Normal file
279
inc/MicroBit.h
Normal file
|
@ -0,0 +1,279 @@
|
|||
#ifndef MICROBIT_H
|
||||
#define MICROBIT_H
|
||||
|
||||
// DEBUG. Enable this to get debug message routed through the USB serial interface.
|
||||
//#define MICROBIT_DBG
|
||||
|
||||
#include "mbed.h"
|
||||
#include "ble/BLE.h"
|
||||
#include "ble/services/DeviceInformationService.h"
|
||||
|
||||
//error number enumeration
|
||||
#include "ErrorNo.h"
|
||||
|
||||
/**
|
||||
* Displays "=(" and an accompanying status code
|
||||
* @param statusCode the appropriate status code - 0 means no code will be displayed. Status codes must be in the range 0-255.
|
||||
*/
|
||||
void panic(int statusCode);
|
||||
|
||||
#include "MicroBitMalloc.h"
|
||||
#include "MicroBitCompat.h"
|
||||
#include "MicroBitFiber.h"
|
||||
#include "ManagedType.h"
|
||||
#include "ManagedString.h"
|
||||
#include "MicroBitFont.h"
|
||||
#include "MicroBitImage.h"
|
||||
#include "MicroBitEvent.h"
|
||||
#include "MicroBitMessageBus.h"
|
||||
#include "DynamicPwm.h"
|
||||
#include "MicroBitComponent.h"
|
||||
#include "MicroBitI2C.h"
|
||||
#include "MicroBitSerial.h"
|
||||
#include "MicroBitButton.h"
|
||||
#include "MicroBitMultiButton.h"
|
||||
#include "MicroBitDisplay.h"
|
||||
#include "MicroBitPin.h"
|
||||
#include "MicroBitIO.h"
|
||||
#include "MicroBitCompass.h"
|
||||
#include "MicroBitAccelerometer.h"
|
||||
|
||||
#include "MicroBitDFUService.h"
|
||||
#include "MicroBitEventService.h"
|
||||
#include "ExternalEvents.h"
|
||||
|
||||
// MicroBit::flags values
|
||||
#define MICROBIT_FLAG_SCHEDULER_RUNNING 0x00000001
|
||||
#define MICROBIT_FLAG_ACCELEROMETER_RUNNING 0x00000002
|
||||
#define MICROBIT_FLAG_DISPLAY_RUNNING 0x00000004
|
||||
#define MICROBIT_FLAG_COMPASS_RUNNING 0x00000008
|
||||
|
||||
|
||||
// Random number generator
|
||||
#define NRF51822_RNG_ADDRESS 0x4000D000
|
||||
|
||||
#define MICROBIT_IO_PINS 20 // TODO: Need to change for live, currently 3 for test
|
||||
|
||||
// Enumeration of core components.
|
||||
#define MICROBIT_ID_BUTTON_A 1
|
||||
#define MICROBIT_ID_BUTTON_B 2
|
||||
#define MICROBIT_ID_BUTTON_RESET 3
|
||||
#define MICROBIT_ID_ACCELEROMETER 4
|
||||
#define MICROBIT_ID_COMPASS 5
|
||||
#define MICROBIT_ID_DISPLAY 6
|
||||
|
||||
//EDGE connector events
|
||||
#define MICROBIT_ID_IO_P0 7 //P0 is the left most pad (ANALOG/DIGITAL)
|
||||
#define MICROBIT_ID_IO_P1 8 //P1 is the middle pad (ANALOG/DIGITAL)
|
||||
#define MICROBIT_ID_IO_P2 9 //P2 is the right most pad (ANALOG/DIGITAL)
|
||||
#define MICROBIT_ID_IO_P3 10 //COL1 (ANALOG/DIGITAL)
|
||||
#define MICROBIT_ID_IO_P4 11 //BTN_A
|
||||
#define MICROBIT_ID_IO_P5 12 //COL2 (ANALOG/DIGITAL)
|
||||
#define MICROBIT_ID_IO_P6 13 //ROW2
|
||||
#define MICROBIT_ID_IO_P7 14 //ROW1
|
||||
#define MICROBIT_ID_IO_P8 15 //PIN 18
|
||||
#define MICROBIT_ID_IO_P9 16 //ROW3
|
||||
#define MICROBIT_ID_IO_P10 17 //COL3 (ANALOG/DIGITAL)
|
||||
#define MICROBIT_ID_IO_P11 18 //BTN_B
|
||||
#define MICROBIT_ID_IO_P12 19 //PIN 20
|
||||
#define MICROBIT_ID_IO_P13 20 //SCK
|
||||
#define MICROBIT_ID_IO_P14 21 //MISO
|
||||
#define MICROBIT_ID_IO_P15 22 //MOSI
|
||||
#define MICROBIT_ID_IO_P16 23 //PIN 16
|
||||
#define MICROBIT_ID_IO_P19 24 //SCL
|
||||
#define MICROBIT_ID_IO_P20 25 //SDA
|
||||
|
||||
#define MICROBIT_ID_BUTTON_AB 26 // Button A+B multibutton
|
||||
|
||||
// mBed pin assignments of core components.
|
||||
//TODO: When platform is built for MB2 - pins will be defined by default, these will change...
|
||||
#define MICROBIT_PIN_SDA P0_30
|
||||
#define MICROBIT_PIN_SCL P0_0
|
||||
|
||||
#define MICROBIT_SYSTEM_COMPONENTS 10
|
||||
#define MICROBIT_IDLE_COMPONENTS 6
|
||||
|
||||
#ifdef MICROBIT_DEBUG
|
||||
extern Serial pc;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Class definition for a MicroBit device.
|
||||
*
|
||||
* Represents the device as a whole, and includes member variables to that reflect the components of the system.
|
||||
*/
|
||||
class MicroBit
|
||||
{
|
||||
private:
|
||||
|
||||
void seedRandom();
|
||||
uint32_t randomValue;
|
||||
|
||||
public:
|
||||
|
||||
// Map of device state.
|
||||
uint32_t flags;
|
||||
|
||||
// Periodic callback
|
||||
Ticker systemTicker;
|
||||
|
||||
// I2C Interface
|
||||
MicroBitI2C i2c;
|
||||
|
||||
// Serial Interface
|
||||
MicroBitSerial serial;
|
||||
|
||||
// Array of components which are iterated during a system tick
|
||||
MicroBitComponent* systemTickComponents[MICROBIT_SYSTEM_COMPONENTS];
|
||||
|
||||
// Array of components which are iterated during idle thread execution, isIdleCallbackNeeded is polled during a systemTick.
|
||||
MicroBitComponent* idleThreadComponents[MICROBIT_IDLE_COMPONENTS];
|
||||
|
||||
// Device level Message Bus abstraction
|
||||
MicroBitMessageBus MessageBus;
|
||||
|
||||
// Member variables to represent each of the core components on the device.
|
||||
MicroBitDisplay display;
|
||||
MicroBitButton buttonA;
|
||||
MicroBitButton buttonB;
|
||||
MicroBitMultiButton buttonAB;
|
||||
MicroBitAccelerometer accelerometer;
|
||||
MicroBitCompass compass;
|
||||
|
||||
//An object of available IO pins on the device
|
||||
MicroBitIO io;
|
||||
|
||||
// Bluetooth related member variables.
|
||||
BLEDevice *ble;
|
||||
DeviceInformationService *ble_device_information_service;
|
||||
MicroBitDFUService *ble_firmware_update_service;
|
||||
MicroBitEventService *ble_event_service;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a representation of a MicroBit device as a global singleton.
|
||||
* @param messageBus callback function to receive MicroBitMessageBus events.
|
||||
*
|
||||
* Exposed objects:
|
||||
* @code
|
||||
* uBit.systemTicker; //the Ticker callback that performs routines like updating the display.
|
||||
* uBit.MessageBus; //The message bus where events are fired.
|
||||
* uBit.display; //The display object for the LED matrix.
|
||||
* uBit.buttonA; //The buttonA object for button a.
|
||||
* uBit.buttonB; //The buttonB object for button b.
|
||||
* uBit.resetButton; //The resetButton used for soft resets.
|
||||
* uBit.accelerometer; //The object that represents the inbuilt accelerometer
|
||||
* uBit.compass; //The object that represents the inbuilt compass(magnetometer)
|
||||
* uBit.io.P*; //Where P* is P0 to P16, P19 & P20 on the edge connector
|
||||
* @endcode
|
||||
*/
|
||||
MicroBit();
|
||||
|
||||
/**
|
||||
* Post constructor initialisation method.
|
||||
* After *MUCH* pain, it's noted that the BLE stack can't be brought up in a
|
||||
* static context, so we bring it up here rather than in the constructor.
|
||||
* n.b. This method *must* be called in main() or later, not before.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.init();
|
||||
* @endcode
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Delay for the given amount of time.
|
||||
* If the scheduler is running, this will deschedule the current fiber and perform
|
||||
* a power efficent, concurrent sleep operation.
|
||||
* If the scheduler is disabled or we're running in an interrupt context, this
|
||||
* will revert to a busy wait.
|
||||
*
|
||||
* @note Values of 6 and below tend to lose resolution - do you really need to sleep for this short amount of time?
|
||||
*
|
||||
* @param milliseconds the amount of time, in ms, to wait for. This number cannot be negative.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.sleep(20); //sleep for 20ms
|
||||
* @endcode
|
||||
*/
|
||||
void sleep(int milliseconds);
|
||||
|
||||
/**
|
||||
* Generate a random number in the given range.
|
||||
* We use the NRF51822 in built random number generator here
|
||||
* TODO: Determine if we want to, given its relatively high power consumption!
|
||||
*
|
||||
* @param max the upper range to generate a number for. This number cannot be negative
|
||||
* @return A random, natural number between 0 and the max-1. Or MICROBIT_INVALID_VALUE (defined in ErrorNo.h) if max is <= 0.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.random(200); //a number between 0 and 199
|
||||
* @endcode
|
||||
*/
|
||||
int random(int max);
|
||||
|
||||
/**
|
||||
* Period callback. Used by MicroBitDisplay, FiberScheduler and I2C sensors to
|
||||
* provide a power efficient sense of time.
|
||||
*/
|
||||
void systemTick();
|
||||
|
||||
/**
|
||||
* System tasks to be executed by the idle thread when the Micro:Bit isn't busy or when data needs to be read.
|
||||
*/
|
||||
void systemTasks();
|
||||
|
||||
/**
|
||||
* add a component to the array of system components which invocate the systemTick member function during a systemTick
|
||||
*/
|
||||
void addSystemComponent(MicroBitComponent *component);
|
||||
|
||||
/**
|
||||
* remove a component from the array of system components
|
||||
*/
|
||||
void removeSystemComponent(MicroBitComponent *component);
|
||||
|
||||
/**
|
||||
* add a component to the array of of idle thread components.
|
||||
* isIdleCallbackNeeded is polled during a systemTick to determine if the idle thread should jump to the front of the queue
|
||||
*/
|
||||
void addIdleComponent(MicroBitComponent *component);
|
||||
|
||||
/**
|
||||
* remove a component from the array of idle thread components
|
||||
*/
|
||||
void removeIdleComponent(MicroBitComponent *component);
|
||||
|
||||
/**
|
||||
* Determine the time since this MicroBit was last reset.
|
||||
*
|
||||
* @return The time since the last reset, in milliseconds. This will result in overflow after 1.6 months.
|
||||
* TODO: handle overflow case.
|
||||
*/
|
||||
unsigned long systemTime();
|
||||
|
||||
/**
|
||||
* Triggers a microbit panic where an infinite loop will occur swapping between the panicFace and statusCode if provided.
|
||||
*
|
||||
* @param statusCode the status code of the associated error. Status codes must be in the range 0-255.
|
||||
*/
|
||||
void panic(int statusCode = 0);
|
||||
|
||||
};
|
||||
|
||||
// Definition of the global instance of the MicroBit class.
|
||||
// Using this as a variation on the singleton pattern, just to make
|
||||
// code integration a little bit easier for 3rd parties.
|
||||
extern MicroBit uBit;
|
||||
|
||||
// Entry point for application programs. Called after the super-main function
|
||||
// has initialized the device and runtime environment.
|
||||
extern "C" void app_main();
|
||||
|
||||
|
||||
#endif
|
||||
|
161
inc/MicroBitAccelerometer.h
Normal file
161
inc/MicroBitAccelerometer.h
Normal file
|
@ -0,0 +1,161 @@
|
|||
#ifndef MICROBIT_ACCELEROMETER_H
|
||||
#define MICROBIT_ACCELEROMETER_H
|
||||
|
||||
#include "mbed.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
|
||||
|
||||
struct MMA8653Sample
|
||||
{
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 MicroBitAccelerometer : public MicroBitComponent
|
||||
{
|
||||
/**
|
||||
* Unique, enumerated ID for this component.
|
||||
* Used to track asynchronous events in the event bus.
|
||||
*/
|
||||
|
||||
//if you are adding status here - don't it's in MicroBitComponent!!!
|
||||
uint16_t address; // I2C address of this accelerometer.
|
||||
MMA8653Sample sample; // The last sample read.
|
||||
DigitalIn int1; // Data ready interrupt.
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create an accelerometer representation with the given ID.
|
||||
* @param id the ID of the new object.
|
||||
* @param address the default base address of the accelerometer.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* accelerometer(MICROBIT_ID_ACCELEROMETER, MMA8653_DEFAULT_ADDR)
|
||||
* @endcode
|
||||
*/
|
||||
MicroBitAccelerometer(uint16_t id, uint16_t address);
|
||||
|
||||
/**
|
||||
* Reads the acceleration data from the accelerometer, and stores it in our buffer.
|
||||
* This is called by the tick() member function, if the interrupt is set!
|
||||
*/
|
||||
void update();
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to determine the 8 bit ID from the accelerometer.
|
||||
* @return the 8 bit ID returned by the accelerometer
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.accelerometer.whoAmI();
|
||||
* @endcode
|
||||
*/
|
||||
int whoAmI();
|
||||
|
||||
/**
|
||||
* Reads the X axis value of the latest update from the accelerometer.
|
||||
* Currently limited to +/- 2g
|
||||
* @return The force measured in the X axis, in milli-g.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.accelerometer.getX();
|
||||
* @endcode
|
||||
*/
|
||||
int getX();
|
||||
|
||||
/**
|
||||
* Reads the Y axis value of the latest update from the accelerometer.
|
||||
* Currently limited to +/- 2g
|
||||
* @return The force measured in the Y axis, in milli-g.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.accelerometer.getY();
|
||||
* @endcode
|
||||
*/
|
||||
int getY();
|
||||
|
||||
/**
|
||||
* Reads the Z axis value of the latest update from the accelerometer.
|
||||
* Currently limited to +/- 2g
|
||||
* @return The force measured in the Z axis, in milli-g.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.accelerometer.getZ();
|
||||
* @endcode
|
||||
*/
|
||||
int getZ();
|
||||
|
||||
/**
|
||||
* periodic callback from MicroBit idle thread.
|
||||
* Check if any data is ready for reading by checking the interrupt flag on the accelerometer
|
||||
*/
|
||||
virtual void idleTick();
|
||||
|
||||
/**
|
||||
* Returns 0 or 1. 1 indicates data is waiting to be read, zero means data is not ready to be read.
|
||||
*/
|
||||
virtual int isIdleCallbackNeeded();
|
||||
|
||||
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.
|
||||
*/
|
||||
void writeCommand(uint8_t reg, uint8_t value);
|
||||
|
||||
/**
|
||||
* Issues a read command 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.
|
||||
*/
|
||||
void readCommand(uint8_t reg, uint8_t* buffer, int length);
|
||||
};
|
||||
|
||||
#endif
|
92
inc/MicroBitButton.h
Normal file
92
inc/MicroBitButton.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
#ifndef MICROBIT_BUTTON_H
|
||||
#define MICROBIT_BUTTON_H
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
//TODO: When platform is built for MB2 - pins will be defined by default, these will change...
|
||||
#define MICROBIT_PIN_BUTTON_A P0_17
|
||||
#define MICROBIT_PIN_BUTTON_B P0_26
|
||||
#define MICROBIT_PIN_BUTTON_RESET P0_19
|
||||
|
||||
#define MICROBIT_BUTTON_EVT_DOWN 1
|
||||
#define MICROBIT_BUTTON_EVT_UP 2
|
||||
#define MICROBIT_BUTTON_EVT_CLICK 3
|
||||
#define MICROBIT_BUTTON_EVT_LONG_CLICK 4
|
||||
#define MICROBIT_BUTTON_EVT_HOLD 5
|
||||
#define MICROBIT_BUTTON_EVT_DOUBLE_CLICK 6
|
||||
|
||||
#define MICROBIT_BUTTON_LONG_CLICK_TIME 1000
|
||||
#define MICROBIT_BUTTON_HOLD_TIME 1500
|
||||
|
||||
#define MICROBIT_BUTTON_STATE 1
|
||||
#define MICROBIT_BUTTON_STATE_HOLD_TRIGGERED 2
|
||||
#define MICROBIT_BUTTON_STATE_CLICK 4
|
||||
#define MICROBIT_BUTTON_STATE_LONG_CLICK 8
|
||||
|
||||
#define MICROBIT_BUTTON_SIGMA_MIN 0
|
||||
#define MICROBIT_BUTTON_SIGMA_MAX 12
|
||||
#define MICROBIT_BUTTON_SIGMA_THRESH_HI 8
|
||||
#define MICROBIT_BUTTON_SIGMA_THRESH_LO 2
|
||||
#define MICROBIT_BUTTON_DOUBLE_CLICK_THRESH 50
|
||||
|
||||
/**
|
||||
* Class definition for MicroBit Button.
|
||||
*
|
||||
* Represents a single, generic button on the device.
|
||||
*/
|
||||
class MicroBitButton : public MicroBitComponent
|
||||
{
|
||||
PinName name; // mBed pin name of this pin.
|
||||
DigitalIn pin; // The mBed object looking after this pin at any point in time (may change!).
|
||||
|
||||
unsigned long downStartTime; // used to store the current system clock when a button down event occurs
|
||||
uint8_t sigma; // integration of samples over time.
|
||||
uint8_t doubleClickTimer; // double click timer (ticks).
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a pin representation with the given ID.
|
||||
* @param id the ID of the new MicroBitButton object.
|
||||
* @param name the physical pin on the processor that this butotn is connected to.
|
||||
* @param mode the configuration of internal pullups/pulldowns, as define in the mbed PinMode class. PullNone by default.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* buttonA(MICROBIT_ID_BUTTON_A,MICROBIT_PIN_BUTTON_A); //a number between 0 and 200 inclusive
|
||||
* @endcode
|
||||
*
|
||||
* Possible Events:
|
||||
* @code
|
||||
* MICROBIT_BUTTON_EVT_DOWN
|
||||
* MICROBIT_BUTTON_EVT_UP
|
||||
* MICROBIT_BUTTON_EVT_CLICK
|
||||
* MICROBIT_BUTTON_EVT_LONG_CLICK
|
||||
* MICROBIT_BUTTON_EVT_DOUBLE_CLICK
|
||||
* MICROBIT_BUTTON_EVT_HOLD
|
||||
* @endcode
|
||||
*/
|
||||
MicroBitButton(uint16_t id, PinName name, PinMode mode = PullNone);
|
||||
|
||||
/**
|
||||
* Tests if this Button is currently pressed.
|
||||
* @return 1 if this button is pressed, 0 otherwise.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* if(uBit.buttonA.isPressed())
|
||||
* print("Pressed!");
|
||||
* @endcode
|
||||
*/
|
||||
int isPressed();
|
||||
|
||||
/**
|
||||
* periodic callback from MicroBit clock.
|
||||
* Check for state change for this button, and fires a hold event if button is pressed.
|
||||
*/
|
||||
virtual void systemTick();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
262
inc/MicroBitCompass.h
Normal file
262
inc/MicroBitCompass.h
Normal file
|
@ -0,0 +1,262 @@
|
|||
#ifndef MICROBIT_COMPASS_H
|
||||
#define MICROBIT_COMPASS_H
|
||||
|
||||
#include "mbed.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
|
||||
|
||||
/*
|
||||
* Compass events
|
||||
*/
|
||||
#define MICROBIT_COMPASS_EVT_CAL_REQUIRED 1
|
||||
#define MICROBIT_COMPASS_EVT_CAL_START 2
|
||||
#define MICROBIT_COMPASS_EVT_CAL_END 3
|
||||
|
||||
/*
|
||||
* Status Bits
|
||||
*/
|
||||
#define MICROBIT_COMPASS_STATUS_CALIBRATED 1
|
||||
#define MICROBIT_COMPASS_STATUS_CALIBRATING 2
|
||||
|
||||
|
||||
#define MICROBIT_COMPASS_CALIBRATE_PERIOD 10000
|
||||
|
||||
/*
|
||||
* MAG3110 MAGIC ID value
|
||||
* Returned from the MAG_WHO_AM_I register for ID purposes.
|
||||
*/
|
||||
#define MAG3110_WHOAMI_VAL 0xC4
|
||||
|
||||
struct CompassSample
|
||||
{
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
|
||||
CompassSample()
|
||||
{
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class definition for MicroBit Compass.
|
||||
*
|
||||
* Represents an implementation of the Freescale MAG3110 I2C Magnetmometer.
|
||||
* Also includes basic caching, calibration and on demand activation.
|
||||
*/
|
||||
class MicroBitCompass : public MicroBitComponent
|
||||
{
|
||||
/**
|
||||
* Unique, enumerated ID for this component.
|
||||
* Used to track asynchronous events in the event bus.
|
||||
*/
|
||||
|
||||
uint16_t address; // I2C address of the magnetmometer.
|
||||
|
||||
unsigned long eventStartTime; // used to store the current system clock when async calibration has started
|
||||
|
||||
public:
|
||||
|
||||
CompassSample minSample; // Calibration sample.
|
||||
CompassSample maxSample; // Calibration sample.
|
||||
CompassSample average; // Centre point of sample data.
|
||||
CompassSample sample; // The latest sample data recorded.
|
||||
DigitalIn int1; // Data ready interrupt.
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a compass representation with the given ID.
|
||||
* @param id the event ID of the compass object.
|
||||
* @param address the default address for the compass register
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* compass(MICROBIT_ID_COMPASS, MAG3110_DEFAULT_ADDR);
|
||||
* @endcode
|
||||
*
|
||||
* Possible Events for the compass are as follows:
|
||||
* @code
|
||||
* MICROBIT_COMPASS_EVT_CAL_REQUIRED // triggered when no magnetometer data is available in persistent storage
|
||||
* MICROBIT_COMPASS_EVT_CAL_START // triggered when calibration has begun
|
||||
* MICROBIT_COMPASS_EVT_CAL_END // triggered when calibration has finished.
|
||||
* @endcode
|
||||
*/
|
||||
MicroBitCompass(uint16_t id, uint16_t address);
|
||||
|
||||
/**
|
||||
* Gets the current heading of the device, relative to magnetic north.
|
||||
* @return the current heading, in degrees.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.compass.heading();
|
||||
* @endcode
|
||||
*/
|
||||
int heading();
|
||||
|
||||
/**
|
||||
* Attempts to determine the 8 bit ID from the magnetometer.
|
||||
* @return the id of the compass (magnetometer)
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.compass.whoAmI();
|
||||
* @endcode
|
||||
*/
|
||||
int whoAmI();
|
||||
|
||||
/**
|
||||
* Reads the X axis value of the latest update from the compass.
|
||||
* @return The magnetic force measured in the X axis, in no specific units.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.compass.getX();
|
||||
* @endcode
|
||||
*/
|
||||
int getX();
|
||||
|
||||
/**
|
||||
* Reads the Y axis value of the latest update from the compass.
|
||||
* @return The magnetic force measured in the Y axis, in no specific units.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.compass.getY();
|
||||
* @endcode
|
||||
*/
|
||||
int getY();
|
||||
|
||||
/**
|
||||
* Reads the Z axis value of the latest update from the compass.
|
||||
* @return The magnetic force measured in the Z axis, in no specific units.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* uBit.compass.getZ();
|
||||
* @endcode
|
||||
*/
|
||||
int getZ();
|
||||
|
||||
/**
|
||||
* Perform the asynchronous calibration of the compass.
|
||||
* This will fire MICROBIT_COMPASS_EVT_CAL_START and MICROBIT_COMPASS_EVT_CAL_END when finished.
|
||||
* @note THIS MUST BE CALLED TO GAIN RELIABLE VALUES FROM THE COMPASS
|
||||
*/
|
||||
void calibrateAsync();
|
||||
|
||||
/**
|
||||
* Perform a calibration of the compass.
|
||||
* This will fire MICROBIT_COMPASS_EVT_CAL_START.
|
||||
* @note THIS MUST BE CALLED TO GAIN RELIABLE VALUES FROM THE COMPASS
|
||||
*/
|
||||
void calibrateStart();
|
||||
|
||||
/**
|
||||
* Complete the calibration of the compass.
|
||||
* This will fire MICROBIT_COMPASS_EVT_CAL_END.
|
||||
* @note THIS MUST BE CALLED TO GAIN RELIABLE VALUES FROM THE COMPASS
|
||||
*/
|
||||
void calibrateEnd();
|
||||
|
||||
/**
|
||||
* Periodic callback from MicroBit idle thread.
|
||||
* Check if any data is ready for reading by checking the interrupt.
|
||||
*/
|
||||
virtual void idleTick();
|
||||
|
||||
/**
|
||||
* Returns 0 or 1. 1 indicates that the compass is calibrated, zero means the compass requires calibration.
|
||||
*/
|
||||
int isCalibrated();
|
||||
|
||||
/**
|
||||
* Returns 0 or 1. 1 indicates that the compass is calibrating, zero means the compass is not currently calibrating.
|
||||
*/
|
||||
int isCalibrating();
|
||||
|
||||
/**
|
||||
* Clears the calibration held in persistent storage, and sets the calibrated flag to zero.
|
||||
*/
|
||||
void clearCalibration();
|
||||
|
||||
/**
|
||||
* Returns 0 or 1. 1 indicates data is waiting to be read, zero means data is not ready to be read.
|
||||
*/
|
||||
virtual int isIdleCallbackNeeded();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Issues a standard, 2 byte I2C command write to the magnetometer.
|
||||
* Blocks the calling thread until complete.
|
||||
*
|
||||
* @param reg The address of the register to write to.
|
||||
* @param value The value to write.
|
||||
*/
|
||||
void writeCommand(uint8_t reg, uint8_t value);
|
||||
|
||||
/**
|
||||
* Issues a read command 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.
|
||||
*/
|
||||
void readCommand(uint8_t reg, uint8_t* buffer, int length);
|
||||
|
||||
/**
|
||||
* Issues a read of a given address, and returns the value.
|
||||
* Blocks the calling thread until complete.
|
||||
*
|
||||
* @param reg The based address of the 16 bit register to access.
|
||||
* @return The register value, interpreted as a 16 but signed value.
|
||||
*/
|
||||
int16_t read16(uint8_t reg);
|
||||
|
||||
|
||||
/**
|
||||
* Issues a read of a given address, and returns the value.
|
||||
* Blocks the calling thread until complete.
|
||||
*
|
||||
* @param reg The based address of the 16 bit register to access.
|
||||
* @return The register value, interpreted as a 8 bi signed value.
|
||||
*/
|
||||
int16_t read8(uint8_t reg);
|
||||
};
|
||||
|
||||
#endif
|
73
inc/MicroBitCompat.h
Normal file
73
inc/MicroBitCompat.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* Compatibility / portability funcitons and constants for the MicroBit DAL.
|
||||
*/
|
||||
|
||||
#ifndef MICROBIT_COMPAT_H
|
||||
#define MICROBIT_COMPAT_H
|
||||
|
||||
#define PI 3.14159265359
|
||||
|
||||
/*! \
|
||||
\brief Utility functions.
|
||||
|
||||
Included here often to reduce the need to import a whole library for simple opertations.
|
||||
This helps to minimize our SRAM footprint.
|
||||
*/
|
||||
/*!
|
||||
\brief returns the smallest of the two numbers
|
||||
\param a the first number
|
||||
\param b the number to compare against a
|
||||
\return whichever value is the smallest
|
||||
*/
|
||||
inline int min(int a, int b)
|
||||
{
|
||||
return (a < b ? a : b);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief returns the biggest of the two numbers
|
||||
\param a the first number
|
||||
\param b the number to compare against a
|
||||
\return whichever value is the biggest
|
||||
*/
|
||||
inline int max(int a, int b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clears b number of bytes given the pointer a
|
||||
\param a the pointer to the beginning of the memory to clear
|
||||
\param b the number of bytes to clear.
|
||||
*/
|
||||
inline void *memclr(void *a, size_t b)
|
||||
{
|
||||
return memset(a,0,b);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief returns true if the character c lies between ascii values 48 and 57 inclusive.
|
||||
\param c the character to check
|
||||
\return a bool, true if it is a digit, false otherwise
|
||||