updates

Dependencies:   BLE_API mbed-dev-bin nRF51822

Fork of microbit-dal-eddystone by Martin Woolley

Files at this revision

API Documentation at this revision

Comitter:
LancasterUniversity
Date:
Wed Jul 13 12:18:46 2016 +0100
Parent:
65:f7ebabf23e15
Child:
67:99cfde195ff3
Commit message:
Synchronized with git rev a962befe
Author: Joe Finney
Merge pull request #159 from lancaster-university/bugfix-145-shake-hard-to-trigger

Bugfix 145 shake hard to trigger

Changed in this revision

inc/bluetooth/MicroBitUARTService.h Show annotated file Show diff for this revision Revisions of this file
inc/core/MicroBitConfig.h Show annotated file Show diff for this revision Revisions of this file
inc/drivers/MicroBitPin.h Show annotated file Show diff for this revision Revisions of this file
inc/drivers/MicroBitSerial.h Show annotated file Show diff for this revision Revisions of this file
inc/platform/yotta_cfg_mappings.h Show annotated file Show diff for this revision Revisions of this file
module.json Show annotated file Show diff for this revision Revisions of this file
source/bluetooth/MicroBitBLEManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/bluetooth/MicroBitUARTService.cpp Show annotated file Show diff for this revision Revisions of this file
source/core/MicroBitDevice.cpp Show annotated file Show diff for this revision Revisions of this file
source/drivers/MicroBitPin.cpp Show annotated file Show diff for this revision Revisions of this file
source/drivers/MicroBitRadio.cpp Show annotated file Show diff for this revision Revisions of this file
source/drivers/MicroBitSerial.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/inc/bluetooth/MicroBitUARTService.h	Wed Jul 13 12:18:45 2016 +0100
+++ b/inc/bluetooth/MicroBitUARTService.h	Wed Jul 13 12:18:46 2016 +0100
@@ -55,7 +55,7 @@
 
     uint8_t txBufferSize;
 
-    uint32_t txCharacteristicHandle;
+    uint32_t rxCharacteristicHandle;
 
     // Bluetooth stack we're running on.
     BLEDevice           &ble;
@@ -115,36 +115,69 @@
     int getc(MicroBitSerialMode mode = SYNC_SLEEP);
 
     /**
-      * places a single character into our transmission buffer,
+      * Places a single character into our transmission buffer,
       *
       * @param c the character to transmit
       *
-      * @return the number of characters written (0, or 1).
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+      *                    and return control to the user.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+      *                         given characters have been received by the connected
+      *                         device.
+      *
+      * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+      *         no connected device, or the connected device has not enabled indications.
       */
-    int putc(char c);
+    int putc(char c, MicroBitSerialMode mode = SYNC_SLEEP);
 
     /**
       * Copies characters into the buffer used for Transmitting to the central device.
       *
       * @param buf a buffer containing length number of bytes.
       * @param length the size of the buffer.
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
       *
-      * @return the number of characters copied into the buffer
+      *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+      *                    and return control to the user.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
       *
-      * @note no modes for sending are available at the moment, due to interrupt overhead.
+      *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+      *                         given characters have been received by the connected
+      *                         device.
+      *
+      * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+      *         no connected device, or the connected device has not enabled indications.
       */
-    int send(const uint8_t *buf, int length);
+    int send(const uint8_t *buf, int length, MicroBitSerialMode mode = SYNC_SLEEP);
 
     /**
       * Copies characters into the buffer used for Transmitting to the central device.
       *
       * @param s the string to transmit
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
       *
-      * @return the number of characters copied into the buffer
+      *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+      *                    and return control to the user.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
       *
-      * @note no modes for sending are available at the moment, due to interrupt overhead.
+      *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+      *                         given characters have been received by the connected
+      *                         device.
+      *
+      * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+      *         no connected device, or the connected device has not enabled indications.
       */
-    int send(ManagedString s);
+    int send(ManagedString s, MicroBitSerialMode mode = SYNC_SLEEP);
 
     /**
       * Reads a number of characters from the rxBuffer and fills user given buffer.
--- a/inc/core/MicroBitConfig.h	Wed Jul 13 12:18:45 2016 +0100
+++ b/inc/core/MicroBitConfig.h	Wed Jul 13 12:18:46 2016 +0100
@@ -320,6 +320,19 @@
 
 
 //
+// I/O Options
+//
+
+
+//
+// Define the default mode in which the digital input pins are configured.
+// valid options are PullDown, PullUp and PullNone.
+//
+#ifndef MICROBIT_DEFAULT_PULLMODE
+#define MICROBIT_DEFAULT_PULLMODE                PullDown
+#endif
+
+//
 // Panic options
 //
 
--- a/inc/drivers/MicroBitPin.h	Wed Jul 13 12:18:45 2016 +0100
+++ b/inc/drivers/MicroBitPin.h	Wed Jul 13 12:18:46 2016 +0100
@@ -95,8 +95,8 @@
 {
     // The mbed object looking after this pin at any point in time (untyped due to dynamic behaviour).
     void *pin;
-
     PinCapability capability;
+    uint8_t pullMode;
 
     /**
       * Disconnect any attached mBed IO from this pin.
@@ -200,6 +200,21 @@
     int getDigitalValue();
 
     /**
+      * Configures this IO pin as a digital input with the specified internal pull-up/pull-down configuraiton (if necessary) and tests its current value.
+      *
+      * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
+      *
+      * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
+      *         if the given pin does not have digital capability.
+      *
+      * @code
+      * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+      * P0.getDigitalValue(PullUp); // P0 is either 0 or 1;
+      * @endcode
+      */
+    int getDigitalValue(PinMode pull);
+
+    /**
       * Configures this IO pin as an analog/pwm output, and change the output value to the given level.
       *
       * @param value the level to set on the output pin, in the range 0 - 1024
--- a/inc/drivers/MicroBitSerial.h	Wed Jul 13 12:18:45 2016 +0100
+++ b/inc/drivers/MicroBitSerial.h	Wed Jul 13 12:18:46 2016 +0100
@@ -436,6 +436,8 @@
     /**
       * Configures an event to be fired after "len" characters.
       *
+      * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_HEAD_MATCH.
+      *
       * @param len the number of characters to wait before triggering the event.
       *
       * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
@@ -455,7 +457,9 @@
     /**
       * Configures an event to be fired on a match with one of the delimeters.
       *
-      * @param delimeters the characters to match received characters against e.g. ManagedString("\r\n")
+      * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_DELIM_MATCH.
+      *
+      * @param delimeters the characters to match received characters against e.g. ManagedString("\n")
       *
       * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
       *        gives a different behaviour:
--- a/inc/platform/yotta_cfg_mappings.h	Wed Jul 13 12:18:45 2016 +0100
+++ b/inc/platform/yotta_cfg_mappings.h	Wed Jul 13 12:18:46 2016 +0100
@@ -63,6 +63,10 @@
     #define MICROBIT_DEFAULT_PRINT_SPEED YOTTA_CFG_MICROBIT_DAL_DISPLAY_PRINT_SPEED
 #endif
 
+#ifdef YOTTA_CFG_MICROBIT_DAL_DEFAULT_PULLMODE
+    #define MICROBIT_DEFAULT_PULLMODE YOTTA_CFG_MICROBIT_DAL_DEFAULT_PULLMODE
+#endif
+
 #ifdef YOTTA_CFG_MICROBIT_DAL_PANIC_ON_HEAP_FULL
     #define MICROBIT_PANIC_HEAP_FULL YOTTA_CFG_MICROBIT_DAL_PANIC_ON_HEAP_FULL
 #endif
--- a/module.json	Wed Jul 13 12:18:45 2016 +0100
+++ b/module.json	Wed Jul 13 12:18:46 2016 +0100
@@ -14,7 +14,7 @@
   "author": "Joe Finney <j.finney@lancaster.ac.uk (mailto:j.finney@lancaster.ac.uk) >",
   "homepage": "https://github.com/lancaster-university/microbit-dal/",
   "dependencies": {
-    "mbed-classic": "lancaster-university/mbed-classic#microbit_hfclk+mb4",
+    "mbed-classic": "lancaster-university/mbed-classic#microbit_hfclk+mb5",
     "ble": "lancaster-university/BLE_API#v2.5.0+mb3",
     "ble-nrf51822": "lancaster-university/nrf51822#v2.5.0+mb6",
     "nrf51-sdk": "lancaster-university/nrf51-sdk#v2.2.0+mb4"
--- a/source/bluetooth/MicroBitBLEManager.cpp	Wed Jul 13 12:18:45 2016 +0100
+++ b/source/bluetooth/MicroBitBLEManager.cpp	Wed Jul 13 12:18:46 2016 +0100
@@ -336,6 +336,8 @@
 
 #if CONFIG_ENABLED(MICROBIT_BLE_DEVICE_INFORMATION_SERVICE)
     DeviceInformationService ble_device_information_service (*ble, MICROBIT_BLE_MANUFACTURER, MICROBIT_BLE_MODEL, serialNumber.toCharArray(), MICROBIT_BLE_HARDWARE_VERSION, MICROBIT_BLE_FIRMWARE_VERSION, MICROBIT_BLE_SOFTWARE_VERSION);
+#else
+    (void)serialNumber;
 #endif
 
 #if CONFIG_ENABLED(MICROBIT_BLE_EVENT_SERVICE)
--- a/source/bluetooth/MicroBitUARTService.cpp	Wed Jul 13 12:18:45 2016 +0100
+++ b/source/bluetooth/MicroBitUARTService.cpp	Wed Jul 13 12:18:46 2016 +0100
@@ -40,17 +40,14 @@
 static uint8_t txBufferHead = 0;
 static uint8_t txBufferTail = 0;
 
-static GattCharacteristic* rxCharacteristic = NULL;
+static GattCharacteristic* txCharacteristic = NULL;
 
 /**
-  * A callback function for whenever a Bluetooth device consumes our RX Buffer
+  * A callback function for whenever a Bluetooth device consumes our TX Buffer
   */
-void on_confirmation_received_callback(uint16_t handle)
+void on_confirmation(uint16_t handle)
 {
-#if CONFIG_ENABLED(MICROBIT_DBG)
-    SERIAL_DEBUG->printf("RECEIVED!! %d \r\n",handle);
-#endif
-    if(handle == rxCharacteristic->getValueAttribute().getHandle())
+    if(handle == txCharacteristic->getValueAttribute().getHandle())
     {
         txBufferTail = txBufferHead;
         MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY);
@@ -81,27 +78,27 @@
     txBufferTail = 0;
     this->txBufferSize = txBufferSize;
 
-    GattCharacteristic txCharacteristic(UARTServiceTXCharacteristicUUID, rxBuffer, 1, rxBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
+    GattCharacteristic rxCharacteristic(UARTServiceRXCharacteristicUUID, rxBuffer, 1, rxBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
 
-    rxCharacteristic = new GattCharacteristic(UARTServiceRXCharacteristicUUID, txBuffer, 1, txBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
+    txCharacteristic = new GattCharacteristic(UARTServiceTXCharacteristicUUID, txBuffer, 1, txBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
 
-    GattCharacteristic *charTable[] = {&txCharacteristic, rxCharacteristic};
+    GattCharacteristic *charTable[] = {txCharacteristic, &rxCharacteristic};
 
     GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
 
     _ble.addService(uartService);
 
-    this->txCharacteristicHandle = txCharacteristic.getValueAttribute().getHandle();
+    this->rxCharacteristicHandle = rxCharacteristic.getValueAttribute().getHandle();
 
     _ble.gattServer().onDataWritten(this, &MicroBitUARTService::onDataWritten);
-    _ble.gattServer().onConfirmationReceived(on_confirmation_received_callback);
+    _ble.gattServer().onConfirmationReceived(on_confirmation);
 }
 
 /**
-  * A callback function for whenever a Bluetooth device writes to our TX characteristic.
+  * A callback function for whenever a Bluetooth device writes to our RX characteristic.
   */
 void MicroBitUARTService::onDataWritten(const GattWriteCallbackParams *params) {
-    if (params->handle == this->txCharacteristicHandle)
+    if (params->handle == this->rxCharacteristicHandle)
     {
         uint16_t bytesWritten = params->len;
 
@@ -210,11 +207,24 @@
   *
   * @param c the character to transmit
   *
-  * @return the number of characters written (0, or 1).
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+  *                    and return control to the user.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+  *                         given characters have been received by the connected
+  *                         device.
+  *
+  * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+  *         no connected device, or the connected device has not enabled indications.
   */
-int MicroBitUARTService::putc(char c)
+int MicroBitUARTService::putc(char c, MicroBitSerialMode mode)
 {
-    return (send((uint8_t *)&c, 1) == 1) ? 1 : EOF;
+    return (send((uint8_t *)&c, 1, mode) == 1) ? 1 : EOF;
 }
 
 /**
@@ -222,21 +232,38 @@
   *
   * @param buf a buffer containing length number of bytes.
   * @param length the size of the buffer.
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
   *
-  * @return the number of characters copied into the buffer
+  *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+  *                    and return control to the user.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
   *
-  * @note no modes for sending are available at the moment, due to interrupt overhead.
+  *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+  *                         given characters have been received by the connected
+  *                         device.
+  *
+  * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+  *         no connected device, or the connected device has not enabled indications.
   */
-int MicroBitUARTService::send(const uint8_t *buf, int length)
+int MicroBitUARTService::send(const uint8_t *buf, int length, MicroBitSerialMode mode)
 {
-    if(length < 1)
+    if(length < 1 || mode == SYNC_SPINWAIT)
         return MICROBIT_INVALID_PARAMETER;
 
+    bool updatesEnabled = false;
+
+    ble.gattServer().areUpdatesEnabled(*txCharacteristic, &updatesEnabled);
+
+    if(!ble.getGapState().connected && !updatesEnabled)
+        return MICROBIT_NOT_SUPPORTED;
+
     int bytesWritten = 0;
 
-    if (ble.getGapState().connected) {
-
-        for(int bufferIterator = 0; bufferIterator < length; bufferIterator++)
+    while(bytesWritten < length && ble.getGapState().connected && updatesEnabled)
+    {
+        for(int bufferIterator = bytesWritten; bufferIterator < length; bufferIterator++)
         {
             int nextHead = (txBufferHead + 1) % txBufferSize;
 
@@ -252,27 +279,25 @@
 
         int size = txBufferedSize();
 
-#if CONFIG_ENABLED(MICROBIT_DBG)
-        SERIAL_DEBUG->printf("tx size: %d", size);
-#endif
-
         uint8_t temp[size];
 
         memclr(&temp, size);
 
         circularCopy(txBuffer, txBufferSize, temp, txBufferTail, txBufferHead);
 
-#if CONFIG_ENABLED(MICROBIT_DBG)
-        for(int i = 0; i < size; i++)
-            SERIAL_DEBUG->printf("%c",temp[i]);
-#endif
+
+        if(mode == SYNC_SLEEP)
+            fiber_wake_on_event(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY);
+
+        ble.gattServer().write(txCharacteristic->getValueAttribute().getHandle(), temp, size);
 
-        ble.gattServer().write(rxCharacteristic->getValueAttribute().getHandle(), temp, size);
-    }
+        if(mode == SYNC_SLEEP)
+            schedule();
+        else
+            break;
 
-#if CONFIG_ENABLED(MICROBIT_DBG)
-    SERIAL_DEBUG->printf("written: %d \r\n",bytesWritten);
-#endif
+        ble.gattServer().areUpdatesEnabled(*txCharacteristic, &updatesEnabled);
+    }
 
     return bytesWritten;
 }
@@ -281,14 +306,24 @@
   * Copies characters into the buffer used for Transmitting to the central device.
   *
   * @param s the string to transmit
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
   *
-  * @return the number of characters copied into the buffer
+  *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+  *                    and return control to the user.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
   *
-  * @note no modes for sending are available at the moment, due to interrupt overhead.
+  *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+  *                         given characters have been received by the connected
+  *                         device.
+  *
+  * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+  *         no connected device, or the connected device has not enabled indications.
   */
-int MicroBitUARTService::send(ManagedString s)
+int MicroBitUARTService::send(ManagedString s, MicroBitSerialMode mode)
 {
-    return send((uint8_t *)s.toCharArray(), s.length());
+    return send((uint8_t *)s.toCharArray(), s.length(), mode);
 }
 
 /**
--- a/source/core/MicroBitDevice.cpp	Wed Jul 13 12:18:45 2016 +0100
+++ b/source/core/MicroBitDevice.cpp	Wed Jul 13 12:18:46 2016 +0100
@@ -67,8 +67,12 @@
   */
 bool ble_running()
 {
-    uint8_t t;
+    uint8_t t = 0;
+
+#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED) || CONFIG_ENABLED(MICROBIT_BLE_PAIRING_MODE)
     sd_softdevice_is_enabled(&t);
+#endif
+
     return t==1;
 }
 
--- a/source/drivers/MicroBitPin.cpp	Wed Jul 13 12:18:45 2016 +0100
+++ b/source/drivers/MicroBitPin.cpp	Wed Jul 13 12:18:46 2016 +0100
@@ -57,6 +57,7 @@
     this->id = id;
     this->name = name;
     this->capability = capability;
+    this->pullMode = MICROBIT_DEFAULT_PULLMODE;
 
     // Power up in a disconnected, low power state.
     // If we're unused, this is how it will stay...
@@ -159,7 +160,7 @@
     if (!(status & (IO_STATUS_DIGITAL_IN | IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE)))
     {
         disconnect();
-        pin = new DigitalIn(name,PullDown);
+        pin = new DigitalIn(name, (PinMode)pullMode);
         status |= IO_STATUS_DIGITAL_IN;
     }
 
@@ -169,6 +170,25 @@
     return ((DigitalIn *)pin)->read();
 }
 
+/**
+ * Configures this IO pin as a digital input with the specified internal pull-up/pull-down configuraiton (if necessary) and tests its current value.
+ *
+ * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
+ *
+ * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
+ *         if the given pin does not have digital capability.
+ *
+ * @code
+ * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+ * P0.getDigitalValue(PullUp); // P0 is either 0 or 1;
+ * @endcode
+ */
+int MicroBitPin::getDigitalValue(PinMode pull)
+{
+    setPull(pull);
+    return getDigitalValue();
+}
+
 int MicroBitPin::obtainAnalogChannel()
 {
     // Move into an analogue input state if necessary, if we are no longer the focus of a DynamicPWM instance, allocate ourselves again!
@@ -451,6 +471,8 @@
   */
 int MicroBitPin::setPull(PinMode pull)
 {
+    pullMode = pull;
+
     if ((status & IO_STATUS_DIGITAL_IN))
     {
         ((DigitalIn *)pin)->mode(pull);
@@ -528,7 +550,7 @@
         disconnect();
         pin = new TimedInterruptIn(name);
 
-        ((TimedInterruptIn *)pin)->mode(PullDown);
+        ((TimedInterruptIn *)pin)->mode((PinMode)pullMode);
         ((TimedInterruptIn *)pin)->rise(this, &MicroBitPin::onRise);
         ((TimedInterruptIn *)pin)->fall(this, &MicroBitPin::onFall);
     }
--- a/source/drivers/MicroBitRadio.cpp	Wed Jul 13 12:18:45 2016 +0100
+++ b/source/drivers/MicroBitRadio.cpp	Wed Jul 13 12:18:46 2016 +0100
@@ -59,10 +59,6 @@
 
 extern "C" void RADIO_IRQHandler(void)
 {
-    // Move on to the next buffer, if possible.
-    MicroBitRadio::instance->queueRxBuf();
-    NRF_RADIO->PACKETPTR = (uint32_t) MicroBitRadio::instance->getRxBuf();
-
     if(NRF_RADIO->EVENTS_READY)
     {
         NRF_RADIO->EVENTS_READY = 0;
@@ -74,12 +70,24 @@
     if(NRF_RADIO->EVENTS_END)
     {
         NRF_RADIO->EVENTS_END = 0;
-
         if(NRF_RADIO->CRCSTATUS == 1)
         {
             uint8_t sample = NRF_RADIO->RSSISAMPLE;
 
+            // Associate this packet's rssi value with the data just 
+            // transferred by DMA receive
             MicroBitRadio::instance->setRSSI(sample);
+
+            // Now move on to the next buffer, if possible.
+            // The queued packet will get the rssi value set above.
+            MicroBitRadio::instance->queueRxBuf();
+
+            // Set the new buffer for DMA
+            NRF_RADIO->PACKETPTR = (uint32_t) MicroBitRadio::instance->getRxBuf();
+        }
+        else
+        {
+            MicroBitRadio::instance->setRSSI(0);
         }
 
         // Start listening and wait for the END event
--- a/source/drivers/MicroBitSerial.cpp	Wed Jul 13 12:18:45 2016 +0100
+++ b/source/drivers/MicroBitSerial.cpp	Wed Jul 13 12:18:46 2016 +0100
@@ -57,8 +57,9 @@
   */
 MicroBitSerial::MicroBitSerial(PinName tx, PinName rx, uint8_t rxBufferSize, uint8_t txBufferSize) : RawSerial(tx,rx), delimeters()
 {
-    this->rxBuffSize = rxBufferSize;
-    this->txBuffSize = txBufferSize;
+    // + 1 so there is a usable buffer size, of the size the user requested.
+    this->rxBuffSize = rxBufferSize + 1;
+    this->txBuffSize = txBufferSize + 1;
 
     this->rxBuff = NULL;
     this->txBuff = NULL;
@@ -545,7 +546,7 @@
             return result;
     }
 
-    char c = (char)getChar(mode);
+    int c = getChar(mode);
 
     unlockRx();
 
@@ -834,7 +835,6 @@
 
     detach(Serial::RxIrq);
 
-    serial_free(&_serial);
     serial_init(&_serial, tx, rx);
 
     attach(this, &MicroBitSerial::dataReceived, Serial::RxIrq);
@@ -853,6 +853,8 @@
 /**
   * Configures an event to be fired after "len" characters.
   *
+  * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_HEAD_MATCH.
+  *
   * @param len the number of characters to wait before triggering the event.
   *
   * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
@@ -885,7 +887,9 @@
 /**
   * Configures an event to be fired on a match with one of the delimeters.
   *
-  * @param delimeters the characters to match received characters against e.g. ManagedString("\r\n")
+  * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_DELIM_MATCH.
+  *
+  * @param delimeters the characters to match received characters against e.g. ManagedString("\n")
   *
   * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
   *        gives a different behaviour:
@@ -957,7 +961,8 @@
 
     lockRx();
 
-    this->rxBuffSize = size;
+    // + 1 so there is a usable buffer size, of the size the user requested.
+    this->rxBuffSize = size + 1;
 
     int result = initialiseRx();
 
@@ -981,7 +986,8 @@
 
     lockTx();
 
-    this->txBuffSize = size;
+    // + 1 so there is a usable buffer size, of the size the user requested.
+    this->txBuffSize = size + 1;
 
     int result = initialiseTx();