updates
Dependencies: BLE_API mbed-dev-bin nRF51822
Fork of microbit-dal-eddystone by
Revision 35:8ce23bc1af38, committed 2016-07-13
- Comitter:
- LancasterUniversity
- Date:
- Wed Jul 13 12:18:14 2016 +0100
- Parent:
- 34:9162efc289ca
- Child:
- 36:6837feb07da4
- Commit message:
- Synchronized with git rev 732971e7
Author: James Devine
microbit-dal: Added events to MicroBitPin
Added rise, fall, pulse HI and LO events.
The pulse Hi and LO event timestamp given in the MicroBitEvent is the
duration for which the input was HI or LO for.
eventOn(int eventType) is used to configure the events generated
from the pin instance.
Changed in this revision
--- a/inc/bluetooth/MicroBitIOPinService.h Wed Jul 13 12:18:13 2016 +0100 +++ b/inc/bluetooth/MicroBitIOPinService.h Wed Jul 13 12:18:14 2016 +0100 @@ -30,7 +30,7 @@ #include "ble/BLE.h" #include "MicroBitIO.h" -#define MICROBIT_IO_PIN_SERVICE_PINCOUNT 19 +#define MICROBIT_IO_PIN_SERVICE_PINCOUNT 20 #define MICROBIT_IO_PIN_SERVICE_DATA_SIZE 10 // UUIDs for our service and characteristics
--- a/inc/core/MicroBitSystemTimer.h Wed Jul 13 12:18:13 2016 +0100 +++ b/inc/core/MicroBitSystemTimer.h Wed Jul 13 12:18:14 2016 +0100 @@ -43,7 +43,7 @@ #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. * @@ -70,11 +70,26 @@ 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.
--- a/inc/drivers/MicroBitPin.h Wed Jul 13 12:18:13 2016 +0100 +++ b/inc/drivers/MicroBitPin.h Wed Jul 13 12:18:14 2016 +0100 @@ -35,7 +35,8 @@ #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 @@ #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. @@ -103,6 +113,43 @@ */ 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. @@ -143,8 +190,9 @@ /** * 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 +340,37 @@ * given pin is not configured as an analog output. */ int getAnalogPeriod(); + + /** + * 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 +#endif \ No newline at end of file
--- a/inc/drivers/MicroBitStorage.h Wed Jul 13 12:18:13 2016 +0100 +++ b/inc/drivers/MicroBitStorage.h Wed Jul 13 12:18:14 2016 +0100 @@ -162,13 +162,9 @@ * * @param data a pointer to the beginning of the data to be persisted. * - * @param dataSize the size of the data to be persisted - * - * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large, - * MICROBIT_NO_RESOURCES if the storage page is full + * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the storage page is full */ - int put(const char* key, uint8_t* data, int dataSize); - + int put(const char* key, uint8_t* data); /** * Places a given key, and it's corresponding value into flash at the earliest @@ -178,12 +174,9 @@ * * @param data a pointer to the beginning of the data to be persisted. * - * @param dataSize the size of the data to be persisted - * - * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large, - * MICROBIT_NO_RESOURCES if the storage page is full + * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the storage page is full */ - int put(ManagedString key, uint8_t* data, int dataSize); + int put(ManagedString key, uint8_t* data); /** * Retreives a KeyValuePair identified by a given key.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/drivers/TimedInterruptIn.h Wed Jul 13 12:18:14 2016 +0100 @@ -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 \ No newline at end of file
--- a/inc/types/MicroBitEvent.h Wed Jul 13 12:18:13 2016 +0100 +++ b/inc/types/MicroBitEvent.h Wed Jul 13 12:18:14 2016 +0100 @@ -52,7 +52,7 @@ 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.
--- a/source/CMakeLists.txt Wed Jul 13 12:18:13 2016 +0100 +++ b/source/CMakeLists.txt Wed Jul 13 12:18:14 2016 +0100 @@ -40,6 +40,7 @@ "drivers/MicroBitSerial.cpp" "drivers/MicroBitStorage.cpp" "drivers/MicroBitThermometer.cpp" + "drivers/TimedInterruptIn.cpp" "bluetooth/MicroBitAccelerometerService.cpp" "bluetooth/MicroBitBLEManager.cpp" @@ -101,4 +102,4 @@ target_compile_options(ble PRIVATE "-w") target_compile_options(ble-nrf51822 PRIVATE "-w") target_compile_options(nrf51-sdk PRIVATE "-w") -endif() +endif() \ No newline at end of file
--- a/source/bluetooth/MicroBitBLEManager.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/bluetooth/MicroBitBLEManager.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -99,7 +99,7 @@ if(memcmp(attribStore.sys_attrs[deviceID].sys_attr, attrib.sys_attr, len) != 0) { attribStore.sys_attrs[deviceID] = attrib; - manager->storage->put(key, (uint8_t *)&attribStore, sizeof(attribStore)); + manager->storage->put(key, (uint8_t *)&attribStore); } } }
--- a/source/bluetooth/MicroBitButtonService.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/bluetooth/MicroBitButtonService.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -45,8 +45,8 @@ GattCharacteristic buttonADataCharacteristic(MicroBitButtonAServiceDataUUID, (uint8_t *)&buttonADataCharacteristicBuffer, 0, sizeof(buttonADataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); - GattCharacteristic buttonBDataCharacteristic(MicroBitButtonBServiceDataUUID, (uint8_t *)&buttonBDataCharacteristicBuffer, 0, - sizeof(buttonBDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); + GattCharacteristic buttonBDataCharacteristic(MicroBitButtonBServiceDataUUID, (uint8_t *)&buttonADataCharacteristicBuffer, 0, + sizeof(buttonADataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); // Initialise our characteristic values.
--- a/source/core/MicroBitSystemTimer.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/core/MicroBitSystemTimer.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -42,18 +42,21 @@ * 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 @@ */ 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 @@ // 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; } @@ -103,13 +112,40 @@ } /** + * 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 @@ */ 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 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)
--- a/source/drivers/MicroBitCompass.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/drivers/MicroBitCompass.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -703,7 +703,7 @@ void MicroBitCompass::setCalibration(CompassSample calibration) { if(this->storage != NULL) - this->storage->put(ManagedString("compassCal"), (uint8_t *)&calibration, sizeof(CompassSample)); + this->storage->put(ManagedString("compassCal"), (uint8_t *)&calibration); average = calibration; status |= MICROBIT_COMPASS_STATUS_CALIBRATED;
--- a/source/drivers/MicroBitMessageBus.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/drivers/MicroBitMessageBus.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -237,7 +237,7 @@ // Walk this list of event handlers. Delete any that match the given listener. while (l != NULL) { - if ((l->flags & MESSAGE_BUS_LISTENER_DELETING) && !(l->flags & MESSAGE_BUS_LISTENER_BUSY)) + if (l->flags & MESSAGE_BUS_LISTENER_DELETING && !l->flags & MESSAGE_BUS_LISTENER_BUSY) { if (p == NULL) listeners = l->next;
--- a/source/drivers/MicroBitPin.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/drivers/MicroBitPin.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -31,6 +31,8 @@ #include "MicroBitConfig.h" #include "MicroBitPin.h" #include "MicroBitButton.h" +#include "MicroBitSystemTimer.h" +#include "TimedInterruptIn.h" #include "DynamicPwm.h" #include "ErrorNo.h" @@ -92,8 +94,11 @@ 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 @@ /** * 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 @@ 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(); } @@ -430,3 +440,148 @@ { return getAnalogPeriodUs()/1000; } + +/** + * 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; +} \ No newline at end of file
--- a/source/drivers/MicroBitStorage.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/drivers/MicroBitStorage.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -209,22 +209,14 @@ * * @param data a pointer to the beginning of the data to be persisted. * - * @param dataSize the size of the data to be persisted - * - * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large, - * MICROBIT_NO_RESOURCES if the storage page is full + * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the storage page is full */ -int MicroBitStorage::put(const char *key, uint8_t *data, int dataSize) +int MicroBitStorage::put(const char *key, uint8_t *data) { KeyValuePair pair = KeyValuePair(); - int keySize = strlen(key) + 1; - - if(keySize > (int)sizeof(pair.key) || dataSize > (int)sizeof(pair.value) || dataSize < 0) - return MICROBIT_INVALID_PARAMETER; - - memcpy(pair.key, key, keySize); - memcpy(pair.value, data, dataSize); + memcpy(pair.key, key, min(sizeof(pair.key), strlen(key))); + memcpy(pair.value, data, sizeof(pair.value)); //calculate our various offsets. uint32_t pg_size = NRF_FICR->CODEPAGESIZE; @@ -298,14 +290,11 @@ * * @param data a pointer to the beginning of the data to be persisted. * - * @param dataSize the size of the data to be persisted - * - * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large, - * MICROBIT_NO_RESOURCES if the storage page is full + * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the storage page is full */ -int MicroBitStorage::put(ManagedString key, uint8_t* data, int dataSize) +int MicroBitStorage::put(ManagedString key, uint8_t* data) { - return put((char *)key.toCharArray(), data, dataSize); + return put((char *)key.toCharArray(), data); } /**
--- a/source/drivers/MicroBitThermometer.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/drivers/MicroBitThermometer.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -245,7 +245,7 @@ int MicroBitThermometer::setOffset(int offset) { if(this->storage != NULL) - this->storage->put(ManagedString("tempCal"), (uint8_t *)&offset, sizeof(int)); + this->storage->put(ManagedString("tempCal"), (uint8_t *)&offset); this->offset = offset;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/drivers/TimedInterruptIn.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -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; +} \ No newline at end of file
--- a/source/types/MicroBitEvent.cpp Wed Jul 13 12:18:13 2016 +0100 +++ b/source/types/MicroBitEvent.cpp Wed Jul 13 12:18:14 2016 +0100 @@ -58,7 +58,7 @@ { 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 @@ { this->source = 0; this->value = 0; - this->timestamp = system_timer_current_time(); + this->timestamp = system_timer_current_time_us(); } /**