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:07 2016 +0100
Revision:
29:62f8b007debf
Parent:
8:ec4465853952
Child:
58:2ac8d45f1b08
Synchronized with git rev 0048a9ac
Author: James Devine
microbit-dal: fixed UART service buffer sizing, and re-enabled config options for default services

There was a perspective mismatch with the UART service, where the
actual buffer size given in the constructor, did not reflect the size
of the user buffer that was available to the application. This was not
documented, and hence cause confusion. The patch applied in this
commit, increments the given buffer sizes by one, so that the
application buffer has the available size given in the constructor.

Additionally, some configuration options were lost during the component
refactor, these have now been restored.

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
Jonathan Austin 1:8aa5cdb4ab67 43 static GattCharacteristic* rxCharacteristic = NULL;
Jonathan Austin 1:8aa5cdb4ab67 44
Jonathan Austin 1:8aa5cdb4ab67 45 /**
Jonathan Austin 1:8aa5cdb4ab67 46 * A callback function for whenever a Bluetooth device consumes our RX Buffer
Jonathan Austin 1:8aa5cdb4ab67 47 */
Jonathan Austin 1:8aa5cdb4ab67 48 void on_confirmation_received_callback(uint16_t handle)
Jonathan Austin 1:8aa5cdb4ab67 49 {
Jonathan Austin 1:8aa5cdb4ab67 50 #if CONFIG_ENABLED(MICROBIT_DBG)
Jonathan Austin 1:8aa5cdb4ab67 51 SERIAL_DEBUG->printf("RECEIVED!! %d \r\n",handle);
Jonathan Austin 1:8aa5cdb4ab67 52 #endif
Jonathan Austin 1:8aa5cdb4ab67 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
Jonathan Austin 1:8aa5cdb4ab67 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
Jonathan Austin 1:8aa5cdb4ab67 86 rxCharacteristic = new GattCharacteristic(UARTServiceRXCharacteristicUUID, txBuffer, 1, txBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
Jonathan Austin 1:8aa5cdb4ab67 87
Jonathan Austin 1:8aa5cdb4ab67 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
Jonathan Austin 1:8aa5cdb4ab67 94 this->txCharacteristicHandle = txCharacteristic.getValueAttribute().getHandle();
Jonathan Austin 1:8aa5cdb4ab67 95
Jonathan Austin 1:8aa5cdb4ab67 96 _ble.gattServer().onDataWritten(this, &MicroBitUARTService::onDataWritten);
Jonathan Austin 1:8aa5cdb4ab67 97 _ble.gattServer().onConfirmationReceived(on_confirmation_received_callback);
Jonathan Austin 1:8aa5cdb4ab67 98 }
Jonathan Austin 1:8aa5cdb4ab67 99
Jonathan Austin 1:8aa5cdb4ab67 100 /**
Jonathan Austin 1:8aa5cdb4ab67 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) {
Jonathan Austin 1:8aa5cdb4ab67 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 *
Jonathan Austin 1:8aa5cdb4ab67 213 * @return the number of characters written (0, or 1).
Jonathan Austin 1:8aa5cdb4ab67 214 */
Jonathan Austin 1:8aa5cdb4ab67 215 int MicroBitUARTService::putc(char c)
Jonathan Austin 1:8aa5cdb4ab67 216 {
Jonathan Austin 1:8aa5cdb4ab67 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 *
Jonathan Austin 1:8aa5cdb4ab67 226 * @return the number of characters copied into the buffer
Jonathan Austin 1:8aa5cdb4ab67 227 *
Jonathan Austin 1:8aa5cdb4ab67 228 * @note no modes for sending are available at the moment, due to interrupt overhead.
Jonathan Austin 1:8aa5cdb4ab67 229 */
Jonathan Austin 1:8aa5cdb4ab67 230 int MicroBitUARTService::send(const uint8_t *buf, int length)
Jonathan Austin 1:8aa5cdb4ab67 231 {
Jonathan Austin 1:8aa5cdb4ab67 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
Jonathan Austin 1:8aa5cdb4ab67 237 if (ble.getGapState().connected) {
Jonathan Austin 1:8aa5cdb4ab67 238
Jonathan Austin 1:8aa5cdb4ab67 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
Jonathan Austin 1:8aa5cdb4ab67 255 #if CONFIG_ENABLED(MICROBIT_DBG)
Jonathan Austin 1:8aa5cdb4ab67 256 SERIAL_DEBUG->printf("tx size: %d", size);
Jonathan Austin 1:8aa5cdb4ab67 257 #endif
Jonathan Austin 1:8aa5cdb4ab67 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
Jonathan Austin 1:8aa5cdb4ab67 265 #if CONFIG_ENABLED(MICROBIT_DBG)
Jonathan Austin 1:8aa5cdb4ab67 266 for(int i = 0; i < size; i++)
Jonathan Austin 1:8aa5cdb4ab67 267 SERIAL_DEBUG->printf("%c",temp[i]);
Jonathan Austin 1:8aa5cdb4ab67 268 #endif
Jonathan Austin 1:8aa5cdb4ab67 269
Jonathan Austin 1:8aa5cdb4ab67 270 ble.gattServer().write(rxCharacteristic->getValueAttribute().getHandle(), temp, size);
Jonathan Austin 1:8aa5cdb4ab67 271 }
Jonathan Austin 1:8aa5cdb4ab67 272
Jonathan Austin 1:8aa5cdb4ab67 273 #if CONFIG_ENABLED(MICROBIT_DBG)
Jonathan Austin 1:8aa5cdb4ab67 274 SERIAL_DEBUG->printf("written: %d \r\n",bytesWritten);
Jonathan Austin 1:8aa5cdb4ab67 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 *
Jonathan Austin 1:8aa5cdb4ab67 285 * @return the number of characters copied into the buffer
Jonathan Austin 1:8aa5cdb4ab67 286 *
Jonathan Austin 1:8aa5cdb4ab67 287 * @note no modes for sending are available at the moment, due to interrupt overhead.
Jonathan Austin 1:8aa5cdb4ab67 288 */
Jonathan Austin 1:8aa5cdb4ab67 289 int MicroBitUARTService::send(ManagedString s)
Jonathan Austin 1:8aa5cdb4ab67 290 {
Jonathan Austin 1:8aa5cdb4ab67 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 }