Solution for Bluetooth SIG hands-on training course

Dependencies:   BLE_API mbed-dev-bin nRF51822-bluetooth-mdw

Dependents:   microbit

Fork of microbit-dal-bluetooth-mdw_starter by Martin Woolley

Committer:
LancasterUniversity
Date:
Wed Jul 13 12:18:45 2016 +0100
Revision:
65:f7ebabf23e15
Parent:
58:2ac8d45f1b08
Child:
66:2fc7d7c2fffc
Synchronized with git rev 00674e34
Author: Joe Finney
microbit: Tuning and furhter debounce of SHAKE gesture

- Added timeout code to prevent over-generation of SHAKE events.
- Tuning of SHAKE detection parameters to align sensitivity with existing
microbit.co.uk algorithm

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Class definition for the custom MicroBit UART Service.
Jonathan Austin 1:8aa5cdb4ab67 28 * Provides a BLE service that acts as a UART port, enabling the reception and transmission
Jonathan Austin 1:8aa5cdb4ab67 29 * of an arbitrary number of bytes.
Jonathan Austin 1:8aa5cdb4ab67 30 */
Jonathan Austin 1:8aa5cdb4ab67 31
Jonathan Austin 1:8aa5cdb4ab67 32 #include "ble/UUID.h"
Jonathan Austin 1:8aa5cdb4ab67 33
Jonathan Austin 1:8aa5cdb4ab67 34 #include "ExternalEvents.h"
Jonathan Austin 1:8aa5cdb4ab67 35 #include "MicroBitUARTService.h"
Jonathan Austin 1:8aa5cdb4ab67 36 #include "MicroBitFiber.h"
Jonathan Austin 1:8aa5cdb4ab67 37 #include "ErrorNo.h"
Jonathan Austin 1:8aa5cdb4ab67 38 #include "NotifyEvents.h"
Jonathan Austin 1:8aa5cdb4ab67 39
Jonathan Austin 1:8aa5cdb4ab67 40 static uint8_t txBufferHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 41 static uint8_t txBufferTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 42
LancasterUniversity 65:f7ebabf23e15 43 static GattCharacteristic* rxCharacteristic = NULL;
Jonathan Austin 1:8aa5cdb4ab67 44
Jonathan Austin 1:8aa5cdb4ab67 45 /**
LancasterUniversity 65:f7ebabf23e15 46 * A callback function for whenever a Bluetooth device consumes our RX Buffer
Jonathan Austin 1:8aa5cdb4ab67 47 */
LancasterUniversity 65:f7ebabf23e15 48 void on_confirmation_received_callback(uint16_t handle)
Jonathan Austin 1:8aa5cdb4ab67 49 {
LancasterUniversity 65:f7ebabf23e15 50 #if CONFIG_ENABLED(MICROBIT_DBG)
LancasterUniversity 65:f7ebabf23e15 51 SERIAL_DEBUG->printf("RECEIVED!! %d \r\n",handle);
LancasterUniversity 65:f7ebabf23e15 52 #endif
LancasterUniversity 65:f7ebabf23e15 53 if(handle == rxCharacteristic->getValueAttribute().getHandle())
Jonathan Austin 1:8aa5cdb4ab67 54 {
Jonathan Austin 1:8aa5cdb4ab67 55 txBufferTail = txBufferHead;
Jonathan Austin 1:8aa5cdb4ab67 56 MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY);
Jonathan Austin 1:8aa5cdb4ab67 57 }
Jonathan Austin 1:8aa5cdb4ab67 58 }
Jonathan Austin 1:8aa5cdb4ab67 59
Jonathan Austin 1:8aa5cdb4ab67 60 /**
Jonathan Austin 1:8aa5cdb4ab67 61 * Constructor for the UARTService.
Jonathan Austin 1:8aa5cdb4ab67 62 * @param _ble an instance of BLEDevice
Jonathan Austin 1:8aa5cdb4ab67 63 * @param rxBufferSize the size of the rxBuffer
Jonathan Austin 1:8aa5cdb4ab67 64 * @param txBufferSize the size of the txBuffer
Jonathan Austin 1:8aa5cdb4ab67 65 *
Jonathan Austin 1:8aa5cdb4ab67 66 * @note defaults to 20
Jonathan Austin 1:8aa5cdb4ab67 67 */
Jonathan Austin 1:8aa5cdb4ab67 68 MicroBitUARTService::MicroBitUARTService(BLEDevice &_ble, uint8_t rxBufferSize, uint8_t txBufferSize) : ble(_ble)
Jonathan Austin 1:8aa5cdb4ab67 69 {
LancasterUniversity 29:62f8b007debf 70 rxBufferSize += 1;
LancasterUniversity 29:62f8b007debf 71 txBufferSize += 1;
Jonathan Austin 1:8aa5cdb4ab67 72
Jonathan Austin 1:8aa5cdb4ab67 73 txBuffer = (uint8_t *)malloc(txBufferSize);
Jonathan Austin 1:8aa5cdb4ab67 74 rxBuffer = (uint8_t *)malloc(rxBufferSize);
Jonathan Austin 1:8aa5cdb4ab67 75
Jonathan Austin 1:8aa5cdb4ab67 76 rxBufferHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 77 rxBufferTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 78 this->rxBufferSize = rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 79
Jonathan Austin 1:8aa5cdb4ab67 80 txBufferHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 81 txBufferTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 82 this->txBufferSize = txBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 83
LancasterUniversity 65:f7ebabf23e15 84 GattCharacteristic txCharacteristic(UARTServiceTXCharacteristicUUID, rxBuffer, 1, rxBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
Jonathan Austin 1:8aa5cdb4ab67 85
LancasterUniversity 65:f7ebabf23e15 86 rxCharacteristic = new GattCharacteristic(UARTServiceRXCharacteristicUUID, txBuffer, 1, txBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
Jonathan Austin 1:8aa5cdb4ab67 87
LancasterUniversity 65:f7ebabf23e15 88 GattCharacteristic *charTable[] = {&txCharacteristic, rxCharacteristic};
Jonathan Austin 1:8aa5cdb4ab67 89
Jonathan Austin 1:8aa5cdb4ab67 90 GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
Jonathan Austin 1:8aa5cdb4ab67 91
Jonathan Austin 1:8aa5cdb4ab67 92 _ble.addService(uartService);
Jonathan Austin 1:8aa5cdb4ab67 93
LancasterUniversity 65:f7ebabf23e15 94 this->txCharacteristicHandle = txCharacteristic.getValueAttribute().getHandle();
Jonathan Austin 1:8aa5cdb4ab67 95
Jonathan Austin 1:8aa5cdb4ab67 96 _ble.gattServer().onDataWritten(this, &MicroBitUARTService::onDataWritten);
LancasterUniversity 65:f7ebabf23e15 97 _ble.gattServer().onConfirmationReceived(on_confirmation_received_callback);
Jonathan Austin 1:8aa5cdb4ab67 98 }
Jonathan Austin 1:8aa5cdb4ab67 99
Jonathan Austin 1:8aa5cdb4ab67 100 /**
LancasterUniversity 65:f7ebabf23e15 101 * A callback function for whenever a Bluetooth device writes to our TX characteristic.
Jonathan Austin 1:8aa5cdb4ab67 102 */
Jonathan Austin 1:8aa5cdb4ab67 103 void MicroBitUARTService::onDataWritten(const GattWriteCallbackParams *params) {
LancasterUniversity 65:f7ebabf23e15 104 if (params->handle == this->txCharacteristicHandle)
Jonathan Austin 1:8aa5cdb4ab67 105 {
Jonathan Austin 1:8aa5cdb4ab67 106 uint16_t bytesWritten = params->len;
Jonathan Austin 1:8aa5cdb4ab67 107
Jonathan Austin 1:8aa5cdb4ab67 108 for(int byteIterator = 0; byteIterator < bytesWritten; byteIterator++)
Jonathan Austin 1:8aa5cdb4ab67 109 {
Jonathan Austin 1:8aa5cdb4ab67 110 int newHead = (rxBufferHead + 1) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 111
Jonathan Austin 1:8aa5cdb4ab67 112 if(newHead != rxBufferTail)
Jonathan Austin 1:8aa5cdb4ab67 113 {
Jonathan Austin 1:8aa5cdb4ab67 114 char c = params->data[byteIterator];
Jonathan Austin 1:8aa5cdb4ab67 115
Jonathan Austin 1:8aa5cdb4ab67 116 int delimeterOffset = 0;
Jonathan Austin 1:8aa5cdb4ab67 117 int delimLength = this->delimeters.length();
Jonathan Austin 1:8aa5cdb4ab67 118
Jonathan Austin 1:8aa5cdb4ab67 119 //iterate through our delimeters (if any) to see if there is a match
Jonathan Austin 1:8aa5cdb4ab67 120 while(delimeterOffset < delimLength)
Jonathan Austin 1:8aa5cdb4ab67 121 {
Jonathan Austin 1:8aa5cdb4ab67 122 //fire an event if there is to block any waiting fibers
Jonathan Austin 1:8aa5cdb4ab67 123 if(this->delimeters.charAt(delimeterOffset) == c)
Jonathan Austin 1:8aa5cdb4ab67 124 MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 125
Jonathan Austin 1:8aa5cdb4ab67 126 delimeterOffset++;
Jonathan Austin 1:8aa5cdb4ab67 127 }
Jonathan Austin 1:8aa5cdb4ab67 128
Jonathan Austin 1:8aa5cdb4ab67 129 rxBuffer[rxBufferHead] = c;
Jonathan Austin 1:8aa5cdb4ab67 130
Jonathan Austin 1:8aa5cdb4ab67 131 rxBufferHead = newHead;
Jonathan Austin 1:8aa5cdb4ab67 132
Jonathan Austin 1:8aa5cdb4ab67 133 if(rxBufferHead == rxBuffHeadMatch)
Jonathan Austin 1:8aa5cdb4ab67 134 {
Jonathan Austin 1:8aa5cdb4ab67 135 rxBuffHeadMatch = -1;
Jonathan Austin 1:8aa5cdb4ab67 136 MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_HEAD_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 137 }
Jonathan Austin 1:8aa5cdb4ab67 138 }
Jonathan Austin 1:8aa5cdb4ab67 139 else
Jonathan Austin 1:8aa5cdb4ab67 140 MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_RX_FULL);
Jonathan Austin 1:8aa5cdb4ab67 141 }
Jonathan Austin 1:8aa5cdb4ab67 142 }
Jonathan Austin 1:8aa5cdb4ab67 143 }
Jonathan Austin 1:8aa5cdb4ab67 144
Jonathan Austin 1:8aa5cdb4ab67 145 /**
Jonathan Austin 1:8aa5cdb4ab67 146 * An internal method that copies values from a circular buffer to a linear buffer.
Jonathan Austin 1:8aa5cdb4ab67 147 *
Jonathan Austin 1:8aa5cdb4ab67 148 * @param circularBuff a pointer to the source circular buffer
Jonathan Austin 1:8aa5cdb4ab67 149 * @param circularBuffSize the size of the circular buffer
Jonathan Austin 1:8aa5cdb4ab67 150 * @param linearBuff a pointer to the destination linear buffer
Jonathan Austin 1:8aa5cdb4ab67 151 * @param tailPosition the tail position in the circular buffer you want to copy from
Jonathan Austin 1:8aa5cdb4ab67 152 * @param headPosition the head position in the circular buffer you want to copy to
Jonathan Austin 1:8aa5cdb4ab67 153 *
Jonathan Austin 1:8aa5cdb4ab67 154 * @note this method assumes that the linear buffer has the appropriate amount of
Jonathan Austin 1:8aa5cdb4ab67 155 * memory to contain the copy operation
Jonathan Austin 1:8aa5cdb4ab67 156 */
Jonathan Austin 1:8aa5cdb4ab67 157 void MicroBitUARTService::circularCopy(uint8_t *circularBuff, uint8_t circularBuffSize, uint8_t *linearBuff, uint16_t tailPosition, uint16_t headPosition)
Jonathan Austin 1:8aa5cdb4ab67 158 {
Jonathan Austin 1:8aa5cdb4ab67 159 int toBuffIndex = 0;
Jonathan Austin 1:8aa5cdb4ab67 160
Jonathan Austin 1:8aa5cdb4ab67 161 while(tailPosition != headPosition)
Jonathan Austin 1:8aa5cdb4ab67 162 {
Jonathan Austin 1:8aa5cdb4ab67 163 linearBuff[toBuffIndex++] = circularBuff[tailPosition];
Jonathan Austin 1:8aa5cdb4ab67 164
Jonathan Austin 1:8aa5cdb4ab67 165 tailPosition = (tailPosition + 1) % circularBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 166 }
Jonathan Austin 1:8aa5cdb4ab67 167 }
Jonathan Austin 1:8aa5cdb4ab67 168
Jonathan Austin 1:8aa5cdb4ab67 169 /**
Jonathan Austin 1:8aa5cdb4ab67 170 * Retreives a single character from our RxBuffer.
Jonathan Austin 1:8aa5cdb4ab67 171 *
Jonathan Austin 1:8aa5cdb4ab67 172 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 173 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 174 *
Jonathan Austin 1:8aa5cdb4ab67 175 * ASYNC - Will attempt to read a single character, and return immediately
Jonathan Austin 1:8aa5cdb4ab67 176 *
Jonathan Austin 1:8aa5cdb4ab67 177 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 178 *
Jonathan Austin 1:8aa5cdb4ab67 179 * SYNC_SLEEP - Will configure the event and block the current fiber until the
Jonathan Austin 1:8aa5cdb4ab67 180 * event is received.
Jonathan Austin 1:8aa5cdb4ab67 181 *
Jonathan Austin 1:8aa5cdb4ab67 182 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, a character or MICROBIT_NO_DATA
Jonathan Austin 1:8aa5cdb4ab67 183 */
Jonathan Austin 1:8aa5cdb4ab67 184 int MicroBitUARTService::getc(MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 185 {
Jonathan Austin 1:8aa5cdb4ab67 186 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 187 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 188
Jonathan Austin 1:8aa5cdb4ab67 189 if(mode == ASYNC)
Jonathan Austin 1:8aa5cdb4ab67 190 {
Jonathan Austin 1:8aa5cdb4ab67 191 if(!isReadable())
Jonathan Austin 1:8aa5cdb4ab67 192 return MICROBIT_NO_DATA;
Jonathan Austin 1:8aa5cdb4ab67 193 }
Jonathan Austin 1:8aa5cdb4ab67 194
Jonathan Austin 1:8aa5cdb4ab67 195 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 196 {
Jonathan Austin 1:8aa5cdb4ab67 197 if(!isReadable())
Jonathan Austin 1:8aa5cdb4ab67 198 eventAfter(1, mode);
Jonathan Austin 1:8aa5cdb4ab67 199 }
Jonathan Austin 1:8aa5cdb4ab67 200
Jonathan Austin 1:8aa5cdb4ab67 201 char c = rxBuffer[rxBufferTail];
Jonathan Austin 1:8aa5cdb4ab67 202
Jonathan Austin 1:8aa5cdb4ab67 203 rxBufferTail = (rxBufferTail + 1) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 204
Jonathan Austin 1:8aa5cdb4ab67 205 return c;
Jonathan Austin 1:8aa5cdb4ab67 206 }
Jonathan Austin 1:8aa5cdb4ab67 207
Jonathan Austin 1:8aa5cdb4ab67 208 /**
Jonathan Austin 1:8aa5cdb4ab67 209 * places a single character into our transmission buffer,
Jonathan Austin 1:8aa5cdb4ab67 210 *
Jonathan Austin 1:8aa5cdb4ab67 211 * @param c the character to transmit
Jonathan Austin 1:8aa5cdb4ab67 212 *
LancasterUniversity 65:f7ebabf23e15 213 * @return the number of characters written (0, or 1).
Jonathan Austin 1:8aa5cdb4ab67 214 */
LancasterUniversity 65:f7ebabf23e15 215 int MicroBitUARTService::putc(char c)
Jonathan Austin 1:8aa5cdb4ab67 216 {
LancasterUniversity 65:f7ebabf23e15 217 return (send((uint8_t *)&c, 1) == 1) ? 1 : EOF;
Jonathan Austin 1:8aa5cdb4ab67 218 }
Jonathan Austin 1:8aa5cdb4ab67 219
Jonathan Austin 1:8aa5cdb4ab67 220 /**
Jonathan Austin 1:8aa5cdb4ab67 221 * Copies characters into the buffer used for Transmitting to the central device.
Jonathan Austin 1:8aa5cdb4ab67 222 *
Jonathan Austin 1:8aa5cdb4ab67 223 * @param buf a buffer containing length number of bytes.
Jonathan Austin 1:8aa5cdb4ab67 224 * @param length the size of the buffer.
Jonathan Austin 1:8aa5cdb4ab67 225 *
LancasterUniversity 65:f7ebabf23e15 226 * @return the number of characters copied into the buffer
LancasterUniversity 58:2ac8d45f1b08 227 *
LancasterUniversity 65:f7ebabf23e15 228 * @note no modes for sending are available at the moment, due to interrupt overhead.
Jonathan Austin 1:8aa5cdb4ab67 229 */
LancasterUniversity 65:f7ebabf23e15 230 int MicroBitUARTService::send(const uint8_t *buf, int length)
Jonathan Austin 1:8aa5cdb4ab67 231 {
LancasterUniversity 65:f7ebabf23e15 232 if(length < 1)
Jonathan Austin 1:8aa5cdb4ab67 233 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 234
Jonathan Austin 1:8aa5cdb4ab67 235 int bytesWritten = 0;
Jonathan Austin 1:8aa5cdb4ab67 236
LancasterUniversity 65:f7ebabf23e15 237 if (ble.getGapState().connected) {
LancasterUniversity 65:f7ebabf23e15 238
LancasterUniversity 65:f7ebabf23e15 239 for(int bufferIterator = 0; bufferIterator < length; bufferIterator++)
Jonathan Austin 1:8aa5cdb4ab67 240 {
Jonathan Austin 1:8aa5cdb4ab67 241 int nextHead = (txBufferHead + 1) % txBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 242
Jonathan Austin 1:8aa5cdb4ab67 243 if(nextHead != txBufferTail)
Jonathan Austin 1:8aa5cdb4ab67 244 {
Jonathan Austin 1:8aa5cdb4ab67 245 txBuffer[txBufferHead] = buf[bufferIterator];
Jonathan Austin 1:8aa5cdb4ab67 246
Jonathan Austin 1:8aa5cdb4ab67 247 txBufferHead = nextHead;
Jonathan Austin 1:8aa5cdb4ab67 248
Jonathan Austin 1:8aa5cdb4ab67 249 bytesWritten++;
Jonathan Austin 1:8aa5cdb4ab67 250 }
Jonathan Austin 1:8aa5cdb4ab67 251 }
Jonathan Austin 1:8aa5cdb4ab67 252
Jonathan Austin 1:8aa5cdb4ab67 253 int size = txBufferedSize();
Jonathan Austin 1:8aa5cdb4ab67 254
LancasterUniversity 65:f7ebabf23e15 255 #if CONFIG_ENABLED(MICROBIT_DBG)
LancasterUniversity 65:f7ebabf23e15 256 SERIAL_DEBUG->printf("tx size: %d", size);
LancasterUniversity 65:f7ebabf23e15 257 #endif
LancasterUniversity 65:f7ebabf23e15 258
LancasterUniversity 3:d86a4ddc1867 259 uint8_t temp[size];
Jonathan Austin 1:8aa5cdb4ab67 260
LancasterUniversity 8:ec4465853952 261 memclr(&temp, size);
LancasterUniversity 8:ec4465853952 262
Jonathan Austin 1:8aa5cdb4ab67 263 circularCopy(txBuffer, txBufferSize, temp, txBufferTail, txBufferHead);
Jonathan Austin 1:8aa5cdb4ab67 264
LancasterUniversity 65:f7ebabf23e15 265 #if CONFIG_ENABLED(MICROBIT_DBG)
LancasterUniversity 65:f7ebabf23e15 266 for(int i = 0; i < size; i++)
LancasterUniversity 65:f7ebabf23e15 267 SERIAL_DEBUG->printf("%c",temp[i]);
LancasterUniversity 65:f7ebabf23e15 268 #endif
Jonathan Austin 1:8aa5cdb4ab67 269
LancasterUniversity 65:f7ebabf23e15 270 ble.gattServer().write(rxCharacteristic->getValueAttribute().getHandle(), temp, size);
LancasterUniversity 65:f7ebabf23e15 271 }
Jonathan Austin 1:8aa5cdb4ab67 272
LancasterUniversity 65:f7ebabf23e15 273 #if CONFIG_ENABLED(MICROBIT_DBG)
LancasterUniversity 65:f7ebabf23e15 274 SERIAL_DEBUG->printf("written: %d \r\n",bytesWritten);
LancasterUniversity 65:f7ebabf23e15 275 #endif
Jonathan Austin 1:8aa5cdb4ab67 276
Jonathan Austin 1:8aa5cdb4ab67 277 return bytesWritten;
Jonathan Austin 1:8aa5cdb4ab67 278 }
Jonathan Austin 1:8aa5cdb4ab67 279
Jonathan Austin 1:8aa5cdb4ab67 280 /**
Jonathan Austin 1:8aa5cdb4ab67 281 * Copies characters into the buffer used for Transmitting to the central device.
Jonathan Austin 1:8aa5cdb4ab67 282 *
Jonathan Austin 1:8aa5cdb4ab67 283 * @param s the string to transmit
Jonathan Austin 1:8aa5cdb4ab67 284 *
LancasterUniversity 65:f7ebabf23e15 285 * @return the number of characters copied into the buffer
Jonathan Austin 1:8aa5cdb4ab67 286 *
LancasterUniversity 65:f7ebabf23e15 287 * @note no modes for sending are available at the moment, due to interrupt overhead.
Jonathan Austin 1:8aa5cdb4ab67 288 */
LancasterUniversity 65:f7ebabf23e15 289 int MicroBitUARTService::send(ManagedString s)
Jonathan Austin 1:8aa5cdb4ab67 290 {
LancasterUniversity 65:f7ebabf23e15 291 return send((uint8_t *)s.toCharArray(), s.length());
Jonathan Austin 1:8aa5cdb4ab67 292 }
Jonathan Austin 1:8aa5cdb4ab67 293
Jonathan Austin 1:8aa5cdb4ab67 294 /**
Jonathan Austin 1:8aa5cdb4ab67 295 * Reads a number of characters from the rxBuffer and fills user given buffer.
Jonathan Austin 1:8aa5cdb4ab67 296 *
Jonathan Austin 1:8aa5cdb4ab67 297 * @param buf a pointer to a buffer of len bytes.
Jonathan Austin 1:8aa5cdb4ab67 298 * @param len the size of the user allocated buffer
Jonathan Austin 1:8aa5cdb4ab67 299 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 300 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 301 *
Jonathan Austin 1:8aa5cdb4ab67 302 * ASYNC - Will attempt to read all available characters, and return immediately
Jonathan Austin 1:8aa5cdb4ab67 303 * until the buffer limit is reached
Jonathan Austin 1:8aa5cdb4ab67 304 *
Jonathan Austin 1:8aa5cdb4ab67 305 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 306 *
Jonathan Austin 1:8aa5cdb4ab67 307 * SYNC_SLEEP - Will first of all determine whether the given number of characters
Jonathan Austin 1:8aa5cdb4ab67 308 * are available in our buffer, if not, it will set an event and sleep
Jonathan Austin 1:8aa5cdb4ab67 309 * until the number of characters are avaialable.
Jonathan Austin 1:8aa5cdb4ab67 310 *
Jonathan Austin 1:8aa5cdb4ab67 311 * @return the number of characters digested
Jonathan Austin 1:8aa5cdb4ab67 312 */
Jonathan Austin 1:8aa5cdb4ab67 313 int MicroBitUARTService::read(uint8_t *buf, int len, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 314 {
Jonathan Austin 1:8aa5cdb4ab67 315 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 316 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 317
Jonathan Austin 1:8aa5cdb4ab67 318 int i = 0;
Jonathan Austin 1:8aa5cdb4ab67 319
Jonathan Austin 1:8aa5cdb4ab67 320 if(mode == ASYNC)
Jonathan Austin 1:8aa5cdb4ab67 321 {
Jonathan Austin 1:8aa5cdb4ab67 322 int c;
Jonathan Austin 1:8aa5cdb4ab67 323
Jonathan Austin 1:8aa5cdb4ab67 324 while((c = getc(mode)) > 0 && i < len)
Jonathan Austin 1:8aa5cdb4ab67 325 {
Jonathan Austin 1:8aa5cdb4ab67 326 buf[i] = c;
Jonathan Austin 1:8aa5cdb4ab67 327 i++;
Jonathan Austin 1:8aa5cdb4ab67 328 }
Jonathan Austin 1:8aa5cdb4ab67 329 }
Jonathan Austin 1:8aa5cdb4ab67 330
Jonathan Austin 1:8aa5cdb4ab67 331 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 332 {
Jonathan Austin 1:8aa5cdb4ab67 333 if(len > rxBufferedSize())
Jonathan Austin 1:8aa5cdb4ab67 334 eventAfter(len - rxBufferedSize(), mode);
Jonathan Austin 1:8aa5cdb4ab67 335
Jonathan Austin 1:8aa5cdb4ab67 336 while(i < len)
Jonathan Austin 1:8aa5cdb4ab67 337 {
Jonathan Austin 1:8aa5cdb4ab67 338 buf[i] = (char)getc(mode);
Jonathan Austin 1:8aa5cdb4ab67 339 i++;
Jonathan Austin 1:8aa5cdb4ab67 340 }
Jonathan Austin 1:8aa5cdb4ab67 341 }
Jonathan Austin 1:8aa5cdb4ab67 342
Jonathan Austin 1:8aa5cdb4ab67 343 return i;
Jonathan Austin 1:8aa5cdb4ab67 344 }
Jonathan Austin 1:8aa5cdb4ab67 345
Jonathan Austin 1:8aa5cdb4ab67 346 /**
Jonathan Austin 1:8aa5cdb4ab67 347 * Reads a number of characters from the rxBuffer and returns them as a ManagedString
Jonathan Austin 1:8aa5cdb4ab67 348 *
Jonathan Austin 1:8aa5cdb4ab67 349 * @param len the number of characters to read.
Jonathan Austin 1:8aa5cdb4ab67 350 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 351 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 352 *
Jonathan Austin 1:8aa5cdb4ab67 353 * ASYNC - Will attempt to read all available characters, and return immediately
Jonathan Austin 1:8aa5cdb4ab67 354 * until the buffer limit is reached
Jonathan Austin 1:8aa5cdb4ab67 355 *
Jonathan Austin 1:8aa5cdb4ab67 356 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 357 *
Jonathan Austin 1:8aa5cdb4ab67 358 * SYNC_SLEEP - Will first of all determine whether the given number of characters
Jonathan Austin 1:8aa5cdb4ab67 359 * are available in our buffer, if not, it will set an event and sleep
Jonathan Austin 1:8aa5cdb4ab67 360 * until the number of characters are avaialable.
Jonathan Austin 1:8aa5cdb4ab67 361 *
Jonathan Austin 1:8aa5cdb4ab67 362 * @return an empty ManagedString on error, or a ManagedString containing characters
Jonathan Austin 1:8aa5cdb4ab67 363 */
Jonathan Austin 1:8aa5cdb4ab67 364 ManagedString MicroBitUARTService::read(int len, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 365 {
LancasterUniversity 3:d86a4ddc1867 366 uint8_t buf[len + 1];
Jonathan Austin 1:8aa5cdb4ab67 367
LancasterUniversity 8:ec4465853952 368 memclr(&buf, len + 1);
LancasterUniversity 8:ec4465853952 369
Jonathan Austin 1:8aa5cdb4ab67 370 int ret = read(buf, len, mode);
Jonathan Austin 1:8aa5cdb4ab67 371
Jonathan Austin 1:8aa5cdb4ab67 372 if(ret < 1)
Jonathan Austin 1:8aa5cdb4ab67 373 return ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 374
Jonathan Austin 1:8aa5cdb4ab67 375 return ManagedString((const char *)buf);
Jonathan Austin 1:8aa5cdb4ab67 376 }
Jonathan Austin 1:8aa5cdb4ab67 377
Jonathan Austin 1:8aa5cdb4ab67 378 /**
Jonathan Austin 1:8aa5cdb4ab67 379 * Reads characters until a character matches one of the given delimeters
Jonathan Austin 1:8aa5cdb4ab67 380 *
Jonathan Austin 1:8aa5cdb4ab67 381 * @param delimeters the number of characters to match against
Jonathan Austin 1:8aa5cdb4ab67 382 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 383 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 384 *
Jonathan Austin 1:8aa5cdb4ab67 385 * ASYNC - Will attempt read the immediate buffer, and look for a match.
Jonathan Austin 1:8aa5cdb4ab67 386 * If there isn't, an empty ManagedString will be returned.
Jonathan Austin 1:8aa5cdb4ab67 387 *
Jonathan Austin 1:8aa5cdb4ab67 388 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 389 *
Jonathan Austin 1:8aa5cdb4ab67 390 * SYNC_SLEEP - Will first of all consider the characters in the immediate buffer,
Jonathan Austin 1:8aa5cdb4ab67 391 * if a match is not found, it will block on an event, fired when a
Jonathan Austin 1:8aa5cdb4ab67 392 * character is matched.
Jonathan Austin 1:8aa5cdb4ab67 393 *
Jonathan Austin 1:8aa5cdb4ab67 394 * @return an empty ManagedString on error, or a ManagedString containing characters
Jonathan Austin 1:8aa5cdb4ab67 395 */
Jonathan Austin 1:8aa5cdb4ab67 396 ManagedString MicroBitUARTService::readUntil(ManagedString delimeters, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 397 {
Jonathan Austin 1:8aa5cdb4ab67 398 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 399 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 400
Jonathan Austin 1:8aa5cdb4ab67 401 int localTail = rxBufferTail;
Jonathan Austin 1:8aa5cdb4ab67 402 int preservedTail = rxBufferTail;
Jonathan Austin 1:8aa5cdb4ab67 403
Jonathan Austin 1:8aa5cdb4ab67 404 int foundIndex = -1;
Jonathan Austin 1:8aa5cdb4ab67 405
Jonathan Austin 1:8aa5cdb4ab67 406 //ASYNC mode just iterates through our stored characters checking for any matches.
Jonathan Austin 1:8aa5cdb4ab67 407 while(localTail != rxBufferHead && foundIndex == -1)
Jonathan Austin 1:8aa5cdb4ab67 408 {
Jonathan Austin 1:8aa5cdb4ab67 409 //we use localTail to prevent modification of the actual tail.
Jonathan Austin 1:8aa5cdb4ab67 410 char c = rxBuffer[localTail];
Jonathan Austin 1:8aa5cdb4ab67 411
Jonathan Austin 1:8aa5cdb4ab67 412 for(int delimeterIterator = 0; delimeterIterator < delimeters.length(); delimeterIterator++)
Jonathan Austin 1:8aa5cdb4ab67 413 if(delimeters.charAt(delimeterIterator) == c)
Jonathan Austin 1:8aa5cdb4ab67 414 foundIndex = localTail;
Jonathan Austin 1:8aa5cdb4ab67 415
Jonathan Austin 1:8aa5cdb4ab67 416 localTail = (localTail + 1) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 417 }
Jonathan Austin 1:8aa5cdb4ab67 418
Jonathan Austin 1:8aa5cdb4ab67 419 //if our mode is SYNC_SLEEP, we set up an event to be fired when we see a
Jonathan Austin 1:8aa5cdb4ab67 420 //matching character.
Jonathan Austin 1:8aa5cdb4ab67 421 if(mode == SYNC_SLEEP && foundIndex == -1)
Jonathan Austin 1:8aa5cdb4ab67 422 {
Jonathan Austin 1:8aa5cdb4ab67 423 eventOn(delimeters, mode);
Jonathan Austin 1:8aa5cdb4ab67 424
Jonathan Austin 1:8aa5cdb4ab67 425 foundIndex = rxBufferHead - 1;
Jonathan Austin 1:8aa5cdb4ab67 426
Jonathan Austin 1:8aa5cdb4ab67 427 this->delimeters = ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 428 }
Jonathan Austin 1:8aa5cdb4ab67 429
Jonathan Austin 1:8aa5cdb4ab67 430 if(foundIndex >= 0)
Jonathan Austin 1:8aa5cdb4ab67 431 {
Jonathan Austin 1:8aa5cdb4ab67 432 //calculate our local buffer size
Jonathan Austin 1:8aa5cdb4ab67 433 int localBuffSize = (preservedTail > foundIndex) ? (rxBufferSize - preservedTail) + foundIndex : foundIndex - preservedTail;
Jonathan Austin 1:8aa5cdb4ab67 434
LancasterUniversity 3:d86a4ddc1867 435 uint8_t localBuff[localBuffSize + 1];
Jonathan Austin 1:8aa5cdb4ab67 436
LancasterUniversity 8:ec4465853952 437 memclr(&localBuff, localBuffSize + 1);
LancasterUniversity 8:ec4465853952 438
Jonathan Austin 1:8aa5cdb4ab67 439 circularCopy(rxBuffer, rxBufferSize, localBuff, preservedTail, foundIndex);
Jonathan Austin 1:8aa5cdb4ab67 440
Jonathan Austin 1:8aa5cdb4ab67 441 //plus one for the character we listened for...
Jonathan Austin 1:8aa5cdb4ab67 442 rxBufferTail = (rxBufferTail + localBuffSize + 1) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 443
Jonathan Austin 1:8aa5cdb4ab67 444 return ManagedString((char *)localBuff, localBuffSize);
Jonathan Austin 1:8aa5cdb4ab67 445 }
Jonathan Austin 1:8aa5cdb4ab67 446
Jonathan Austin 1:8aa5cdb4ab67 447 return ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 448 }
Jonathan Austin 1:8aa5cdb4ab67 449
Jonathan Austin 1:8aa5cdb4ab67 450 /**
Jonathan Austin 1:8aa5cdb4ab67 451 * Configures an event to be fired on a match with one of the delimeters.
Jonathan Austin 1:8aa5cdb4ab67 452 *
Jonathan Austin 1:8aa5cdb4ab67 453 * @param delimeters the characters to match received characters against e.g. ManagedString("\r\n")
Jonathan Austin 1:8aa5cdb4ab67 454 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 455 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 456 *
Jonathan Austin 1:8aa5cdb4ab67 457 * ASYNC - Will configure the event and return immediately.
Jonathan Austin 1:8aa5cdb4ab67 458 *
Jonathan Austin 1:8aa5cdb4ab67 459 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 460 *
Jonathan Austin 1:8aa5cdb4ab67 461 * SYNC_SLEEP - Will configure the event and block the current fiber until the
Jonathan Austin 1:8aa5cdb4ab67 462 * event is received.
Jonathan Austin 1:8aa5cdb4ab67 463 *
Jonathan Austin 1:8aa5cdb4ab67 464 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 465 *
Jonathan Austin 1:8aa5cdb4ab67 466 * @note delimeters are matched on a per byte basis.
Jonathan Austin 1:8aa5cdb4ab67 467 */
Jonathan Austin 1:8aa5cdb4ab67 468 int MicroBitUARTService::eventOn(ManagedString delimeters, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 469 {
Jonathan Austin 1:8aa5cdb4ab67 470 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 471 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 472
Jonathan Austin 1:8aa5cdb4ab67 473 //configure our head match...
Jonathan Austin 1:8aa5cdb4ab67 474 this->delimeters = delimeters;
Jonathan Austin 1:8aa5cdb4ab67 475
Jonathan Austin 1:8aa5cdb4ab67 476 //block!
Jonathan Austin 1:8aa5cdb4ab67 477 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 478 fiber_wait_for_event(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 479
Jonathan Austin 1:8aa5cdb4ab67 480 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 481 }
Jonathan Austin 1:8aa5cdb4ab67 482
Jonathan Austin 1:8aa5cdb4ab67 483 /**
Jonathan Austin 1:8aa5cdb4ab67 484 * Configures an event to be fired after "len" characters.
Jonathan Austin 1:8aa5cdb4ab67 485 *
Jonathan Austin 1:8aa5cdb4ab67 486 * @param len the number of characters to wait before triggering the event
Jonathan Austin 1:8aa5cdb4ab67 487 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 488 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 489 *
Jonathan Austin 1:8aa5cdb4ab67 490 * ASYNC - Will configure the event and return immediately.
Jonathan Austin 1:8aa5cdb4ab67 491 *
Jonathan Austin 1:8aa5cdb4ab67 492 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 493 *
Jonathan Austin 1:8aa5cdb4ab67 494 * SYNC_SLEEP - Will configure the event and block the current fiber until the
Jonathan Austin 1:8aa5cdb4ab67 495 * event is received.
Jonathan Austin 1:8aa5cdb4ab67 496 *
Jonathan Austin 1:8aa5cdb4ab67 497 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 498 */
Jonathan Austin 1:8aa5cdb4ab67 499 int MicroBitUARTService::eventAfter(int len, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 500 {
Jonathan Austin 1:8aa5cdb4ab67 501 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 502 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 503
Jonathan Austin 1:8aa5cdb4ab67 504 //configure our head match...
Jonathan Austin 1:8aa5cdb4ab67 505 this->rxBuffHeadMatch = (rxBufferHead + len) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 506
Jonathan Austin 1:8aa5cdb4ab67 507 //block!
Jonathan Austin 1:8aa5cdb4ab67 508 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 509 fiber_wait_for_event(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_HEAD_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 510
Jonathan Austin 1:8aa5cdb4ab67 511 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 512 }
Jonathan Austin 1:8aa5cdb4ab67 513
Jonathan Austin 1:8aa5cdb4ab67 514 /**
Jonathan Austin 1:8aa5cdb4ab67 515 * Determines if we have space in our rxBuff.
Jonathan Austin 1:8aa5cdb4ab67 516 *
Jonathan Austin 1:8aa5cdb4ab67 517 * @return 1 if we have space, 0 if we do not.
Jonathan Austin 1:8aa5cdb4ab67 518 *
Jonathan Austin 1:8aa5cdb4ab67 519 * @note the reason we do not wrap the super's readable() method is so that we
Jonathan Austin 1:8aa5cdb4ab67 520 * don't interfere with communities that use manual calls to uBit.serial.readable()
Jonathan Austin 1:8aa5cdb4ab67 521 */
Jonathan Austin 1:8aa5cdb4ab67 522 int MicroBitUARTService::isReadable()
Jonathan Austin 1:8aa5cdb4ab67 523 {
Jonathan Austin 1:8aa5cdb4ab67 524 return (rxBufferTail != rxBufferHead) ? 1 : 0;
Jonathan Austin 1:8aa5cdb4ab67 525 }
Jonathan Austin 1:8aa5cdb4ab67 526
Jonathan Austin 1:8aa5cdb4ab67 527 /**
Jonathan Austin 1:8aa5cdb4ab67 528 * @return The currently buffered number of bytes in our rxBuff.
Jonathan Austin 1:8aa5cdb4ab67 529 */
Jonathan Austin 1:8aa5cdb4ab67 530 int MicroBitUARTService::rxBufferedSize()
Jonathan Austin 1:8aa5cdb4ab67 531 {
Jonathan Austin 1:8aa5cdb4ab67 532 if(rxBufferTail > rxBufferHead)
Jonathan Austin 1:8aa5cdb4ab67 533 return (rxBufferSize - rxBufferTail) + rxBufferHead;
Jonathan Austin 1:8aa5cdb4ab67 534
Jonathan Austin 1:8aa5cdb4ab67 535 return rxBufferHead - rxBufferTail;
Jonathan Austin 1:8aa5cdb4ab67 536 }
Jonathan Austin 1:8aa5cdb4ab67 537
Jonathan Austin 1:8aa5cdb4ab67 538 /**
Jonathan Austin 1:8aa5cdb4ab67 539 * @return The currently buffered number of bytes in our txBuff.
Jonathan Austin 1:8aa5cdb4ab67 540 */
Jonathan Austin 1:8aa5cdb4ab67 541 int MicroBitUARTService::txBufferedSize()
Jonathan Austin 1:8aa5cdb4ab67 542 {
Jonathan Austin 1:8aa5cdb4ab67 543 if(txBufferTail > txBufferHead)
Jonathan Austin 1:8aa5cdb4ab67 544 return (txBufferSize - txBufferTail) + txBufferHead;
Jonathan Austin 1:8aa5cdb4ab67 545
Jonathan Austin 1:8aa5cdb4ab67 546 return txBufferHead - txBufferTail;
LancasterUniversity 3:d86a4ddc1867 547 }