Revised to disable BLE for radio communication as needed.

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit

Committer:
tsfarber
Date:
Tue Nov 26 04:12:46 2019 +0000
Revision:
74:26717338739d
Parent:
66:2fc7d7c2fffc
This program combines samples programs radio TX and radio RX so that both units can send or receive depending on which unit's buttons are pressed. Tested successfully. MicroBitConfig.h has been edited to disable BLE.

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 66:2fc7d7c2fffc 43 static GattCharacteristic* txCharacteristic = NULL;
Jonathan Austin 1:8aa5cdb4ab67 44
Jonathan Austin 1:8aa5cdb4ab67 45 /**
LancasterUniversity 66:2fc7d7c2fffc 46 * A callback function for whenever a Bluetooth device consumes our TX Buffer
Jonathan Austin 1:8aa5cdb4ab67 47 */
LancasterUniversity 66:2fc7d7c2fffc 48 void on_confirmation(uint16_t handle)
Jonathan Austin 1:8aa5cdb4ab67 49 {
LancasterUniversity 66:2fc7d7c2fffc 50 if(handle == txCharacteristic->getValueAttribute().getHandle())
Jonathan Austin 1:8aa5cdb4ab67 51 {
Jonathan Austin 1:8aa5cdb4ab67 52 txBufferTail = txBufferHead;
Jonathan Austin 1:8aa5cdb4ab67 53 MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY);
Jonathan Austin 1:8aa5cdb4ab67 54 }
Jonathan Austin 1:8aa5cdb4ab67 55 }
Jonathan Austin 1:8aa5cdb4ab67 56
Jonathan Austin 1:8aa5cdb4ab67 57 /**
Jonathan Austin 1:8aa5cdb4ab67 58 * Constructor for the UARTService.
Jonathan Austin 1:8aa5cdb4ab67 59 * @param _ble an instance of BLEDevice
Jonathan Austin 1:8aa5cdb4ab67 60 * @param rxBufferSize the size of the rxBuffer
Jonathan Austin 1:8aa5cdb4ab67 61 * @param txBufferSize the size of the txBuffer
Jonathan Austin 1:8aa5cdb4ab67 62 *
Jonathan Austin 1:8aa5cdb4ab67 63 * @note defaults to 20
Jonathan Austin 1:8aa5cdb4ab67 64 */
Jonathan Austin 1:8aa5cdb4ab67 65 MicroBitUARTService::MicroBitUARTService(BLEDevice &_ble, uint8_t rxBufferSize, uint8_t txBufferSize) : ble(_ble)
Jonathan Austin 1:8aa5cdb4ab67 66 {
LancasterUniversity 29:62f8b007debf 67 rxBufferSize += 1;
LancasterUniversity 29:62f8b007debf 68 txBufferSize += 1;
Jonathan Austin 1:8aa5cdb4ab67 69
Jonathan Austin 1:8aa5cdb4ab67 70 txBuffer = (uint8_t *)malloc(txBufferSize);
Jonathan Austin 1:8aa5cdb4ab67 71 rxBuffer = (uint8_t *)malloc(rxBufferSize);
Jonathan Austin 1:8aa5cdb4ab67 72
Jonathan Austin 1:8aa5cdb4ab67 73 rxBufferHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 74 rxBufferTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 75 this->rxBufferSize = rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 76
Jonathan Austin 1:8aa5cdb4ab67 77 txBufferHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 78 txBufferTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 79 this->txBufferSize = txBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 80
LancasterUniversity 66:2fc7d7c2fffc 81 GattCharacteristic rxCharacteristic(UARTServiceRXCharacteristicUUID, rxBuffer, 1, rxBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
Jonathan Austin 1:8aa5cdb4ab67 82
LancasterUniversity 66:2fc7d7c2fffc 83 txCharacteristic = new GattCharacteristic(UARTServiceTXCharacteristicUUID, txBuffer, 1, txBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
Jonathan Austin 1:8aa5cdb4ab67 84
LancasterUniversity 66:2fc7d7c2fffc 85 GattCharacteristic *charTable[] = {txCharacteristic, &rxCharacteristic};
Jonathan Austin 1:8aa5cdb4ab67 86
Jonathan Austin 1:8aa5cdb4ab67 87 GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
Jonathan Austin 1:8aa5cdb4ab67 88
Jonathan Austin 1:8aa5cdb4ab67 89 _ble.addService(uartService);
Jonathan Austin 1:8aa5cdb4ab67 90
LancasterUniversity 66:2fc7d7c2fffc 91 this->rxCharacteristicHandle = rxCharacteristic.getValueAttribute().getHandle();
Jonathan Austin 1:8aa5cdb4ab67 92
Jonathan Austin 1:8aa5cdb4ab67 93 _ble.gattServer().onDataWritten(this, &MicroBitUARTService::onDataWritten);
LancasterUniversity 66:2fc7d7c2fffc 94 _ble.gattServer().onConfirmationReceived(on_confirmation);
Jonathan Austin 1:8aa5cdb4ab67 95 }
Jonathan Austin 1:8aa5cdb4ab67 96
Jonathan Austin 1:8aa5cdb4ab67 97 /**
LancasterUniversity 66:2fc7d7c2fffc 98 * A callback function for whenever a Bluetooth device writes to our RX characteristic.
Jonathan Austin 1:8aa5cdb4ab67 99 */
Jonathan Austin 1:8aa5cdb4ab67 100 void MicroBitUARTService::onDataWritten(const GattWriteCallbackParams *params) {
LancasterUniversity 66:2fc7d7c2fffc 101 if (params->handle == this->rxCharacteristicHandle)
Jonathan Austin 1:8aa5cdb4ab67 102 {
Jonathan Austin 1:8aa5cdb4ab67 103 uint16_t bytesWritten = params->len;
Jonathan Austin 1:8aa5cdb4ab67 104
Jonathan Austin 1:8aa5cdb4ab67 105 for(int byteIterator = 0; byteIterator < bytesWritten; byteIterator++)
Jonathan Austin 1:8aa5cdb4ab67 106 {
Jonathan Austin 1:8aa5cdb4ab67 107 int newHead = (rxBufferHead + 1) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 108
Jonathan Austin 1:8aa5cdb4ab67 109 if(newHead != rxBufferTail)
Jonathan Austin 1:8aa5cdb4ab67 110 {
Jonathan Austin 1:8aa5cdb4ab67 111 char c = params->data[byteIterator];
Jonathan Austin 1:8aa5cdb4ab67 112
Jonathan Austin 1:8aa5cdb4ab67 113 int delimeterOffset = 0;
Jonathan Austin 1:8aa5cdb4ab67 114 int delimLength = this->delimeters.length();
Jonathan Austin 1:8aa5cdb4ab67 115
Jonathan Austin 1:8aa5cdb4ab67 116 //iterate through our delimeters (if any) to see if there is a match
Jonathan Austin 1:8aa5cdb4ab67 117 while(delimeterOffset < delimLength)
Jonathan Austin 1:8aa5cdb4ab67 118 {
Jonathan Austin 1:8aa5cdb4ab67 119 //fire an event if there is to block any waiting fibers
Jonathan Austin 1:8aa5cdb4ab67 120 if(this->delimeters.charAt(delimeterOffset) == c)
Jonathan Austin 1:8aa5cdb4ab67 121 MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 122
Jonathan Austin 1:8aa5cdb4ab67 123 delimeterOffset++;
Jonathan Austin 1:8aa5cdb4ab67 124 }
Jonathan Austin 1:8aa5cdb4ab67 125
Jonathan Austin 1:8aa5cdb4ab67 126 rxBuffer[rxBufferHead] = c;
Jonathan Austin 1:8aa5cdb4ab67 127
Jonathan Austin 1:8aa5cdb4ab67 128 rxBufferHead = newHead;
Jonathan Austin 1:8aa5cdb4ab67 129
Jonathan Austin 1:8aa5cdb4ab67 130 if(rxBufferHead == rxBuffHeadMatch)
Jonathan Austin 1:8aa5cdb4ab67 131 {
Jonathan Austin 1:8aa5cdb4ab67 132 rxBuffHeadMatch = -1;
Jonathan Austin 1:8aa5cdb4ab67 133 MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_HEAD_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 134 }
Jonathan Austin 1:8aa5cdb4ab67 135 }
Jonathan Austin 1:8aa5cdb4ab67 136 else
Jonathan Austin 1:8aa5cdb4ab67 137 MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_RX_FULL);
Jonathan Austin 1:8aa5cdb4ab67 138 }
Jonathan Austin 1:8aa5cdb4ab67 139 }
Jonathan Austin 1:8aa5cdb4ab67 140 }
Jonathan Austin 1:8aa5cdb4ab67 141
Jonathan Austin 1:8aa5cdb4ab67 142 /**
Jonathan Austin 1:8aa5cdb4ab67 143 * An internal method that copies values from a circular buffer to a linear buffer.
Jonathan Austin 1:8aa5cdb4ab67 144 *
Jonathan Austin 1:8aa5cdb4ab67 145 * @param circularBuff a pointer to the source circular buffer
Jonathan Austin 1:8aa5cdb4ab67 146 * @param circularBuffSize the size of the circular buffer
Jonathan Austin 1:8aa5cdb4ab67 147 * @param linearBuff a pointer to the destination linear buffer
Jonathan Austin 1:8aa5cdb4ab67 148 * @param tailPosition the tail position in the circular buffer you want to copy from
Jonathan Austin 1:8aa5cdb4ab67 149 * @param headPosition the head position in the circular buffer you want to copy to
Jonathan Austin 1:8aa5cdb4ab67 150 *
Jonathan Austin 1:8aa5cdb4ab67 151 * @note this method assumes that the linear buffer has the appropriate amount of
Jonathan Austin 1:8aa5cdb4ab67 152 * memory to contain the copy operation
Jonathan Austin 1:8aa5cdb4ab67 153 */
Jonathan Austin 1:8aa5cdb4ab67 154 void MicroBitUARTService::circularCopy(uint8_t *circularBuff, uint8_t circularBuffSize, uint8_t *linearBuff, uint16_t tailPosition, uint16_t headPosition)
Jonathan Austin 1:8aa5cdb4ab67 155 {
Jonathan Austin 1:8aa5cdb4ab67 156 int toBuffIndex = 0;
Jonathan Austin 1:8aa5cdb4ab67 157
Jonathan Austin 1:8aa5cdb4ab67 158 while(tailPosition != headPosition)
Jonathan Austin 1:8aa5cdb4ab67 159 {
Jonathan Austin 1:8aa5cdb4ab67 160 linearBuff[toBuffIndex++] = circularBuff[tailPosition];
Jonathan Austin 1:8aa5cdb4ab67 161
Jonathan Austin 1:8aa5cdb4ab67 162 tailPosition = (tailPosition + 1) % circularBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 163 }
Jonathan Austin 1:8aa5cdb4ab67 164 }
Jonathan Austin 1:8aa5cdb4ab67 165
Jonathan Austin 1:8aa5cdb4ab67 166 /**
Jonathan Austin 1:8aa5cdb4ab67 167 * Retreives a single character from our RxBuffer.
Jonathan Austin 1:8aa5cdb4ab67 168 *
Jonathan Austin 1:8aa5cdb4ab67 169 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 170 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 171 *
Jonathan Austin 1:8aa5cdb4ab67 172 * ASYNC - Will attempt to read a single character, and return immediately
Jonathan Austin 1:8aa5cdb4ab67 173 *
Jonathan Austin 1:8aa5cdb4ab67 174 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 175 *
Jonathan Austin 1:8aa5cdb4ab67 176 * SYNC_SLEEP - Will configure the event and block the current fiber until the
Jonathan Austin 1:8aa5cdb4ab67 177 * event is received.
Jonathan Austin 1:8aa5cdb4ab67 178 *
Jonathan Austin 1:8aa5cdb4ab67 179 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, a character or MICROBIT_NO_DATA
Jonathan Austin 1:8aa5cdb4ab67 180 */
Jonathan Austin 1:8aa5cdb4ab67 181 int MicroBitUARTService::getc(MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 182 {
Jonathan Austin 1:8aa5cdb4ab67 183 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 184 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 185
Jonathan Austin 1:8aa5cdb4ab67 186 if(mode == ASYNC)
Jonathan Austin 1:8aa5cdb4ab67 187 {
Jonathan Austin 1:8aa5cdb4ab67 188 if(!isReadable())
Jonathan Austin 1:8aa5cdb4ab67 189 return MICROBIT_NO_DATA;
Jonathan Austin 1:8aa5cdb4ab67 190 }
Jonathan Austin 1:8aa5cdb4ab67 191
Jonathan Austin 1:8aa5cdb4ab67 192 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 193 {
Jonathan Austin 1:8aa5cdb4ab67 194 if(!isReadable())
Jonathan Austin 1:8aa5cdb4ab67 195 eventAfter(1, mode);
Jonathan Austin 1:8aa5cdb4ab67 196 }
Jonathan Austin 1:8aa5cdb4ab67 197
Jonathan Austin 1:8aa5cdb4ab67 198 char c = rxBuffer[rxBufferTail];
Jonathan Austin 1:8aa5cdb4ab67 199
Jonathan Austin 1:8aa5cdb4ab67 200 rxBufferTail = (rxBufferTail + 1) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 201
Jonathan Austin 1:8aa5cdb4ab67 202 return c;
Jonathan Austin 1:8aa5cdb4ab67 203 }
Jonathan Austin 1:8aa5cdb4ab67 204
Jonathan Austin 1:8aa5cdb4ab67 205 /**
Jonathan Austin 1:8aa5cdb4ab67 206 * places a single character into our transmission buffer,
Jonathan Austin 1:8aa5cdb4ab67 207 *
Jonathan Austin 1:8aa5cdb4ab67 208 * @param c the character to transmit
Jonathan Austin 1:8aa5cdb4ab67 209 *
LancasterUniversity 66:2fc7d7c2fffc 210 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
LancasterUniversity 66:2fc7d7c2fffc 211 * gives a different behaviour:
LancasterUniversity 66:2fc7d7c2fffc 212 *
LancasterUniversity 66:2fc7d7c2fffc 213 * ASYNC - Will copy as many characters as it can into the buffer for transmission,
LancasterUniversity 66:2fc7d7c2fffc 214 * and return control to the user.
LancasterUniversity 66:2fc7d7c2fffc 215 *
LancasterUniversity 66:2fc7d7c2fffc 216 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
LancasterUniversity 66:2fc7d7c2fffc 217 *
LancasterUniversity 66:2fc7d7c2fffc 218 * SYNC_SLEEP - Will perform a cooperative blocking wait until all
LancasterUniversity 66:2fc7d7c2fffc 219 * given characters have been received by the connected
LancasterUniversity 66:2fc7d7c2fffc 220 * device.
LancasterUniversity 66:2fc7d7c2fffc 221 *
LancasterUniversity 66:2fc7d7c2fffc 222 * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
LancasterUniversity 66:2fc7d7c2fffc 223 * no connected device, or the connected device has not enabled indications.
Jonathan Austin 1:8aa5cdb4ab67 224 */
LancasterUniversity 66:2fc7d7c2fffc 225 int MicroBitUARTService::putc(char c, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 226 {
LancasterUniversity 66:2fc7d7c2fffc 227 return (send((uint8_t *)&c, 1, mode) == 1) ? 1 : EOF;
Jonathan Austin 1:8aa5cdb4ab67 228 }
Jonathan Austin 1:8aa5cdb4ab67 229
Jonathan Austin 1:8aa5cdb4ab67 230 /**
Jonathan Austin 1:8aa5cdb4ab67 231 * Copies characters into the buffer used for Transmitting to the central device.
Jonathan Austin 1:8aa5cdb4ab67 232 *
Jonathan Austin 1:8aa5cdb4ab67 233 * @param buf a buffer containing length number of bytes.
Jonathan Austin 1:8aa5cdb4ab67 234 * @param length the size of the buffer.
LancasterUniversity 66:2fc7d7c2fffc 235 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
LancasterUniversity 66:2fc7d7c2fffc 236 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 237 *
LancasterUniversity 66:2fc7d7c2fffc 238 * ASYNC - Will copy as many characters as it can into the buffer for transmission,
LancasterUniversity 66:2fc7d7c2fffc 239 * and return control to the user.
LancasterUniversity 66:2fc7d7c2fffc 240 *
LancasterUniversity 66:2fc7d7c2fffc 241 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
LancasterUniversity 58:2ac8d45f1b08 242 *
LancasterUniversity 66:2fc7d7c2fffc 243 * SYNC_SLEEP - Will perform a cooperative blocking wait until all
LancasterUniversity 66:2fc7d7c2fffc 244 * given characters have been received by the connected
LancasterUniversity 66:2fc7d7c2fffc 245 * device.
LancasterUniversity 66:2fc7d7c2fffc 246 *
LancasterUniversity 66:2fc7d7c2fffc 247 * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
LancasterUniversity 66:2fc7d7c2fffc 248 * no connected device, or the connected device has not enabled indications.
Jonathan Austin 1:8aa5cdb4ab67 249 */
LancasterUniversity 66:2fc7d7c2fffc 250 int MicroBitUARTService::send(const uint8_t *buf, int length, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 251 {
LancasterUniversity 66:2fc7d7c2fffc 252 if(length < 1 || mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 253 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 254
LancasterUniversity 66:2fc7d7c2fffc 255 bool updatesEnabled = false;
LancasterUniversity 66:2fc7d7c2fffc 256
LancasterUniversity 66:2fc7d7c2fffc 257 ble.gattServer().areUpdatesEnabled(*txCharacteristic, &updatesEnabled);
LancasterUniversity 66:2fc7d7c2fffc 258
LancasterUniversity 66:2fc7d7c2fffc 259 if(!ble.getGapState().connected && !updatesEnabled)
LancasterUniversity 66:2fc7d7c2fffc 260 return MICROBIT_NOT_SUPPORTED;
LancasterUniversity 66:2fc7d7c2fffc 261
Jonathan Austin 1:8aa5cdb4ab67 262 int bytesWritten = 0;
Jonathan Austin 1:8aa5cdb4ab67 263
LancasterUniversity 66:2fc7d7c2fffc 264 while(bytesWritten < length && ble.getGapState().connected && updatesEnabled)
LancasterUniversity 66:2fc7d7c2fffc 265 {
LancasterUniversity 66:2fc7d7c2fffc 266 for(int bufferIterator = bytesWritten; bufferIterator < length; bufferIterator++)
Jonathan Austin 1:8aa5cdb4ab67 267 {
Jonathan Austin 1:8aa5cdb4ab67 268 int nextHead = (txBufferHead + 1) % txBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 269
Jonathan Austin 1:8aa5cdb4ab67 270 if(nextHead != txBufferTail)
Jonathan Austin 1:8aa5cdb4ab67 271 {
Jonathan Austin 1:8aa5cdb4ab67 272 txBuffer[txBufferHead] = buf[bufferIterator];
Jonathan Austin 1:8aa5cdb4ab67 273
Jonathan Austin 1:8aa5cdb4ab67 274 txBufferHead = nextHead;
Jonathan Austin 1:8aa5cdb4ab67 275
Jonathan Austin 1:8aa5cdb4ab67 276 bytesWritten++;
Jonathan Austin 1:8aa5cdb4ab67 277 }
Jonathan Austin 1:8aa5cdb4ab67 278 }
Jonathan Austin 1:8aa5cdb4ab67 279
Jonathan Austin 1:8aa5cdb4ab67 280 int size = txBufferedSize();
Jonathan Austin 1:8aa5cdb4ab67 281
LancasterUniversity 3:d86a4ddc1867 282 uint8_t temp[size];
Jonathan Austin 1:8aa5cdb4ab67 283
LancasterUniversity 8:ec4465853952 284 memclr(&temp, size);
LancasterUniversity 8:ec4465853952 285
Jonathan Austin 1:8aa5cdb4ab67 286 circularCopy(txBuffer, txBufferSize, temp, txBufferTail, txBufferHead);
Jonathan Austin 1:8aa5cdb4ab67 287
LancasterUniversity 66:2fc7d7c2fffc 288
LancasterUniversity 66:2fc7d7c2fffc 289 if(mode == SYNC_SLEEP)
LancasterUniversity 66:2fc7d7c2fffc 290 fiber_wake_on_event(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY);
LancasterUniversity 66:2fc7d7c2fffc 291
LancasterUniversity 66:2fc7d7c2fffc 292 ble.gattServer().write(txCharacteristic->getValueAttribute().getHandle(), temp, size);
Jonathan Austin 1:8aa5cdb4ab67 293
LancasterUniversity 66:2fc7d7c2fffc 294 if(mode == SYNC_SLEEP)
LancasterUniversity 66:2fc7d7c2fffc 295 schedule();
LancasterUniversity 66:2fc7d7c2fffc 296 else
LancasterUniversity 66:2fc7d7c2fffc 297 break;
Jonathan Austin 1:8aa5cdb4ab67 298
LancasterUniversity 66:2fc7d7c2fffc 299 ble.gattServer().areUpdatesEnabled(*txCharacteristic, &updatesEnabled);
LancasterUniversity 66:2fc7d7c2fffc 300 }
Jonathan Austin 1:8aa5cdb4ab67 301
Jonathan Austin 1:8aa5cdb4ab67 302 return bytesWritten;
Jonathan Austin 1:8aa5cdb4ab67 303 }
Jonathan Austin 1:8aa5cdb4ab67 304
Jonathan Austin 1:8aa5cdb4ab67 305 /**
Jonathan Austin 1:8aa5cdb4ab67 306 * Copies characters into the buffer used for Transmitting to the central device.
Jonathan Austin 1:8aa5cdb4ab67 307 *
Jonathan Austin 1:8aa5cdb4ab67 308 * @param s the string to transmit
LancasterUniversity 66:2fc7d7c2fffc 309 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
LancasterUniversity 66:2fc7d7c2fffc 310 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 311 *
LancasterUniversity 66:2fc7d7c2fffc 312 * ASYNC - Will copy as many characters as it can into the buffer for transmission,
LancasterUniversity 66:2fc7d7c2fffc 313 * and return control to the user.
LancasterUniversity 66:2fc7d7c2fffc 314 *
LancasterUniversity 66:2fc7d7c2fffc 315 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 316 *
LancasterUniversity 66:2fc7d7c2fffc 317 * SYNC_SLEEP - Will perform a cooperative blocking wait until all
LancasterUniversity 66:2fc7d7c2fffc 318 * given characters have been received by the connected
LancasterUniversity 66:2fc7d7c2fffc 319 * device.
LancasterUniversity 66:2fc7d7c2fffc 320 *
LancasterUniversity 66:2fc7d7c2fffc 321 * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
LancasterUniversity 66:2fc7d7c2fffc 322 * no connected device, or the connected device has not enabled indications.
Jonathan Austin 1:8aa5cdb4ab67 323 */
LancasterUniversity 66:2fc7d7c2fffc 324 int MicroBitUARTService::send(ManagedString s, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 325 {
LancasterUniversity 66:2fc7d7c2fffc 326 return send((uint8_t *)s.toCharArray(), s.length(), mode);
Jonathan Austin 1:8aa5cdb4ab67 327 }
Jonathan Austin 1:8aa5cdb4ab67 328
Jonathan Austin 1:8aa5cdb4ab67 329 /**
Jonathan Austin 1:8aa5cdb4ab67 330 * Reads a number of characters from the rxBuffer and fills user given buffer.
Jonathan Austin 1:8aa5cdb4ab67 331 *
Jonathan Austin 1:8aa5cdb4ab67 332 * @param buf a pointer to a buffer of len bytes.
Jonathan Austin 1:8aa5cdb4ab67 333 * @param len the size of the user allocated buffer
Jonathan Austin 1:8aa5cdb4ab67 334 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 335 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 336 *
Jonathan Austin 1:8aa5cdb4ab67 337 * ASYNC - Will attempt to read all available characters, and return immediately
Jonathan Austin 1:8aa5cdb4ab67 338 * until the buffer limit is reached
Jonathan Austin 1:8aa5cdb4ab67 339 *
Jonathan Austin 1:8aa5cdb4ab67 340 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 341 *
Jonathan Austin 1:8aa5cdb4ab67 342 * SYNC_SLEEP - Will first of all determine whether the given number of characters
Jonathan Austin 1:8aa5cdb4ab67 343 * are available in our buffer, if not, it will set an event and sleep
Jonathan Austin 1:8aa5cdb4ab67 344 * until the number of characters are avaialable.
Jonathan Austin 1:8aa5cdb4ab67 345 *
Jonathan Austin 1:8aa5cdb4ab67 346 * @return the number of characters digested
Jonathan Austin 1:8aa5cdb4ab67 347 */
Jonathan Austin 1:8aa5cdb4ab67 348 int MicroBitUARTService::read(uint8_t *buf, int len, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 349 {
Jonathan Austin 1:8aa5cdb4ab67 350 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 351 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 352
Jonathan Austin 1:8aa5cdb4ab67 353 int i = 0;
Jonathan Austin 1:8aa5cdb4ab67 354
Jonathan Austin 1:8aa5cdb4ab67 355 if(mode == ASYNC)
Jonathan Austin 1:8aa5cdb4ab67 356 {
Jonathan Austin 1:8aa5cdb4ab67 357 int c;
Jonathan Austin 1:8aa5cdb4ab67 358
Jonathan Austin 1:8aa5cdb4ab67 359 while((c = getc(mode)) > 0 && i < len)
Jonathan Austin 1:8aa5cdb4ab67 360 {
Jonathan Austin 1:8aa5cdb4ab67 361 buf[i] = c;
Jonathan Austin 1:8aa5cdb4ab67 362 i++;
Jonathan Austin 1:8aa5cdb4ab67 363 }
Jonathan Austin 1:8aa5cdb4ab67 364 }
Jonathan Austin 1:8aa5cdb4ab67 365
Jonathan Austin 1:8aa5cdb4ab67 366 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 367 {
Jonathan Austin 1:8aa5cdb4ab67 368 if(len > rxBufferedSize())
Jonathan Austin 1:8aa5cdb4ab67 369 eventAfter(len - rxBufferedSize(), mode);
Jonathan Austin 1:8aa5cdb4ab67 370
Jonathan Austin 1:8aa5cdb4ab67 371 while(i < len)
Jonathan Austin 1:8aa5cdb4ab67 372 {
Jonathan Austin 1:8aa5cdb4ab67 373 buf[i] = (char)getc(mode);
Jonathan Austin 1:8aa5cdb4ab67 374 i++;
Jonathan Austin 1:8aa5cdb4ab67 375 }
Jonathan Austin 1:8aa5cdb4ab67 376 }
Jonathan Austin 1:8aa5cdb4ab67 377
Jonathan Austin 1:8aa5cdb4ab67 378 return i;
Jonathan Austin 1:8aa5cdb4ab67 379 }
Jonathan Austin 1:8aa5cdb4ab67 380
Jonathan Austin 1:8aa5cdb4ab67 381 /**
Jonathan Austin 1:8aa5cdb4ab67 382 * Reads a number of characters from the rxBuffer and returns them as a ManagedString
Jonathan Austin 1:8aa5cdb4ab67 383 *
Jonathan Austin 1:8aa5cdb4ab67 384 * @param len the number of characters to read.
Jonathan Austin 1:8aa5cdb4ab67 385 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 386 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 387 *
Jonathan Austin 1:8aa5cdb4ab67 388 * ASYNC - Will attempt to read all available characters, and return immediately
Jonathan Austin 1:8aa5cdb4ab67 389 * until the buffer limit is reached
Jonathan Austin 1:8aa5cdb4ab67 390 *
Jonathan Austin 1:8aa5cdb4ab67 391 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 392 *
Jonathan Austin 1:8aa5cdb4ab67 393 * SYNC_SLEEP - Will first of all determine whether the given number of characters
Jonathan Austin 1:8aa5cdb4ab67 394 * are available in our buffer, if not, it will set an event and sleep
Jonathan Austin 1:8aa5cdb4ab67 395 * until the number of characters are avaialable.
Jonathan Austin 1:8aa5cdb4ab67 396 *
Jonathan Austin 1:8aa5cdb4ab67 397 * @return an empty ManagedString on error, or a ManagedString containing characters
Jonathan Austin 1:8aa5cdb4ab67 398 */
Jonathan Austin 1:8aa5cdb4ab67 399 ManagedString MicroBitUARTService::read(int len, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 400 {
LancasterUniversity 3:d86a4ddc1867 401 uint8_t buf[len + 1];
Jonathan Austin 1:8aa5cdb4ab67 402
LancasterUniversity 8:ec4465853952 403 memclr(&buf, len + 1);
LancasterUniversity 8:ec4465853952 404
Jonathan Austin 1:8aa5cdb4ab67 405 int ret = read(buf, len, mode);
Jonathan Austin 1:8aa5cdb4ab67 406
Jonathan Austin 1:8aa5cdb4ab67 407 if(ret < 1)
Jonathan Austin 1:8aa5cdb4ab67 408 return ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 409
Jonathan Austin 1:8aa5cdb4ab67 410 return ManagedString((const char *)buf);
Jonathan Austin 1:8aa5cdb4ab67 411 }
Jonathan Austin 1:8aa5cdb4ab67 412
Jonathan Austin 1:8aa5cdb4ab67 413 /**
Jonathan Austin 1:8aa5cdb4ab67 414 * Reads characters until a character matches one of the given delimeters
Jonathan Austin 1:8aa5cdb4ab67 415 *
Jonathan Austin 1:8aa5cdb4ab67 416 * @param delimeters the number of characters to match against
Jonathan Austin 1:8aa5cdb4ab67 417 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 418 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 419 *
Jonathan Austin 1:8aa5cdb4ab67 420 * ASYNC - Will attempt read the immediate buffer, and look for a match.
Jonathan Austin 1:8aa5cdb4ab67 421 * If there isn't, an empty ManagedString will be returned.
Jonathan Austin 1:8aa5cdb4ab67 422 *
Jonathan Austin 1:8aa5cdb4ab67 423 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 424 *
Jonathan Austin 1:8aa5cdb4ab67 425 * SYNC_SLEEP - Will first of all consider the characters in the immediate buffer,
Jonathan Austin 1:8aa5cdb4ab67 426 * if a match is not found, it will block on an event, fired when a
Jonathan Austin 1:8aa5cdb4ab67 427 * character is matched.
Jonathan Austin 1:8aa5cdb4ab67 428 *
Jonathan Austin 1:8aa5cdb4ab67 429 * @return an empty ManagedString on error, or a ManagedString containing characters
Jonathan Austin 1:8aa5cdb4ab67 430 */
Jonathan Austin 1:8aa5cdb4ab67 431 ManagedString MicroBitUARTService::readUntil(ManagedString delimeters, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 432 {
Jonathan Austin 1:8aa5cdb4ab67 433 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 434 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 435
Jonathan Austin 1:8aa5cdb4ab67 436 int localTail = rxBufferTail;
Jonathan Austin 1:8aa5cdb4ab67 437 int preservedTail = rxBufferTail;
Jonathan Austin 1:8aa5cdb4ab67 438
Jonathan Austin 1:8aa5cdb4ab67 439 int foundIndex = -1;
Jonathan Austin 1:8aa5cdb4ab67 440
Jonathan Austin 1:8aa5cdb4ab67 441 //ASYNC mode just iterates through our stored characters checking for any matches.
Jonathan Austin 1:8aa5cdb4ab67 442 while(localTail != rxBufferHead && foundIndex == -1)
Jonathan Austin 1:8aa5cdb4ab67 443 {
Jonathan Austin 1:8aa5cdb4ab67 444 //we use localTail to prevent modification of the actual tail.
Jonathan Austin 1:8aa5cdb4ab67 445 char c = rxBuffer[localTail];
Jonathan Austin 1:8aa5cdb4ab67 446
Jonathan Austin 1:8aa5cdb4ab67 447 for(int delimeterIterator = 0; delimeterIterator < delimeters.length(); delimeterIterator++)
Jonathan Austin 1:8aa5cdb4ab67 448 if(delimeters.charAt(delimeterIterator) == c)
Jonathan Austin 1:8aa5cdb4ab67 449 foundIndex = localTail;
Jonathan Austin 1:8aa5cdb4ab67 450
Jonathan Austin 1:8aa5cdb4ab67 451 localTail = (localTail + 1) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 452 }
Jonathan Austin 1:8aa5cdb4ab67 453
Jonathan Austin 1:8aa5cdb4ab67 454 //if our mode is SYNC_SLEEP, we set up an event to be fired when we see a
Jonathan Austin 1:8aa5cdb4ab67 455 //matching character.
Jonathan Austin 1:8aa5cdb4ab67 456 if(mode == SYNC_SLEEP && foundIndex == -1)
Jonathan Austin 1:8aa5cdb4ab67 457 {
Jonathan Austin 1:8aa5cdb4ab67 458 eventOn(delimeters, mode);
Jonathan Austin 1:8aa5cdb4ab67 459
Jonathan Austin 1:8aa5cdb4ab67 460 foundIndex = rxBufferHead - 1;
Jonathan Austin 1:8aa5cdb4ab67 461
Jonathan Austin 1:8aa5cdb4ab67 462 this->delimeters = ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 463 }
Jonathan Austin 1:8aa5cdb4ab67 464
Jonathan Austin 1:8aa5cdb4ab67 465 if(foundIndex >= 0)
Jonathan Austin 1:8aa5cdb4ab67 466 {
Jonathan Austin 1:8aa5cdb4ab67 467 //calculate our local buffer size
Jonathan Austin 1:8aa5cdb4ab67 468 int localBuffSize = (preservedTail > foundIndex) ? (rxBufferSize - preservedTail) + foundIndex : foundIndex - preservedTail;
Jonathan Austin 1:8aa5cdb4ab67 469
LancasterUniversity 3:d86a4ddc1867 470 uint8_t localBuff[localBuffSize + 1];
Jonathan Austin 1:8aa5cdb4ab67 471
LancasterUniversity 8:ec4465853952 472 memclr(&localBuff, localBuffSize + 1);
LancasterUniversity 8:ec4465853952 473
Jonathan Austin 1:8aa5cdb4ab67 474 circularCopy(rxBuffer, rxBufferSize, localBuff, preservedTail, foundIndex);
Jonathan Austin 1:8aa5cdb4ab67 475
Jonathan Austin 1:8aa5cdb4ab67 476 //plus one for the character we listened for...
Jonathan Austin 1:8aa5cdb4ab67 477 rxBufferTail = (rxBufferTail + localBuffSize + 1) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 478
Jonathan Austin 1:8aa5cdb4ab67 479 return ManagedString((char *)localBuff, localBuffSize);
Jonathan Austin 1:8aa5cdb4ab67 480 }
Jonathan Austin 1:8aa5cdb4ab67 481
Jonathan Austin 1:8aa5cdb4ab67 482 return ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 483 }
Jonathan Austin 1:8aa5cdb4ab67 484
Jonathan Austin 1:8aa5cdb4ab67 485 /**
Jonathan Austin 1:8aa5cdb4ab67 486 * Configures an event to be fired on a match with one of the delimeters.
Jonathan Austin 1:8aa5cdb4ab67 487 *
Jonathan Austin 1:8aa5cdb4ab67 488 * @param delimeters the characters to match received characters against e.g. ManagedString("\r\n")
Jonathan Austin 1:8aa5cdb4ab67 489 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 490 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 491 *
Jonathan Austin 1:8aa5cdb4ab67 492 * ASYNC - Will configure the event and return immediately.
Jonathan Austin 1:8aa5cdb4ab67 493 *
Jonathan Austin 1:8aa5cdb4ab67 494 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 495 *
Jonathan Austin 1:8aa5cdb4ab67 496 * SYNC_SLEEP - Will configure the event and block the current fiber until the
Jonathan Austin 1:8aa5cdb4ab67 497 * event is received.
Jonathan Austin 1:8aa5cdb4ab67 498 *
Jonathan Austin 1:8aa5cdb4ab67 499 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 500 *
Jonathan Austin 1:8aa5cdb4ab67 501 * @note delimeters are matched on a per byte basis.
Jonathan Austin 1:8aa5cdb4ab67 502 */
Jonathan Austin 1:8aa5cdb4ab67 503 int MicroBitUARTService::eventOn(ManagedString delimeters, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 504 {
Jonathan Austin 1:8aa5cdb4ab67 505 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 506 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 507
Jonathan Austin 1:8aa5cdb4ab67 508 //configure our head match...
Jonathan Austin 1:8aa5cdb4ab67 509 this->delimeters = delimeters;
Jonathan Austin 1:8aa5cdb4ab67 510
Jonathan Austin 1:8aa5cdb4ab67 511 //block!
Jonathan Austin 1:8aa5cdb4ab67 512 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 513 fiber_wait_for_event(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 514
Jonathan Austin 1:8aa5cdb4ab67 515 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 516 }
Jonathan Austin 1:8aa5cdb4ab67 517
Jonathan Austin 1:8aa5cdb4ab67 518 /**
Jonathan Austin 1:8aa5cdb4ab67 519 * Configures an event to be fired after "len" characters.
Jonathan Austin 1:8aa5cdb4ab67 520 *
Jonathan Austin 1:8aa5cdb4ab67 521 * @param len the number of characters to wait before triggering the event
Jonathan Austin 1:8aa5cdb4ab67 522 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 523 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 524 *
Jonathan Austin 1:8aa5cdb4ab67 525 * ASYNC - Will configure the event and return immediately.
Jonathan Austin 1:8aa5cdb4ab67 526 *
Jonathan Austin 1:8aa5cdb4ab67 527 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 528 *
Jonathan Austin 1:8aa5cdb4ab67 529 * SYNC_SLEEP - Will configure the event and block the current fiber until the
Jonathan Austin 1:8aa5cdb4ab67 530 * event is received.
Jonathan Austin 1:8aa5cdb4ab67 531 *
Jonathan Austin 1:8aa5cdb4ab67 532 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 533 */
Jonathan Austin 1:8aa5cdb4ab67 534 int MicroBitUARTService::eventAfter(int len, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 535 {
Jonathan Austin 1:8aa5cdb4ab67 536 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 537 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 538
Jonathan Austin 1:8aa5cdb4ab67 539 //configure our head match...
Jonathan Austin 1:8aa5cdb4ab67 540 this->rxBuffHeadMatch = (rxBufferHead + len) % rxBufferSize;
Jonathan Austin 1:8aa5cdb4ab67 541
Jonathan Austin 1:8aa5cdb4ab67 542 //block!
Jonathan Austin 1:8aa5cdb4ab67 543 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 544 fiber_wait_for_event(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_HEAD_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 545
Jonathan Austin 1:8aa5cdb4ab67 546 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 547 }
Jonathan Austin 1:8aa5cdb4ab67 548
Jonathan Austin 1:8aa5cdb4ab67 549 /**
Jonathan Austin 1:8aa5cdb4ab67 550 * Determines if we have space in our rxBuff.
Jonathan Austin 1:8aa5cdb4ab67 551 *
Jonathan Austin 1:8aa5cdb4ab67 552 * @return 1 if we have space, 0 if we do not.
Jonathan Austin 1:8aa5cdb4ab67 553 *
Jonathan Austin 1:8aa5cdb4ab67 554 * @note the reason we do not wrap the super's readable() method is so that we
Jonathan Austin 1:8aa5cdb4ab67 555 * don't interfere with communities that use manual calls to uBit.serial.readable()
Jonathan Austin 1:8aa5cdb4ab67 556 */
Jonathan Austin 1:8aa5cdb4ab67 557 int MicroBitUARTService::isReadable()
Jonathan Austin 1:8aa5cdb4ab67 558 {
Jonathan Austin 1:8aa5cdb4ab67 559 return (rxBufferTail != rxBufferHead) ? 1 : 0;
Jonathan Austin 1:8aa5cdb4ab67 560 }
Jonathan Austin 1:8aa5cdb4ab67 561
Jonathan Austin 1:8aa5cdb4ab67 562 /**
Jonathan Austin 1:8aa5cdb4ab67 563 * @return The currently buffered number of bytes in our rxBuff.
Jonathan Austin 1:8aa5cdb4ab67 564 */
Jonathan Austin 1:8aa5cdb4ab67 565 int MicroBitUARTService::rxBufferedSize()
Jonathan Austin 1:8aa5cdb4ab67 566 {
Jonathan Austin 1:8aa5cdb4ab67 567 if(rxBufferTail > rxBufferHead)
Jonathan Austin 1:8aa5cdb4ab67 568 return (rxBufferSize - rxBufferTail) + rxBufferHead;
Jonathan Austin 1:8aa5cdb4ab67 569
Jonathan Austin 1:8aa5cdb4ab67 570 return rxBufferHead - rxBufferTail;
Jonathan Austin 1:8aa5cdb4ab67 571 }
Jonathan Austin 1:8aa5cdb4ab67 572
Jonathan Austin 1:8aa5cdb4ab67 573 /**
Jonathan Austin 1:8aa5cdb4ab67 574 * @return The currently buffered number of bytes in our txBuff.
Jonathan Austin 1:8aa5cdb4ab67 575 */
Jonathan Austin 1:8aa5cdb4ab67 576 int MicroBitUARTService::txBufferedSize()
Jonathan Austin 1:8aa5cdb4ab67 577 {
Jonathan Austin 1:8aa5cdb4ab67 578 if(txBufferTail > txBufferHead)
Jonathan Austin 1:8aa5cdb4ab67 579 return (txBufferSize - txBufferTail) + txBufferHead;
Jonathan Austin 1:8aa5cdb4ab67 580
Jonathan Austin 1:8aa5cdb4ab67 581 return txBufferHead - txBufferTail;
LancasterUniversity 3:d86a4ddc1867 582 }