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:38 2016 +0100
Parent:
57:290a35cb9981
Child:
59:d73a257e9f89
Commit message:
Synchronized with git rev bf58aac7

Changed in this revision

inc/bluetooth/MicroBitUARTService.h 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
--- a/inc/bluetooth/MicroBitUARTService.h	Wed Jul 13 12:18:37 2016 +0100
+++ b/inc/bluetooth/MicroBitUARTService.h	Wed Jul 13 12:18:38 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.
@@ -274,4 +307,4 @@
 extern const uint8_t  UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
 extern const uint8_t  UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
 
-#endif
+#endif
\ No newline at end of file
--- a/source/bluetooth/MicroBitUARTService.cpp	Wed Jul 13 12:18:37 2016 +0100
+++ b/source/bluetooth/MicroBitUARTService.cpp	Wed Jul 13 12:18:38 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);
 }
 
 /**