This commit is contained in:
Joe Finney 2016-05-13 16:43:52 +01:00
commit 3d9283b947
16 changed files with 504 additions and 49 deletions

View File

@ -76,7 +76,7 @@ const char * microbit_dal_version();
/**
* Disables all interrupts and user processing.
* Displays "=(" and an accompanying status code on the default display.
* @param statusCode the appropriate status code - 0 means no code will be displayed. Status codes must be in the range 0-255.
* @param statusCode the appropriate status code, must be in the range 0-999.
*
* @code
* microbit_panic(20);

View File

@ -43,7 +43,7 @@ DEALINGS IN THE SOFTWARE.
#include "MicroBitComponent.h"
/**
* Initialises the system wide timer.
* Initialises a system wide timer, used to drive the various components used in the runtime.
*
* This must be called before any components register to receive periodic periodic callbacks.
*
@ -69,12 +69,27 @@ int system_timer_set_period(int period);
*/
int system_timer_get_period();
/**
* Updates the current time in microseconds, since power on.
*
* If the mbed Timer hasn't been initialised, it will be initialised
* on the first call to this function.
*/
inline void update_time();
/**
* Determines the time since the device was powered on.
*
* @return the current time since power on in milliseconds
*/
unsigned long system_timer_current_time();
uint64_t system_timer_current_time();
/**
* Determines the time since the device was powered on.
*
* @return the current time since power on in microseconds
*/
uint64_t system_timer_current_time_us();
/**
* Timer callback. Called from interrupt context, once per period.

View File

@ -35,7 +35,8 @@ DEALINGS IN THE SOFTWARE.
#define IO_STATUS_ANALOG_IN 0x04 // Pin is Analog in
#define IO_STATUS_ANALOG_OUT 0x08 // Pin is Analog out
#define IO_STATUS_TOUCH_IN 0x10 // Pin is a makey-makey style touch sensor
#define IO_STATUS_EVENTBUS_ENABLED 0x80 // Pin is will generate events on change
#define IO_STATUS_EVENT_ON_EDGE 0x20 // Pin will generate events on pin change
#define IO_STATUS_EVENT_PULSE_ON_EDGE 0x40 // Pin will generate events on pin change
//#defines for each edge connector pin
#define MICROBIT_PIN_P0 P0_3 //P0 is the left most pad (ANALOG/DIGITAL) used to be P0_3 on green board
@ -64,6 +65,15 @@ DEALINGS IN THE SOFTWARE.
#define MICROBIT_PIN_DEFAULT_SERVO_RANGE 2000
#define MICROBIT_PIN_DEFAULT_SERVO_CENTER 1500
#define MICROBIT_PIN_EVENT_NONE 0
#define MICROBIT_PIN_EVENT_ON_EDGE 1
#define MICROBIT_PIN_EVENT_ON_PULSE 2
#define MICROBIT_PIN_EVENT_ON_TOUCH 3
#define MICROBIT_PIN_EVT_RISE 2
#define MICROBIT_PIN_EVT_FALL 3
#define MICROBIT_PIN_EVT_PULSE_HI 4
#define MICROBIT_PIN_EVT_PULSE_LO 5
/**
* Pin capabilities enum.
@ -72,10 +82,8 @@ DEALINGS IN THE SOFTWARE.
enum PinCapability{
PIN_CAPABILITY_DIGITAL = 0x01,
PIN_CAPABILITY_ANALOG = 0x02,
PIN_CAPABILITY_TOUCH = 0x04,
PIN_CAPABILITY_AD = PIN_CAPABILITY_DIGITAL | PIN_CAPABILITY_ANALOG,
PIN_CAPABILITY_ALL = PIN_CAPABILITY_DIGITAL | PIN_CAPABILITY_ANALOG | PIN_CAPABILITY_TOUCH
PIN_CAPABILITY_ALL = PIN_CAPABILITY_DIGITAL | PIN_CAPABILITY_ANALOG
};
/**
@ -103,6 +111,43 @@ class MicroBitPin : public MicroBitComponent
*/
int obtainAnalogChannel();
/**
* Interrupt handler for when an rise interrupt is triggered.
*/
void onRise();
/**
* Interrupt handler for when an fall interrupt is triggered.
*/
void onFall();
/**
* This member function manages the calculation of the timestamp of a pulse detected
* on a pin whilst in IO_STATUS_EVENT_PULSE_ON_EDGE or IO_STATUS_EVENT_ON_EDGE modes.
*
* @param eventValue the event value to distribute onto the message bus.
*/
void pulseWidthEvent(int eventValue);
/**
* This member function will construct an TimedInterruptIn instance, and configure
* interrupts for rise and fall.
*
* @param eventType the specific mode used in interrupt context to determine how an
* edge/rise is processed.
*
* @return MICROBIT_OK on success
*/
int enableRiseFallEvents(int eventType);
/**
* If this pin is in a mode where the pin is generating events, it will destruct
* the current instance attached to this MicroBitPin instance.
*
* @return MICROBIT_OK on success.
*/
int disableEvents();
public:
// mbed PinName of this pin.
@ -117,7 +162,7 @@ class MicroBitPin : public MicroBitComponent
* @param name the mbed PinName for this MicroBitPin instance.
*
* @param capability the capabilities this MicroBitPin instance should have.
* (PIN_CAPABILITY_DIGITAL, PIN_CAPABILITY_ANALOG, PIN_CAPABILITY_TOUCH, PIN_CAPABILITY_AD, PIN_CAPABILITY_ALL)
* (PIN_CAPABILITY_DIGITAL, PIN_CAPABILITY_ANALOG, PIN_CAPABILITY_AD, PIN_CAPABILITY_ALL)
*
* @code
* MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL);
@ -143,8 +188,9 @@ class MicroBitPin : public MicroBitComponent
/**
* Configures this IO pin as a digital input (if necessary) and tests its current value.
*
*
* @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
* if the given pin does not have analog capability.
* if the given pin does not have digital capability.
*
* @code
* MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
@ -292,6 +338,47 @@ class MicroBitPin : public MicroBitComponent
* given pin is not configured as an analog output.
*/
int getAnalogPeriod();
/**
* Configures the pull of this pin.
*
* @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
*
* @return MICROBIT_NOT_SUPPORTED if the current pin configuration is anything other
* than a digital input, otherwise MICROBIT_OK.
*/
int setPull(PinMode pull);
/**
* Configures the events generated by this MicroBitPin instance.
*
* MICROBIT_PIN_EVENT_ON_EDGE - Configures this pin to a digital input, and generates events whenever a rise/fall is detected on this pin. (MICROBIT_PIN_EVT_RISE, MICROBIT_PIN_EVT_FALL)
* MICROBIT_PIN_EVENT_ON_PULSE - Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either HI or LO. (MICROBIT_PIN_EVT_PULSE_HI, MICROBIT_PIN_EVT_PULSE_LO)
* MICROBIT_PIN_EVENT_ON_TOUCH - Configures this pin as a makey makey style touch sensor, in the form of a MicroBitButton. Normal button events will be generated using the ID of this pin.
* MICROBIT_PIN_EVENT_NONE - Disables events for this pin.
*
* @param eventType One of: MICROBIT_PIN_EVENT_ON_EDGE, MICROBIT_PIN_EVENT_ON_PULSE, MICROBIT_PIN_EVENT_ON_TOUCH, MICROBIT_PIN_EVENT_NONE
*
* @code
* MicroBitMessageBus bus;
*
* MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
* P0.eventOn(MICROBIT_PIN_EVENT_ON_PULSE);
*
* void onPulse(MicroBitEvent evt)
* {
* int duration = evt.timestamp;
* }
*
* bus.listen(MICROBIT_ID_IO_P0, MICROBIT_PIN_EVT_PULSE_HI, onPulse, MESSAGE_BUS_LISTENER_IMMEDIATE)
* @endcode
*
* @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the given eventype does not match
*
* @note In the MICROBIT_PIN_EVENT_ON_PULSE mode, the smallest pulse that was reliably detected was 85us, around 5khz. If more precision is required,
* please use the InterruptIn class supplied by ARM mbed.
*/
int eventOn(int eventType);
};
#endif

View File

@ -0,0 +1,59 @@
/*
The MIT License (MIT)
Copyright (c) 2016 Lancaster University, UK.
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 TIMED_INTERRUPT_H
#define TIMED_INTERRUPT_H
#include "mbed.h"
#include "MicroBitConfig.h"
class TimedInterruptIn : public InterruptIn
{
uint64_t timestamp;
public:
/**
* Constructor.
*
* Create an instance of TimedInterruptIn that has an additional timestamp field.
*/
TimedInterruptIn(PinName name);
/**
* Stores the given timestamp for this instance of TimedInterruptIn.
*
* @param timestamp the timestamp to retain.
*/
void setTimestamp(uint64_t timestamp);
/**
* Retrieves the retained timestamp for this instance of TimedInterruptIn.
*
* @return the timestamp held by this instance.
*/
uint64_t getTimestamp();
};
#endif

View File

@ -300,9 +300,10 @@ class ManagedString
ManagedString substring(int16_t start, int16_t length);
/**
* Concatenates this string with the one provided.
* Concatenates two strings.
*
* @param s The ManagedString to concatenate.
* @param lhs The first ManagedString to concatenate.
* @param rhs The second ManagedString to concatenate.
*
* @return a new ManagedString representing the joined strings.
*
@ -314,7 +315,7 @@ class ManagedString
* display.scroll(s + p) // scrolls "abcdefgh"
* @endcode
*/
ManagedString operator+ (ManagedString& s);
friend ManagedString operator+ (const ManagedString& lhs, const ManagedString& rhs);
/**
* Provides a character value at a given position in the string, indexed from zero.

View File

@ -52,7 +52,7 @@ class MicroBitEvent
uint16_t source; // ID of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.
uint16_t value; // Component specific code indicating the cause of the event.
uint32_t timestamp; // Time at which the event was generated. ms since power on.
uint64_t timestamp; // Time at which the event was generated. us since power on.
/**
* Constructor.

View File

@ -1,6 +1,6 @@
{
"name": "microbit-dal",
"version": "2.0.0-rc2",
"version": "2.0.0-rc3",
"license": "MIT",
"description": "The runtime library for the BBC micro:bit, developed by Lancaster University",
"keywords": [

View File

@ -40,6 +40,7 @@ set(YOTTA_AUTO_MICROBIT-DAL_CPP_FILES
"drivers/MicroBitSerial.cpp"
"drivers/MicroBitStorage.cpp"
"drivers/MicroBitThermometer.cpp"
"drivers/TimedInterruptIn.cpp"
"bluetooth/MicroBitAccelerometerService.cpp"
"bluetooth/MicroBitBLEManager.cpp"

View File

@ -159,7 +159,7 @@ void microbit_panic_timeout(int iterations)
/**
* Disables all interrupts and user processing.
* Displays "=(" and an accompanying status code on the default display.
* @param statusCode the appropriate status code - 0 means no code will be displayed. Status codes must be in the range 0-255.
* @param statusCode the appropriate status code, must be in the range 0-999.
*
* @code
* microbit_panic(20);
@ -186,19 +186,18 @@ void microbit_panic(int statusCode)
PortOut LEDMatrix(Port0, row_mask | col_mask);
if(statusCode < 0 || statusCode > 255)
if(statusCode < 0 || statusCode > 999)
statusCode = 0;
__disable_irq(); //stop ALL interrupts
//point to the font stored in Flash
const unsigned char * fontLocation = MicroBitFont::defaultFont;
const unsigned char* fontLocation = MicroBitFont::defaultFont;
//get individual digits of status code, and place it into a single array/
const uint8_t* chars[MICROBIT_PANIC_ERROR_CHARS] = { panicFace, fontLocation+((((statusCode/100 % 10)+48)-MICROBIT_FONT_ASCII_START) * 5), fontLocation+((((statusCode/10 % 10)+48)-MICROBIT_FONT_ASCII_START) * 5), fontLocation+((((statusCode % 10)+48)-MICROBIT_FONT_ASCII_START) * 5)};
//enter infinite loop.
while(count)
{
//iterate through our chars :)
@ -234,10 +233,13 @@ void microbit_panic(int statusCode)
col_data = ~col_data << microbitMatrixMap.columnStart & col_mask;
LEDMatrix = col_data | row_data;
if(chars[characterCount] == chars[(characterCount - 1) % MICROBIT_PANIC_ERROR_CHARS] && outerCount < 50)
LEDMatrix = 0;
else
LEDMatrix = col_data | row_data;
//burn cycles
i = 1000;
i = 2000;
while(i>0)
{
// Check if the reset button has been pressed. Interrupts are disabled, so the normal method can't be relied upon...

View File

@ -42,18 +42,21 @@ DEALINGS IN THE SOFTWARE.
* Time since power on. Measured in milliseconds.
* When stored as an unsigned long, this gives us approx 50 days between rollover, which is ample. :-)
*/
static unsigned long ticks = 0;
static uint64_t time_us = 0;
static unsigned int tick_period = 0;
// Array of components which are iterated during a system tick
static MicroBitComponent* systemTickComponents[MICROBIT_SYSTEM_COMPONENTS];
// Periodic callback interrupt
static Ticker *timer = NULL;
static Ticker *ticker = NULL;
// System timer.
static Timer *timer = NULL;
/**
* Initialises the system wide timer.
* Initialises a system wide timer, used to drive the various components used in the runtime.
*
* This must be called before any components register to receive periodic periodic callbacks.
*
@ -63,8 +66,14 @@ static Ticker *timer = NULL;
*/
int system_timer_init(int period)
{
if (ticker == NULL)
ticker = new Ticker();
if (timer == NULL)
timer = new Ticker();
{
timer = new Timer();
timer->start();
}
return system_timer_set_period(period);
}
@ -83,11 +92,11 @@ int system_timer_set_period(int period)
// If a timer is already running, ensure it is disabled before reconfiguring.
if (tick_period)
timer->detach();
ticker->detach();
// register a period callback to drive the scheduler and any other registered components.
tick_period = period;
timer->attach_us(system_timer_tick, period * 1000);
ticker->attach_us(system_timer_tick, period * 1000);
return MICROBIT_OK;
}
@ -102,14 +111,41 @@ int system_timer_get_period()
return tick_period;
}
/**
* Updates the current time in microseconds, since power on.
*
* If the mbed Timer hasn't been initialised, it will be initialised
* on the first call to this function.
*/
void update_time()
{
// If we haven't been initialized, bring up the timer with the default period.
if (timer == NULL || ticker == NULL)
system_timer_init(SYSTEM_TICK_PERIOD_MS);
time_us += timer->read_us();
timer->reset();
}
/**
* Determines the time since the device was powered on.
*
* @return the current time since power on in milliseconds
*/
unsigned long system_timer_current_time()
uint64_t system_timer_current_time()
{
return ticks;
return system_timer_current_time_us() / 1000;
}
/**
* Determines the time since the device was powered on.
*
* @return the current time since power on in microseconds
*/
uint64_t system_timer_current_time_us()
{
update_time();
return time_us;
}
/**
@ -120,8 +156,7 @@ unsigned long system_timer_current_time()
*/
void system_timer_tick()
{
// increment our real-time counter.
ticks += system_timer_get_period();
update_time();
// Update any components registered for a callback
for(int i = 0; i < MICROBIT_SYSTEM_COMPONENTS; i++)
@ -144,7 +179,7 @@ int system_timer_add_component(MicroBitComponent *component)
int i = 0;
// If we haven't been initialized, bring up the timer with the default period.
if (timer == NULL)
if (timer == NULL || ticker == NULL)
system_timer_init(SYSTEM_TICK_PERIOD_MS);
while(systemTickComponents[i] != NULL && i < MICROBIT_SYSTEM_COMPONENTS)

View File

@ -31,6 +31,8 @@ DEALINGS IN THE SOFTWARE.
#include "MicroBitConfig.h"
#include "MicroBitPin.h"
#include "MicroBitButton.h"
#include "MicroBitSystemTimer.h"
#include "TimedInterruptIn.h"
#include "DynamicPwm.h"
#include "ErrorNo.h"
@ -43,7 +45,7 @@ DEALINGS IN THE SOFTWARE.
* @param name the mbed PinName for this MicroBitPin instance.
*
* @param capability the capabilities this MicroBitPin instance should have.
* (PIN_CAPABILITY_DIGITAL, PIN_CAPABILITY_ANALOG, PIN_CAPABILITY_TOUCH, PIN_CAPABILITY_AD, PIN_CAPABILITY_ALL)
* (PIN_CAPABILITY_DIGITAL, PIN_CAPABILITY_ANALOG, PIN_CAPABILITY_AD, PIN_CAPABILITY_ALL)
*
* @code
* MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL);
@ -92,8 +94,11 @@ void MicroBitPin::disconnect()
if (status & IO_STATUS_TOUCH_IN)
delete ((MicroBitButton *)pin);
if ((status & IO_STATUS_EVENT_ON_EDGE) || (status & IO_STATUS_EVENT_PULSE_ON_EDGE))
delete ((TimedInterruptIn *)pin);
this->pin = NULL;
this->status = status & IO_STATUS_EVENTBUS_ENABLED; //retain event bus status
this->status = 0;
}
/**
@ -135,8 +140,9 @@ int MicroBitPin::setDigitalValue(int value)
/**
* Configures this IO pin as a digital input (if necessary) and tests its current value.
*
*
* @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
* if the given pin does not have analog capability.
* if the given pin does not have digital capability.
*
* @code
* MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
@ -150,12 +156,16 @@ int MicroBitPin::getDigitalValue()
return MICROBIT_NOT_SUPPORTED;
// Move into a Digital input state if necessary.
if (!(status & IO_STATUS_DIGITAL_IN)){
if (!(status & (IO_STATUS_DIGITAL_IN | IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE)))
{
disconnect();
pin = new DigitalIn(name,PullDown);
status |= IO_STATUS_DIGITAL_IN;
}
if(status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE))
return ((TimedInterruptIn *)pin)->read();
return ((DigitalIn *)pin)->read();
}
@ -332,7 +342,7 @@ int MicroBitPin::isAnalog()
int MicroBitPin::isTouched()
{
//check if this pin has a touch mode...
if(!(PIN_CAPABILITY_TOUCH & capability))
if(!(PIN_CAPABILITY_DIGITAL & capability))
return MICROBIT_NOT_SUPPORTED;
// Move into a touch input state if necessary.
@ -430,3 +440,173 @@ int MicroBitPin::getAnalogPeriod()
{
return getAnalogPeriodUs()/1000;
}
/**
* Configures the pull of this pin.
*
* @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
*
* @return MICROBIT_NOT_SUPPORTED if the current pin configuration is anything other
* than a digital input, otherwise MICROBIT_OK.
*/
int MicroBitPin::setPull(PinMode pull)
{
if ((status & IO_STATUS_DIGITAL_IN))
{
((DigitalIn *)pin)->mode(pull);
return MICROBIT_OK;
}
if((status & IO_STATUS_EVENT_ON_EDGE) || (status & IO_STATUS_EVENT_PULSE_ON_EDGE))
{
((TimedInterruptIn *)pin)->mode(pull);
return MICROBIT_OK;
}
return MICROBIT_NOT_SUPPORTED;
}
/**
* This member function manages the calculation of the timestamp of a pulse detected
* on a pin whilst in IO_STATUS_EVENT_PULSE_ON_EDGE or IO_STATUS_EVENT_ON_EDGE modes.
*
* @param eventValue the event value to distribute onto the message bus.
*/
void MicroBitPin::pulseWidthEvent(int eventValue)
{
MicroBitEvent evt(id, eventValue, CREATE_ONLY);
uint64_t now = evt.timestamp;
uint64_t previous = ((TimedInterruptIn *)pin)->getTimestamp();
if (previous != 0)
{
evt.timestamp -= previous;
evt.fire();
}
((TimedInterruptIn *)pin)->setTimestamp(now);
}
/**
* Interrupt handler for when an rise interrupt is triggered.
*/
void MicroBitPin::onRise()
{
if(status & IO_STATUS_EVENT_PULSE_ON_EDGE)
pulseWidthEvent(MICROBIT_PIN_EVT_PULSE_LO);
if(status & IO_STATUS_EVENT_ON_EDGE)
MicroBitEvent(id, MICROBIT_PIN_EVT_RISE);
}
/**
* Interrupt handler for when an fall interrupt is triggered.
*/
void MicroBitPin::onFall()
{
if(status & IO_STATUS_EVENT_PULSE_ON_EDGE)
pulseWidthEvent(MICROBIT_PIN_EVT_PULSE_HI);
if(status & IO_STATUS_EVENT_ON_EDGE)
MicroBitEvent(id, MICROBIT_PIN_EVT_FALL);
}
/**
* This member function will construct an TimedInterruptIn instance, and configure
* interrupts for rise and fall.
*
* @param eventType the specific mode used in interrupt context to determine how an
* edge/rise is processed.
*
* @return MICROBIT_OK on success
*/
int MicroBitPin::enableRiseFallEvents(int eventType)
{
// if we are in neither of the two modes, configure pin as a TimedInterruptIn.
if (!(status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE)))
{
disconnect();
pin = new TimedInterruptIn(name);
((TimedInterruptIn *)pin)->mode(PullDown);
((TimedInterruptIn *)pin)->rise(this, &MicroBitPin::onRise);
((TimedInterruptIn *)pin)->fall(this, &MicroBitPin::onFall);
}
status &= ~(IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE);
// set our status bits accordingly.
if(eventType == MICROBIT_PIN_EVENT_ON_EDGE)
status |= IO_STATUS_EVENT_ON_EDGE;
else if(eventType == MICROBIT_PIN_EVENT_ON_PULSE)
status |= IO_STATUS_EVENT_PULSE_ON_EDGE;
return MICROBIT_OK;
}
/**
* If this pin is in a mode where the pin is generating events, it will destruct
* the current instance attached to this MicroBitPin instance.
*
* @return MICROBIT_OK on success.
*/
int MicroBitPin::disableEvents()
{
if (status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE | IO_STATUS_TOUCH_IN))
disconnect();
return MICROBIT_OK;
}
/**
* Configures the events generated by this MicroBitPin instance.
*
* MICROBIT_PIN_EVENT_ON_EDGE - Configures this pin to a digital input, and generates events whenever a rise/fall is detected on this pin. (MICROBIT_PIN_EVT_RISE, MICROBIT_PIN_EVT_FALL)
* MICROBIT_PIN_EVENT_ON_PULSE - Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either HI or LO. (MICROBIT_PIN_EVT_PULSE_HI, MICROBIT_PIN_EVT_PULSE_LO)
* MICROBIT_PIN_EVENT_ON_TOUCH - Configures this pin as a makey makey style touch sensor, in the form of a MicroBitButton. Normal button events will be generated using the ID of this pin.
* MICROBIT_PIN_EVENT_NONE - Disables events for this pin.
*
* @param eventType One of: MICROBIT_PIN_EVENT_ON_EDGE, MICROBIT_PIN_EVENT_ON_PULSE, MICROBIT_PIN_EVENT_ON_TOUCH, MICROBIT_PIN_EVENT_NONE
*
* @code
* MicroBitMessageBus bus;
*
* MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
* P0.eventOn(MICROBIT_PIN_EVENT_ON_PULSE);
*
* void onPulse(MicroBitEvent evt)
* {
* int duration = evt.timestamp;
* }
*
* bus.listen(MICROBIT_ID_IO_P0, MICROBIT_PIN_EVT_PULSE_HI, onPulse, MESSAGE_BUS_LISTENER_IMMEDIATE)
* @endcode
*
* @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the given eventype does not match
*
* @note In the MICROBIT_PIN_EVENT_ON_PULSE mode, the smallest pulse that was reliably detected was 85us, around 5khz. If more precision is required,
* please use the InterruptIn class supplied by ARM mbed.
*/
int MicroBitPin::eventOn(int eventType)
{
switch(eventType)
{
case MICROBIT_PIN_EVENT_ON_EDGE:
case MICROBIT_PIN_EVENT_ON_PULSE:
enableRiseFallEvents(eventType);
break;
case MICROBIT_PIN_EVENT_ON_TOUCH:
isTouched();
break;
case MICROBIT_PIN_EVENT_NONE:
disableEvents();
break;
default:
return MICROBIT_INVALID_PARAMETER;
}
return MICROBIT_OK;
}

View File

@ -489,9 +489,17 @@ int MicroBitSerial::send(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode
return result;
}
int bytesWritten = setTxInterrupt(buffer, bufferLen, mode);
bool complete = false;
int bytesWritten = 0;
send(mode);
while(!complete)
{
bytesWritten += setTxInterrupt(buffer + bytesWritten, bufferLen - bytesWritten, mode);
send(mode);
if(mode == ASYNC || bytesWritten >= bufferLen)
complete = true;
}
unlockTx();

View File

@ -223,6 +223,16 @@ int MicroBitStorage::put(const char *key, uint8_t *data, int dataSize)
if(keySize > (int)sizeof(pair.key) || dataSize > (int)sizeof(pair.value) || dataSize < 0)
return MICROBIT_INVALID_PARAMETER;
KeyValuePair *currentValue = get(key);
int upToDate = currentValue && (memcmp(currentValue->value, data, dataSize) == 0);
if(currentValue)
delete currentValue;
if(upToDate)
return MICROBIT_OK;
memcpy(pair.key, key, keySize);
memcpy(pair.value, data, dataSize);

View File

@ -0,0 +1,55 @@
/*
The MIT License (MIT)
Copyright (c) 2016 Lancaster University, UK.
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.
*/
#include "MicroBitConfig.h"
#include "TimedInterruptIn.h"
/**
* Constructor.
*
* Create an instance of TimedInterruptIn that has an additional timestamp field.
*/
TimedInterruptIn::TimedInterruptIn(PinName name) : InterruptIn(name)
{
timestamp = 0;
}
/**
* Stores the given timestamp for this instance of TimedInterruptIn.
*
* @param timestamp the timestamp to retain.
*/
void TimedInterruptIn::setTimestamp(uint64_t timestamp)
{
this->timestamp = timestamp;
}
/**
* Retrieves the retained timestamp for this instance of TimedInterruptIn.
*
* @return the timestamp held by this instance.
*/
uint64_t TimedInterruptIn::getTimestamp()
{
return timestamp;
}

View File

@ -437,9 +437,10 @@ ManagedString ManagedString::substring(int16_t start, int16_t length)
}
/**
* Concatenates this string with the one provided.
* Concatenates two strings.
*
* @param s The ManagedString to concatenate.
* @param lhs The first ManagedString to concatenate.
* @param rhs The second ManagedString to concatenate.
*
* @return a new ManagedString representing the joined strings.
*
@ -451,16 +452,17 @@ ManagedString ManagedString::substring(int16_t start, int16_t length)
* display.scroll(s + p) // scrolls "abcdefgh"
* @endcode
*/
ManagedString ManagedString::operator+ (ManagedString& s)
ManagedString operator+ (const ManagedString& lhs, const ManagedString& rhs)
{
// If the other string is empty, nothing to do!
if(s.length() == 0)
return *this;
if (length() == 0)
return s;
// If the either string is empty, nothing to do!
if (rhs.length() == 0)
return lhs;
return ManagedString(*this, s);
if (lhs.length() == 0)
return rhs;
return ManagedString(lhs, rhs);
}

View File

@ -58,7 +58,7 @@ MicroBitEvent::MicroBitEvent(uint16_t source, uint16_t value, MicroBitEventLaunc
{
this->source = source;
this->value = value;
this->timestamp = system_timer_current_time();
this->timestamp = system_timer_current_time_us();
if(mode != CREATE_ONLY)
this->fire();
@ -71,7 +71,7 @@ MicroBitEvent::MicroBitEvent()
{
this->source = 0;
this->value = 0;
this->timestamp = system_timer_current_time();
this->timestamp = system_timer_current_time_us();
}
/**