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:
67:99cfde195ff3
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 #include "mbed.h"
Jonathan Austin 1:8aa5cdb4ab67 27 #include "MicroBitSerial.h"
Jonathan Austin 1:8aa5cdb4ab67 28 #include "ErrorNo.h"
Jonathan Austin 1:8aa5cdb4ab67 29 #include "MicroBitComponent.h"
Jonathan Austin 1:8aa5cdb4ab67 30 #include "MicroBitFiber.h"
Jonathan Austin 1:8aa5cdb4ab67 31 #include "NotifyEvents.h"
Jonathan Austin 1:8aa5cdb4ab67 32
Jonathan Austin 1:8aa5cdb4ab67 33 uint8_t MicroBitSerial::status = 0;
Jonathan Austin 1:8aa5cdb4ab67 34
Jonathan Austin 1:8aa5cdb4ab67 35 int MicroBitSerial::baudrate = 0;
Jonathan Austin 1:8aa5cdb4ab67 36
Jonathan Austin 1:8aa5cdb4ab67 37 /**
Jonathan Austin 1:8aa5cdb4ab67 38 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 39 * Create an instance of MicroBitSerial
Jonathan Austin 1:8aa5cdb4ab67 40 *
Jonathan Austin 1:8aa5cdb4ab67 41 * @param tx the Pin to be used for transmission
Jonathan Austin 1:8aa5cdb4ab67 42 *
Jonathan Austin 1:8aa5cdb4ab67 43 * @param rx the Pin to be used for receiving data
Jonathan Austin 1:8aa5cdb4ab67 44 *
Jonathan Austin 1:8aa5cdb4ab67 45 * @param rxBufferSize the size of the buffer to be used for receiving bytes
Jonathan Austin 1:8aa5cdb4ab67 46 *
Jonathan Austin 1:8aa5cdb4ab67 47 * @param txBufferSize the size of the buffer to be used for transmitting bytes
Jonathan Austin 1:8aa5cdb4ab67 48 *
Jonathan Austin 1:8aa5cdb4ab67 49 * @code
Jonathan Austin 1:8aa5cdb4ab67 50 * MicroBitSerial serial(USBTX, USBRX);
Jonathan Austin 1:8aa5cdb4ab67 51 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 52 * @note the default baud rate is 115200. More API details can be found:
Jonathan Austin 1:8aa5cdb4ab67 53 * -https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/api/SerialBase.h
Jonathan Austin 1:8aa5cdb4ab67 54 * -https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/api/RawSerial.h
Jonathan Austin 1:8aa5cdb4ab67 55 *
Jonathan Austin 1:8aa5cdb4ab67 56 * Buffers aren't allocated until the first send or receive respectively.
Jonathan Austin 1:8aa5cdb4ab67 57 */
Jonathan Austin 1:8aa5cdb4ab67 58 MicroBitSerial::MicroBitSerial(PinName tx, PinName rx, uint8_t rxBufferSize, uint8_t txBufferSize) : RawSerial(tx,rx), delimeters()
Jonathan Austin 1:8aa5cdb4ab67 59 {
LancasterUniversity 66:2fc7d7c2fffc 60 // + 1 so there is a usable buffer size, of the size the user requested.
LancasterUniversity 66:2fc7d7c2fffc 61 this->rxBuffSize = rxBufferSize + 1;
LancasterUniversity 66:2fc7d7c2fffc 62 this->txBuffSize = txBufferSize + 1;
Jonathan Austin 1:8aa5cdb4ab67 63
Jonathan Austin 1:8aa5cdb4ab67 64 this->rxBuff = NULL;
Jonathan Austin 1:8aa5cdb4ab67 65 this->txBuff = NULL;
Jonathan Austin 1:8aa5cdb4ab67 66
Jonathan Austin 1:8aa5cdb4ab67 67 this->rxBuffHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 68 this->rxBuffTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 69
Jonathan Austin 1:8aa5cdb4ab67 70 this->txBuffHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 71 this->txBuffTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 72
Jonathan Austin 1:8aa5cdb4ab67 73 this->rxBuffHeadMatch = -1;
Jonathan Austin 1:8aa5cdb4ab67 74
Jonathan Austin 1:8aa5cdb4ab67 75 this->baud(MICROBIT_SERIAL_DEFAULT_BAUD_RATE);
Jonathan Austin 1:8aa5cdb4ab67 76
Jonathan Austin 1:8aa5cdb4ab67 77 #if CONFIG_ENABLED(MICROBIT_DBG)
Jonathan Austin 1:8aa5cdb4ab67 78 SERIAL_DEBUG = this;
Jonathan Austin 1:8aa5cdb4ab67 79 #endif
Jonathan Austin 1:8aa5cdb4ab67 80
Jonathan Austin 1:8aa5cdb4ab67 81 }
Jonathan Austin 1:8aa5cdb4ab67 82
Jonathan Austin 1:8aa5cdb4ab67 83 /**
Jonathan Austin 1:8aa5cdb4ab67 84 * An internal interrupt callback for MicroBitSerial configured for when a
Jonathan Austin 1:8aa5cdb4ab67 85 * character is received.
Jonathan Austin 1:8aa5cdb4ab67 86 *
Jonathan Austin 1:8aa5cdb4ab67 87 * Each time a character is received fill our circular buffer!
Jonathan Austin 1:8aa5cdb4ab67 88 */
Jonathan Austin 1:8aa5cdb4ab67 89 void MicroBitSerial::dataReceived()
Jonathan Austin 1:8aa5cdb4ab67 90 {
Jonathan Austin 1:8aa5cdb4ab67 91 if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 92 return;
Jonathan Austin 1:8aa5cdb4ab67 93
Jonathan Austin 1:8aa5cdb4ab67 94 //get the received character
Jonathan Austin 1:8aa5cdb4ab67 95 char c = getc();
Jonathan Austin 1:8aa5cdb4ab67 96
Jonathan Austin 1:8aa5cdb4ab67 97 int delimeterOffset = 0;
Jonathan Austin 1:8aa5cdb4ab67 98 int delimLength = this->delimeters.length();
Jonathan Austin 1:8aa5cdb4ab67 99
Jonathan Austin 1:8aa5cdb4ab67 100 //iterate through our delimeters (if any) to see if there is a match
Jonathan Austin 1:8aa5cdb4ab67 101 while(delimeterOffset < delimLength)
Jonathan Austin 1:8aa5cdb4ab67 102 {
Jonathan Austin 1:8aa5cdb4ab67 103 //fire an event if there is to block any waiting fibers
Jonathan Austin 1:8aa5cdb4ab67 104 if(this->delimeters.charAt(delimeterOffset) == c)
Jonathan Austin 1:8aa5cdb4ab67 105 MicroBitEvent(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_DELIM_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 106
Jonathan Austin 1:8aa5cdb4ab67 107 delimeterOffset++;
Jonathan Austin 1:8aa5cdb4ab67 108 }
Jonathan Austin 1:8aa5cdb4ab67 109
Jonathan Austin 1:8aa5cdb4ab67 110 uint16_t newHead = (rxBuffHead + 1) % rxBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 111
Jonathan Austin 1:8aa5cdb4ab67 112 //look ahead to our newHead value to see if we are about to collide with the tail
Jonathan Austin 1:8aa5cdb4ab67 113 if(newHead != rxBuffTail)
Jonathan Austin 1:8aa5cdb4ab67 114 {
Jonathan Austin 1:8aa5cdb4ab67 115 //if we are not, store the character, and update our actual head.
Jonathan Austin 1:8aa5cdb4ab67 116 this->rxBuff[rxBuffHead] = c;
Jonathan Austin 1:8aa5cdb4ab67 117 rxBuffHead = newHead;
Jonathan Austin 1:8aa5cdb4ab67 118
Jonathan Austin 1:8aa5cdb4ab67 119 //if we have any fibers waiting for a specific number of characters, unblock them
Jonathan Austin 1:8aa5cdb4ab67 120 if(rxBuffHeadMatch >= 0)
Jonathan Austin 1:8aa5cdb4ab67 121 if(rxBuffHead == rxBuffHeadMatch)
Jonathan Austin 1:8aa5cdb4ab67 122 {
Jonathan Austin 1:8aa5cdb4ab67 123 rxBuffHeadMatch = -1;
Jonathan Austin 1:8aa5cdb4ab67 124 MicroBitEvent(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_HEAD_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 125 }
Jonathan Austin 1:8aa5cdb4ab67 126 }
Jonathan Austin 1:8aa5cdb4ab67 127 else
Jonathan Austin 1:8aa5cdb4ab67 128 //otherwise, our buffer is full, send an event to the user...
Jonathan Austin 1:8aa5cdb4ab67 129 MicroBitEvent(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_RX_FULL);
Jonathan Austin 1:8aa5cdb4ab67 130 }
Jonathan Austin 1:8aa5cdb4ab67 131
Jonathan Austin 1:8aa5cdb4ab67 132 /**
Jonathan Austin 1:8aa5cdb4ab67 133 * An internal interrupt callback for MicroBitSerial.
Jonathan Austin 1:8aa5cdb4ab67 134 *
Jonathan Austin 1:8aa5cdb4ab67 135 * Each time the Serial module's buffer is empty, write a character if we have
Jonathan Austin 1:8aa5cdb4ab67 136 * characters to write.
Jonathan Austin 1:8aa5cdb4ab67 137 */
Jonathan Austin 1:8aa5cdb4ab67 138 void MicroBitSerial::dataWritten()
Jonathan Austin 1:8aa5cdb4ab67 139 {
Jonathan Austin 1:8aa5cdb4ab67 140 if(txBuffTail == txBuffHead || !(status & MICROBIT_SERIAL_TX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 141 return;
Jonathan Austin 1:8aa5cdb4ab67 142
Jonathan Austin 1:8aa5cdb4ab67 143 //send our current char
Jonathan Austin 1:8aa5cdb4ab67 144 putc(txBuff[txBuffTail]);
Jonathan Austin 1:8aa5cdb4ab67 145
Jonathan Austin 1:8aa5cdb4ab67 146 uint16_t nextTail = (txBuffTail + 1) % txBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 147
Jonathan Austin 1:8aa5cdb4ab67 148 //unblock any waiting fibers that are waiting for transmission to finish.
Jonathan Austin 1:8aa5cdb4ab67 149 if(nextTail == txBuffHead)
Jonathan Austin 1:8aa5cdb4ab67 150 {
Jonathan Austin 1:8aa5cdb4ab67 151 MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_SERIAL_EVT_TX_EMPTY);
LancasterUniversity 6:2e1c2e0d8c7a 152 detach(Serial::TxIrq);
Jonathan Austin 1:8aa5cdb4ab67 153 }
Jonathan Austin 1:8aa5cdb4ab67 154
Jonathan Austin 1:8aa5cdb4ab67 155 //update our tail!
Jonathan Austin 1:8aa5cdb4ab67 156 txBuffTail = nextTail;
Jonathan Austin 1:8aa5cdb4ab67 157 }
Jonathan Austin 1:8aa5cdb4ab67 158
Jonathan Austin 1:8aa5cdb4ab67 159 /**
Jonathan Austin 1:8aa5cdb4ab67 160 * An internal method to configure an interrupt on tx buffer and also
Jonathan Austin 1:8aa5cdb4ab67 161 * a best effort copy operation to move bytes from a user buffer to our txBuff
Jonathan Austin 1:8aa5cdb4ab67 162 *
Jonathan Austin 1:8aa5cdb4ab67 163 * @param string a pointer to the first character of the users' buffer.
Jonathan Austin 1:8aa5cdb4ab67 164 *
Jonathan Austin 1:8aa5cdb4ab67 165 * @param len the length of the string, and ultimately the maximum number of bytes
Jonathan Austin 1:8aa5cdb4ab67 166 * that will be copied dependent on the state of txBuff
Jonathan Austin 1:8aa5cdb4ab67 167 *
LancasterUniversity 25:27299423d813 168 * @param mode determines whether to configure the current fiber context or not. If
LancasterUniversity 25:27299423d813 169 * The mode is SYNC_SPINWAIT, the context will not be configured, otherwise
LancasterUniversity 25:27299423d813 170 * no context will be configured.
LancasterUniversity 25:27299423d813 171 *
Jonathan Austin 1:8aa5cdb4ab67 172 * @return the number of bytes copied into the buffer.
Jonathan Austin 1:8aa5cdb4ab67 173 */
LancasterUniversity 25:27299423d813 174 int MicroBitSerial::setTxInterrupt(uint8_t *string, int len, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 175 {
Jonathan Austin 1:8aa5cdb4ab67 176 int copiedBytes = 0;
Jonathan Austin 1:8aa5cdb4ab67 177
Jonathan Austin 1:8aa5cdb4ab67 178 for(copiedBytes = 0; copiedBytes < len; copiedBytes++)
Jonathan Austin 1:8aa5cdb4ab67 179 {
Jonathan Austin 1:8aa5cdb4ab67 180 uint16_t nextHead = (txBuffHead + 1) % txBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 181 if(nextHead != txBuffTail)
Jonathan Austin 1:8aa5cdb4ab67 182 {
Jonathan Austin 1:8aa5cdb4ab67 183 this->txBuff[txBuffHead] = string[copiedBytes];
Jonathan Austin 1:8aa5cdb4ab67 184 txBuffHead = nextHead;
Jonathan Austin 1:8aa5cdb4ab67 185 }
Jonathan Austin 1:8aa5cdb4ab67 186 else
Jonathan Austin 1:8aa5cdb4ab67 187 break;
Jonathan Austin 1:8aa5cdb4ab67 188 }
Jonathan Austin 1:8aa5cdb4ab67 189
LancasterUniversity 25:27299423d813 190 if(mode != SYNC_SPINWAIT)
LancasterUniversity 25:27299423d813 191 fiber_wake_on_event(MICROBIT_ID_NOTIFY, MICROBIT_SERIAL_EVT_TX_EMPTY);
Jonathan Austin 1:8aa5cdb4ab67 192
Jonathan Austin 1:8aa5cdb4ab67 193 //set the TX interrupt
LancasterUniversity 6:2e1c2e0d8c7a 194 attach(this, &MicroBitSerial::dataWritten, Serial::TxIrq);
Jonathan Austin 1:8aa5cdb4ab67 195
Jonathan Austin 1:8aa5cdb4ab67 196 return copiedBytes;
Jonathan Austin 1:8aa5cdb4ab67 197 }
Jonathan Austin 1:8aa5cdb4ab67 198
Jonathan Austin 1:8aa5cdb4ab67 199 /**
Jonathan Austin 1:8aa5cdb4ab67 200 * Locks the mutex so that others can't use this serial instance for reception
Jonathan Austin 1:8aa5cdb4ab67 201 */
Jonathan Austin 1:8aa5cdb4ab67 202 void MicroBitSerial::lockRx()
Jonathan Austin 1:8aa5cdb4ab67 203 {
Jonathan Austin 1:8aa5cdb4ab67 204 status |= MICROBIT_SERIAL_RX_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 205 }
Jonathan Austin 1:8aa5cdb4ab67 206
Jonathan Austin 1:8aa5cdb4ab67 207 /**
Jonathan Austin 1:8aa5cdb4ab67 208 * Locks the mutex so that others can't use this serial instance for transmission
Jonathan Austin 1:8aa5cdb4ab67 209 */
Jonathan Austin 1:8aa5cdb4ab67 210 void MicroBitSerial::lockTx()
Jonathan Austin 1:8aa5cdb4ab67 211 {
Jonathan Austin 1:8aa5cdb4ab67 212 status |= MICROBIT_SERIAL_TX_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 213 }
Jonathan Austin 1:8aa5cdb4ab67 214
Jonathan Austin 1:8aa5cdb4ab67 215 /**
Jonathan Austin 1:8aa5cdb4ab67 216 * Unlocks the mutex so that others can use this serial instance for reception
Jonathan Austin 1:8aa5cdb4ab67 217 */
Jonathan Austin 1:8aa5cdb4ab67 218 void MicroBitSerial::unlockRx()
Jonathan Austin 1:8aa5cdb4ab67 219 {
Jonathan Austin 1:8aa5cdb4ab67 220 status &= ~MICROBIT_SERIAL_RX_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 221 }
Jonathan Austin 1:8aa5cdb4ab67 222
Jonathan Austin 1:8aa5cdb4ab67 223 /**
Jonathan Austin 1:8aa5cdb4ab67 224 * Unlocks the mutex so that others can use this serial instance for transmission
Jonathan Austin 1:8aa5cdb4ab67 225 */
Jonathan Austin 1:8aa5cdb4ab67 226 void MicroBitSerial::unlockTx()
Jonathan Austin 1:8aa5cdb4ab67 227 {
Jonathan Austin 1:8aa5cdb4ab67 228 status &= ~MICROBIT_SERIAL_TX_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 229 }
Jonathan Austin 1:8aa5cdb4ab67 230
Jonathan Austin 1:8aa5cdb4ab67 231 /**
Jonathan Austin 1:8aa5cdb4ab67 232 * We do not want to always have our buffers initialised, especially if users to not
Jonathan Austin 1:8aa5cdb4ab67 233 * use them. We only bring them up on demand.
Jonathan Austin 1:8aa5cdb4ab67 234 */
Jonathan Austin 1:8aa5cdb4ab67 235 int MicroBitSerial::initialiseRx()
Jonathan Austin 1:8aa5cdb4ab67 236 {
Jonathan Austin 1:8aa5cdb4ab67 237 if((status & MICROBIT_SERIAL_RX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 238 {
Jonathan Austin 1:8aa5cdb4ab67 239 //ensure that we receive no interrupts after freeing our buffer
LancasterUniversity 6:2e1c2e0d8c7a 240 detach(Serial::RxIrq);
Jonathan Austin 1:8aa5cdb4ab67 241 free(this->rxBuff);
Jonathan Austin 1:8aa5cdb4ab67 242 }
Jonathan Austin 1:8aa5cdb4ab67 243
Jonathan Austin 1:8aa5cdb4ab67 244 status &= ~MICROBIT_SERIAL_RX_BUFF_INIT;
Jonathan Austin 1:8aa5cdb4ab67 245
Jonathan Austin 1:8aa5cdb4ab67 246 if((this->rxBuff = (uint8_t *)malloc(rxBuffSize)) == NULL)
Jonathan Austin 1:8aa5cdb4ab67 247 return MICROBIT_NO_RESOURCES;
Jonathan Austin 1:8aa5cdb4ab67 248
Jonathan Austin 1:8aa5cdb4ab67 249 this->rxBuffHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 250 this->rxBuffTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 251
Jonathan Austin 1:8aa5cdb4ab67 252 //set the receive interrupt
Jonathan Austin 1:8aa5cdb4ab67 253 status |= MICROBIT_SERIAL_RX_BUFF_INIT;
LancasterUniversity 6:2e1c2e0d8c7a 254 attach(this, &MicroBitSerial::dataReceived, Serial::RxIrq);
Jonathan Austin 1:8aa5cdb4ab67 255
Jonathan Austin 1:8aa5cdb4ab67 256 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 257 }
Jonathan Austin 1:8aa5cdb4ab67 258
Jonathan Austin 1:8aa5cdb4ab67 259 /**
Jonathan Austin 1:8aa5cdb4ab67 260 * We do not want to always have our buffers initialised, especially if users to not
Jonathan Austin 1:8aa5cdb4ab67 261 * use them. We only bring them up on demand.
Jonathan Austin 1:8aa5cdb4ab67 262 */
Jonathan Austin 1:8aa5cdb4ab67 263 int MicroBitSerial::initialiseTx()
Jonathan Austin 1:8aa5cdb4ab67 264 {
Jonathan Austin 1:8aa5cdb4ab67 265 if((status & MICROBIT_SERIAL_TX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 266 {
Jonathan Austin 1:8aa5cdb4ab67 267 //ensure that we receive no interrupts after freeing our buffer
LancasterUniversity 6:2e1c2e0d8c7a 268 detach(Serial::TxIrq);
Jonathan Austin 1:8aa5cdb4ab67 269 free(this->txBuff);
Jonathan Austin 1:8aa5cdb4ab67 270 }
Jonathan Austin 1:8aa5cdb4ab67 271
Jonathan Austin 1:8aa5cdb4ab67 272 status &= ~MICROBIT_SERIAL_TX_BUFF_INIT;
Jonathan Austin 1:8aa5cdb4ab67 273
Jonathan Austin 1:8aa5cdb4ab67 274 if((this->txBuff = (uint8_t *)malloc(txBuffSize)) == NULL)
Jonathan Austin 1:8aa5cdb4ab67 275 return MICROBIT_NO_RESOURCES;
Jonathan Austin 1:8aa5cdb4ab67 276
Jonathan Austin 1:8aa5cdb4ab67 277 this->txBuffHead = 0;
Jonathan Austin 1:8aa5cdb4ab67 278 this->txBuffTail = 0;
Jonathan Austin 1:8aa5cdb4ab67 279
Jonathan Austin 1:8aa5cdb4ab67 280 status |= MICROBIT_SERIAL_TX_BUFF_INIT;
Jonathan Austin 1:8aa5cdb4ab67 281
Jonathan Austin 1:8aa5cdb4ab67 282 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 283 }
Jonathan Austin 1:8aa5cdb4ab67 284
Jonathan Austin 1:8aa5cdb4ab67 285 /**
Jonathan Austin 1:8aa5cdb4ab67 286 * An internal method that either spin waits if mode is set to SYNC_SPINWAIT
Jonathan Austin 1:8aa5cdb4ab67 287 * or puts the fiber to sleep if the mode is set to SYNC_SLEEP
Jonathan Austin 1:8aa5cdb4ab67 288 *
Jonathan Austin 1:8aa5cdb4ab67 289 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP
Jonathan Austin 1:8aa5cdb4ab67 290 */
Jonathan Austin 1:8aa5cdb4ab67 291 void MicroBitSerial::send(MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 292 {
Jonathan Austin 1:8aa5cdb4ab67 293 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 294 while(txBufferedSize() > 0);
Jonathan Austin 1:8aa5cdb4ab67 295
Jonathan Austin 1:8aa5cdb4ab67 296 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 297 fiber_sleep(0);
Jonathan Austin 1:8aa5cdb4ab67 298 }
Jonathan Austin 1:8aa5cdb4ab67 299
Jonathan Austin 1:8aa5cdb4ab67 300 /**
Jonathan Austin 1:8aa5cdb4ab67 301 * Reads a single character from the rxBuff
Jonathan Austin 1:8aa5cdb4ab67 302 *
Jonathan Austin 1:8aa5cdb4ab67 303 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 304 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 305 *
Jonathan Austin 1:8aa5cdb4ab67 306 * ASYNC - A character is read from the rxBuff if available, if there
Jonathan Austin 1:8aa5cdb4ab67 307 * are no characters to be read, a value of zero is returned immediately.
Jonathan Austin 1:8aa5cdb4ab67 308 *
Jonathan Austin 1:8aa5cdb4ab67 309 * SYNC_SPINWAIT - A character is read from the rxBuff if available, if there
Jonathan Austin 1:8aa5cdb4ab67 310 * are no characters to be read, this method will spin
Jonathan Austin 1:8aa5cdb4ab67 311 * (lock up the processor) until a character is available.
Jonathan Austin 1:8aa5cdb4ab67 312 *
Jonathan Austin 1:8aa5cdb4ab67 313 * SYNC_SLEEP - A character is read from the rxBuff if available, if there
Jonathan Austin 1:8aa5cdb4ab67 314 * are no characters to be read, the calling fiber sleeps
Jonathan Austin 1:8aa5cdb4ab67 315 * until there is a character available.
Jonathan Austin 1:8aa5cdb4ab67 316 *
Jonathan Austin 1:8aa5cdb4ab67 317 * Defaults to SYNC_SLEEP.
Jonathan Austin 1:8aa5cdb4ab67 318 *
Jonathan Austin 1:8aa5cdb4ab67 319 * @return a character from the circular buffer, or MICROBIT_NO_DATA is there
Jonathan Austin 1:8aa5cdb4ab67 320 * are no characters in the buffer.
Jonathan Austin 1:8aa5cdb4ab67 321 */
Jonathan Austin 1:8aa5cdb4ab67 322 int MicroBitSerial::getChar(MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 323 {
Jonathan Austin 1:8aa5cdb4ab67 324 if(mode == ASYNC)
Jonathan Austin 1:8aa5cdb4ab67 325 {
Jonathan Austin 1:8aa5cdb4ab67 326 if(!isReadable())
Jonathan Austin 1:8aa5cdb4ab67 327 return MICROBIT_NO_DATA;
Jonathan Austin 1:8aa5cdb4ab67 328 }
Jonathan Austin 1:8aa5cdb4ab67 329
Jonathan Austin 1:8aa5cdb4ab67 330 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 331 while(!isReadable());
Jonathan Austin 1:8aa5cdb4ab67 332
Jonathan Austin 1:8aa5cdb4ab67 333 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 334 {
Jonathan Austin 1:8aa5cdb4ab67 335 if(!isReadable())
Jonathan Austin 1:8aa5cdb4ab67 336 eventAfter(1, mode);
Jonathan Austin 1:8aa5cdb4ab67 337 }
Jonathan Austin 1:8aa5cdb4ab67 338
Jonathan Austin 1:8aa5cdb4ab67 339 char c = rxBuff[rxBuffTail];
Jonathan Austin 1:8aa5cdb4ab67 340
Jonathan Austin 1:8aa5cdb4ab67 341 rxBuffTail = (rxBuffTail + 1) % rxBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 342
Jonathan Austin 1:8aa5cdb4ab67 343 return c;
Jonathan Austin 1:8aa5cdb4ab67 344 }
Jonathan Austin 1:8aa5cdb4ab67 345
Jonathan Austin 1:8aa5cdb4ab67 346 /**
Jonathan Austin 1:8aa5cdb4ab67 347 * An internal method that copies values from a circular buffer to a linear buffer.
Jonathan Austin 1:8aa5cdb4ab67 348 *
Jonathan Austin 1:8aa5cdb4ab67 349 * @param circularBuff a pointer to the source circular buffer
Jonathan Austin 1:8aa5cdb4ab67 350 *
Jonathan Austin 1:8aa5cdb4ab67 351 * @param circularBuffSize the size of the circular buffer
Jonathan Austin 1:8aa5cdb4ab67 352 *
Jonathan Austin 1:8aa5cdb4ab67 353 * @param linearBuff a pointer to the destination linear buffer
Jonathan Austin 1:8aa5cdb4ab67 354 *
Jonathan Austin 1:8aa5cdb4ab67 355 * @param tailPosition the tail position in the circular buffer you want to copy from
Jonathan Austin 1:8aa5cdb4ab67 356 *
Jonathan Austin 1:8aa5cdb4ab67 357 * @param headPosition the head position in the circular buffer you want to copy to
Jonathan Austin 1:8aa5cdb4ab67 358 *
Jonathan Austin 1:8aa5cdb4ab67 359 * @note this method assumes that the linear buffer has the appropriate amount of
Jonathan Austin 1:8aa5cdb4ab67 360 * memory to contain the copy operation
Jonathan Austin 1:8aa5cdb4ab67 361 */
Jonathan Austin 1:8aa5cdb4ab67 362 void MicroBitSerial::circularCopy(uint8_t *circularBuff, uint8_t circularBuffSize, uint8_t *linearBuff, uint16_t tailPosition, uint16_t headPosition)
Jonathan Austin 1:8aa5cdb4ab67 363 {
Jonathan Austin 1:8aa5cdb4ab67 364 int toBuffIndex = 0;
Jonathan Austin 1:8aa5cdb4ab67 365
Jonathan Austin 1:8aa5cdb4ab67 366 while(tailPosition != headPosition)
Jonathan Austin 1:8aa5cdb4ab67 367 {
Jonathan Austin 1:8aa5cdb4ab67 368 linearBuff[toBuffIndex++] = circularBuff[tailPosition];
Jonathan Austin 1:8aa5cdb4ab67 369
Jonathan Austin 1:8aa5cdb4ab67 370 tailPosition = (tailPosition + 1) % circularBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 371 }
Jonathan Austin 1:8aa5cdb4ab67 372 }
Jonathan Austin 1:8aa5cdb4ab67 373
Jonathan Austin 1:8aa5cdb4ab67 374 /**
Jonathan Austin 1:8aa5cdb4ab67 375 * Sends a single character over the serial line.
Jonathan Austin 1:8aa5cdb4ab67 376 *
Jonathan Austin 1:8aa5cdb4ab67 377 * @param c the character to send
Jonathan Austin 1:8aa5cdb4ab67 378 *
Jonathan Austin 1:8aa5cdb4ab67 379 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 380 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 381 *
Jonathan Austin 1:8aa5cdb4ab67 382 * ASYNC - the character is copied into the txBuff and returns immediately.
Jonathan Austin 1:8aa5cdb4ab67 383 *
Jonathan Austin 1:8aa5cdb4ab67 384 * SYNC_SPINWAIT - the character is copied into the txBuff and this method
Jonathan Austin 1:8aa5cdb4ab67 385 * will spin (lock up the processor) until the character has
Jonathan Austin 1:8aa5cdb4ab67 386 * been sent.
Jonathan Austin 1:8aa5cdb4ab67 387 *
Jonathan Austin 1:8aa5cdb4ab67 388 * SYNC_SLEEP - the character is copied into the txBuff and the fiber sleeps
Jonathan Austin 1:8aa5cdb4ab67 389 * until the character has been sent. This allows other fibers
Jonathan Austin 1:8aa5cdb4ab67 390 * to continue execution.
Jonathan Austin 1:8aa5cdb4ab67 391 *
Jonathan Austin 1:8aa5cdb4ab67 392 * Defaults to SYNC_SLEEP.
Jonathan Austin 1:8aa5cdb4ab67 393 *
Jonathan Austin 1:8aa5cdb4ab67 394 * @return the number of bytes written, or MICROBIT_SERIAL_IN_USE if another fiber
Jonathan Austin 1:8aa5cdb4ab67 395 * is using the serial instance for transmission.
Jonathan Austin 1:8aa5cdb4ab67 396 */
Jonathan Austin 1:8aa5cdb4ab67 397 int MicroBitSerial::sendChar(char c, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 398 {
Jonathan Austin 1:8aa5cdb4ab67 399 if(txInUse())
Jonathan Austin 1:8aa5cdb4ab67 400 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 401
Jonathan Austin 1:8aa5cdb4ab67 402 lockTx();
Jonathan Austin 1:8aa5cdb4ab67 403
Jonathan Austin 1:8aa5cdb4ab67 404 //lazy initialisation of our tx buffer
Jonathan Austin 1:8aa5cdb4ab67 405 if(!(status & MICROBIT_SERIAL_TX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 406 {
Jonathan Austin 1:8aa5cdb4ab67 407 int result = initialiseTx();
Jonathan Austin 1:8aa5cdb4ab67 408
Jonathan Austin 1:8aa5cdb4ab67 409 if(result != MICROBIT_OK)
Jonathan Austin 1:8aa5cdb4ab67 410 return result;
Jonathan Austin 1:8aa5cdb4ab67 411 }
Jonathan Austin 1:8aa5cdb4ab67 412
Jonathan Austin 1:8aa5cdb4ab67 413 uint8_t toTransmit[2] = { c, '\0'};
Jonathan Austin 1:8aa5cdb4ab67 414
LancasterUniversity 25:27299423d813 415 int bytesWritten = setTxInterrupt(toTransmit, 1, mode);
Jonathan Austin 1:8aa5cdb4ab67 416
Jonathan Austin 1:8aa5cdb4ab67 417 send(mode);
Jonathan Austin 1:8aa5cdb4ab67 418
Jonathan Austin 1:8aa5cdb4ab67 419 unlockTx();
Jonathan Austin 1:8aa5cdb4ab67 420
Jonathan Austin 1:8aa5cdb4ab67 421 return bytesWritten;
Jonathan Austin 1:8aa5cdb4ab67 422 }
Jonathan Austin 1:8aa5cdb4ab67 423
Jonathan Austin 1:8aa5cdb4ab67 424 /**
Jonathan Austin 1:8aa5cdb4ab67 425 * Sends a ManagedString over the serial line.
Jonathan Austin 1:8aa5cdb4ab67 426 *
Jonathan Austin 1:8aa5cdb4ab67 427 * @param s the string to send
Jonathan Austin 1:8aa5cdb4ab67 428 *
Jonathan Austin 1:8aa5cdb4ab67 429 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 430 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 431 *
Jonathan Austin 1:8aa5cdb4ab67 432 * ASYNC - bytes are copied into the txBuff and returns immediately.
Jonathan Austin 1:8aa5cdb4ab67 433 *
Jonathan Austin 1:8aa5cdb4ab67 434 * SYNC_SPINWAIT - bytes are copied into the txBuff and this method
Jonathan Austin 1:8aa5cdb4ab67 435 * will spin (lock up the processor) until all bytes
Jonathan Austin 1:8aa5cdb4ab67 436 * have been sent.
Jonathan Austin 1:8aa5cdb4ab67 437 *
Jonathan Austin 1:8aa5cdb4ab67 438 * SYNC_SLEEP - bytes are copied into the txBuff and the fiber sleeps
Jonathan Austin 1:8aa5cdb4ab67 439 * until all bytes have been sent. This allows other fibers
Jonathan Austin 1:8aa5cdb4ab67 440 * to continue execution.
Jonathan Austin 1:8aa5cdb4ab67 441 *
Jonathan Austin 1:8aa5cdb4ab67 442 * Defaults to SYNC_SLEEP.
Jonathan Austin 1:8aa5cdb4ab67 443 *
LancasterUniversity 67:99cfde195ff3 444 * @return the number of bytes written, MICROBIT_SERIAL_IN_USE if another fiber
LancasterUniversity 67:99cfde195ff3 445 * is using the serial instance for transmission, MICROBIT_INVALID_PARAMETER
LancasterUniversity 67:99cfde195ff3 446 * if buffer is invalid, or the given bufferLen is <= 0.
Jonathan Austin 1:8aa5cdb4ab67 447 */
Jonathan Austin 1:8aa5cdb4ab67 448 int MicroBitSerial::send(ManagedString s, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 449 {
Jonathan Austin 1:8aa5cdb4ab67 450 return send((uint8_t *)s.toCharArray(), s.length(), mode);
Jonathan Austin 1:8aa5cdb4ab67 451 }
Jonathan Austin 1:8aa5cdb4ab67 452
Jonathan Austin 1:8aa5cdb4ab67 453 /**
Jonathan Austin 1:8aa5cdb4ab67 454 * Sends a buffer of known length over the serial line.
Jonathan Austin 1:8aa5cdb4ab67 455 *
Jonathan Austin 1:8aa5cdb4ab67 456 * @param buffer a pointer to the first character of the buffer
Jonathan Austin 1:8aa5cdb4ab67 457 *
Jonathan Austin 1:8aa5cdb4ab67 458 * @param len the number of bytes that are safely available to read.
Jonathan Austin 1:8aa5cdb4ab67 459 *
Jonathan Austin 1:8aa5cdb4ab67 460 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 461 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 462 *
Jonathan Austin 1:8aa5cdb4ab67 463 * ASYNC - bytes are copied into the txBuff and returns immediately.
Jonathan Austin 1:8aa5cdb4ab67 464 *
Jonathan Austin 1:8aa5cdb4ab67 465 * SYNC_SPINWAIT - bytes are copied into the txBuff and this method
Jonathan Austin 1:8aa5cdb4ab67 466 * will spin (lock up the processor) until all bytes
Jonathan Austin 1:8aa5cdb4ab67 467 * have been sent.
Jonathan Austin 1:8aa5cdb4ab67 468 *
Jonathan Austin 1:8aa5cdb4ab67 469 * SYNC_SLEEP - bytes are copied into the txBuff and the fiber sleeps
Jonathan Austin 1:8aa5cdb4ab67 470 * until all bytes have been sent. This allows other fibers
Jonathan Austin 1:8aa5cdb4ab67 471 * to continue execution.
Jonathan Austin 1:8aa5cdb4ab67 472 *
Jonathan Austin 1:8aa5cdb4ab67 473 * Defaults to SYNC_SLEEP.
Jonathan Austin 1:8aa5cdb4ab67 474 *
LancasterUniversity 67:99cfde195ff3 475 * @return the number of bytes written, MICROBIT_SERIAL_IN_USE if another fiber
LancasterUniversity 67:99cfde195ff3 476 * is using the serial instance for transmission, MICROBIT_INVALID_PARAMETER
LancasterUniversity 67:99cfde195ff3 477 * if buffer is invalid, or the given bufferLen is <= 0.
Jonathan Austin 1:8aa5cdb4ab67 478 */
Jonathan Austin 1:8aa5cdb4ab67 479 int MicroBitSerial::send(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 480 {
Jonathan Austin 1:8aa5cdb4ab67 481 if(txInUse())
Jonathan Austin 1:8aa5cdb4ab67 482 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 483
LancasterUniversity 67:99cfde195ff3 484 if(bufferLen <= 0 || buffer == NULL)
LancasterUniversity 67:99cfde195ff3 485 return MICROBIT_INVALID_PARAMETER;
LancasterUniversity 67:99cfde195ff3 486
Jonathan Austin 1:8aa5cdb4ab67 487 lockTx();
Jonathan Austin 1:8aa5cdb4ab67 488
Jonathan Austin 1:8aa5cdb4ab67 489 //lazy initialisation of our tx buffer
Jonathan Austin 1:8aa5cdb4ab67 490 if(!(status & MICROBIT_SERIAL_TX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 491 {
Jonathan Austin 1:8aa5cdb4ab67 492 int result = initialiseTx();
Jonathan Austin 1:8aa5cdb4ab67 493
Jonathan Austin 1:8aa5cdb4ab67 494 if(result != MICROBIT_OK)
Jonathan Austin 1:8aa5cdb4ab67 495 return result;
Jonathan Austin 1:8aa5cdb4ab67 496 }
Jonathan Austin 1:8aa5cdb4ab67 497
LancasterUniversity 46:c5bb7af0a3f0 498 bool complete = false;
LancasterUniversity 46:c5bb7af0a3f0 499 int bytesWritten = 0;
Jonathan Austin 1:8aa5cdb4ab67 500
LancasterUniversity 46:c5bb7af0a3f0 501 while(!complete)
LancasterUniversity 46:c5bb7af0a3f0 502 {
LancasterUniversity 46:c5bb7af0a3f0 503 bytesWritten += setTxInterrupt(buffer + bytesWritten, bufferLen - bytesWritten, mode);
LancasterUniversity 46:c5bb7af0a3f0 504 send(mode);
LancasterUniversity 46:c5bb7af0a3f0 505
LancasterUniversity 46:c5bb7af0a3f0 506 if(mode == ASYNC || bytesWritten >= bufferLen)
LancasterUniversity 46:c5bb7af0a3f0 507 complete = true;
LancasterUniversity 46:c5bb7af0a3f0 508 }
Jonathan Austin 1:8aa5cdb4ab67 509
Jonathan Austin 1:8aa5cdb4ab67 510 unlockTx();
Jonathan Austin 1:8aa5cdb4ab67 511
Jonathan Austin 1:8aa5cdb4ab67 512 return bytesWritten;
Jonathan Austin 1:8aa5cdb4ab67 513 }
Jonathan Austin 1:8aa5cdb4ab67 514
Jonathan Austin 1:8aa5cdb4ab67 515 /**
Jonathan Austin 1:8aa5cdb4ab67 516 * Reads a single character from the rxBuff
Jonathan Austin 1:8aa5cdb4ab67 517 *
Jonathan Austin 1:8aa5cdb4ab67 518 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 519 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 520 *
Jonathan Austin 1:8aa5cdb4ab67 521 * ASYNC - A character is read from the rxBuff if available, if there
Jonathan Austin 1:8aa5cdb4ab67 522 * are no characters to be read, a value of MICROBIT_NO_DATA is returned immediately.
Jonathan Austin 1:8aa5cdb4ab67 523 *
Jonathan Austin 1:8aa5cdb4ab67 524 * SYNC_SPINWAIT - A character is read from the rxBuff if available, if there
Jonathan Austin 1:8aa5cdb4ab67 525 * are no characters to be read, this method will spin
Jonathan Austin 1:8aa5cdb4ab67 526 * (lock up the processor) until a character is available.
Jonathan Austin 1:8aa5cdb4ab67 527 *
Jonathan Austin 1:8aa5cdb4ab67 528 * SYNC_SLEEP - A character is read from the rxBuff if available, if there
Jonathan Austin 1:8aa5cdb4ab67 529 * are no characters to be read, the calling fiber sleeps
Jonathan Austin 1:8aa5cdb4ab67 530 * until there is a character available.
Jonathan Austin 1:8aa5cdb4ab67 531 *
Jonathan Austin 1:8aa5cdb4ab67 532 * Defaults to SYNC_SLEEP.
Jonathan Austin 1:8aa5cdb4ab67 533 *
Jonathan Austin 1:8aa5cdb4ab67 534 * @return a character, MICROBIT_SERIAL_IN_USE if another fiber is using the serial instance for reception,
Jonathan Austin 1:8aa5cdb4ab67 535 * MICROBIT_NO_RESOURCES if buffer allocation did not complete successfully, or MICROBIT_NO_DATA if
Jonathan Austin 1:8aa5cdb4ab67 536 * the rx buffer is empty and the mode given is ASYNC.
Jonathan Austin 1:8aa5cdb4ab67 537 */
Jonathan Austin 1:8aa5cdb4ab67 538 int MicroBitSerial::read(MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 539 {
Jonathan Austin 1:8aa5cdb4ab67 540 if(rxInUse())
Jonathan Austin 1:8aa5cdb4ab67 541 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 542
Jonathan Austin 1:8aa5cdb4ab67 543 lockRx();
Jonathan Austin 1:8aa5cdb4ab67 544
Jonathan Austin 1:8aa5cdb4ab67 545 //lazy initialisation of our buffers
Jonathan Austin 1:8aa5cdb4ab67 546 if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 547 {
Jonathan Austin 1:8aa5cdb4ab67 548 int result = initialiseRx();
Jonathan Austin 1:8aa5cdb4ab67 549
Jonathan Austin 1:8aa5cdb4ab67 550 if(result != MICROBIT_OK)
Jonathan Austin 1:8aa5cdb4ab67 551 return result;
Jonathan Austin 1:8aa5cdb4ab67 552 }
Jonathan Austin 1:8aa5cdb4ab67 553
LancasterUniversity 66:2fc7d7c2fffc 554 int c = getChar(mode);
Jonathan Austin 1:8aa5cdb4ab67 555
Jonathan Austin 1:8aa5cdb4ab67 556 unlockRx();
Jonathan Austin 1:8aa5cdb4ab67 557
Jonathan Austin 1:8aa5cdb4ab67 558 return c;
Jonathan Austin 1:8aa5cdb4ab67 559 }
Jonathan Austin 1:8aa5cdb4ab67 560
Jonathan Austin 1:8aa5cdb4ab67 561 /**
Jonathan Austin 1:8aa5cdb4ab67 562 * Reads multiple characters from the rxBuff and returns them as a ManagedString
Jonathan Austin 1:8aa5cdb4ab67 563 *
Jonathan Austin 1:8aa5cdb4ab67 564 * @param size the number of characters to read.
Jonathan Austin 1:8aa5cdb4ab67 565 *
Jonathan Austin 1:8aa5cdb4ab67 566 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 567 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 568 *
Jonathan Austin 1:8aa5cdb4ab67 569 * ASYNC - If the desired number of characters are available, this will return
Jonathan Austin 1:8aa5cdb4ab67 570 * a ManagedString with the expected size. Otherwise, it will read however
Jonathan Austin 1:8aa5cdb4ab67 571 * many characters there are available.
Jonathan Austin 1:8aa5cdb4ab67 572 *
Jonathan Austin 1:8aa5cdb4ab67 573 * SYNC_SPINWAIT - If the desired number of characters are available, this will return
Jonathan Austin 1:8aa5cdb4ab67 574 * a ManagedString with the expected size. Otherwise, this method will spin
Jonathan Austin 1:8aa5cdb4ab67 575 * (lock up the processor) until the desired number of characters have been read.
Jonathan Austin 1:8aa5cdb4ab67 576 *
Jonathan Austin 1:8aa5cdb4ab67 577 * SYNC_SLEEP - If the desired number of characters are available, this will return
Jonathan Austin 1:8aa5cdb4ab67 578 * a ManagedString with the expected size. Otherwise, the calling fiber sleeps
Jonathan Austin 1:8aa5cdb4ab67 579 * until the desired number of characters have been read.
Jonathan Austin 1:8aa5cdb4ab67 580 *
Jonathan Austin 1:8aa5cdb4ab67 581 * Defaults to SYNC_SLEEP.
Jonathan Austin 1:8aa5cdb4ab67 582 *
Jonathan Austin 1:8aa5cdb4ab67 583 * @return A ManagedString, or an empty ManagedString if an error was encountered during the read.
Jonathan Austin 1:8aa5cdb4ab67 584 */
Jonathan Austin 1:8aa5cdb4ab67 585 ManagedString MicroBitSerial::read(int size, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 586 {
LancasterUniversity 3:d86a4ddc1867 587 uint8_t buff[size + 1];
Jonathan Austin 1:8aa5cdb4ab67 588
LancasterUniversity 8:ec4465853952 589 memclr(&buff, size + 1);
LancasterUniversity 8:ec4465853952 590
Jonathan Austin 1:8aa5cdb4ab67 591 int returnedSize = read((uint8_t *)buff, size, mode);
Jonathan Austin 1:8aa5cdb4ab67 592
Jonathan Austin 1:8aa5cdb4ab67 593 if(returnedSize <= 0)
Jonathan Austin 1:8aa5cdb4ab67 594 return ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 595
Jonathan Austin 1:8aa5cdb4ab67 596 return ManagedString((char *)buff, returnedSize);
Jonathan Austin 1:8aa5cdb4ab67 597 }
Jonathan Austin 1:8aa5cdb4ab67 598
Jonathan Austin 1:8aa5cdb4ab67 599 /**
Jonathan Austin 1:8aa5cdb4ab67 600 * Reads multiple characters from the rxBuff and fills a user buffer.
Jonathan Austin 1:8aa5cdb4ab67 601 *
Jonathan Austin 1:8aa5cdb4ab67 602 * @param buffer a pointer to a user allocated buffer.
Jonathan Austin 1:8aa5cdb4ab67 603 *
Jonathan Austin 1:8aa5cdb4ab67 604 * @param bufferLen the amount of data that can be safely stored
Jonathan Austin 1:8aa5cdb4ab67 605 *
Jonathan Austin 1:8aa5cdb4ab67 606 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 607 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 608 *
Jonathan Austin 1:8aa5cdb4ab67 609 * ASYNC - If the desired number of characters are available, this will fill
Jonathan Austin 1:8aa5cdb4ab67 610 * the given buffer. Otherwise, it will fill the buffer with however
Jonathan Austin 1:8aa5cdb4ab67 611 * many characters there are available.
Jonathan Austin 1:8aa5cdb4ab67 612 *
Jonathan Austin 1:8aa5cdb4ab67 613 * SYNC_SPINWAIT - If the desired number of characters are available, this will fill
Jonathan Austin 1:8aa5cdb4ab67 614 * the given buffer. Otherwise, this method will spin (lock up the processor)
Jonathan Austin 1:8aa5cdb4ab67 615 * and fill the buffer until the desired number of characters have been read.
Jonathan Austin 1:8aa5cdb4ab67 616 *
Jonathan Austin 1:8aa5cdb4ab67 617 * SYNC_SLEEP - If the desired number of characters are available, this will fill
Jonathan Austin 1:8aa5cdb4ab67 618 * the given buffer. Otherwise, the calling fiber sleeps
Jonathan Austin 1:8aa5cdb4ab67 619 * until the desired number of characters have been read.
Jonathan Austin 1:8aa5cdb4ab67 620 *
Jonathan Austin 1:8aa5cdb4ab67 621 * Defaults to SYNC_SLEEP.
Jonathan Austin 1:8aa5cdb4ab67 622 *
Jonathan Austin 1:8aa5cdb4ab67 623 * @return the number of characters read, or MICROBIT_SERIAL_IN_USE if another fiber
Jonathan Austin 1:8aa5cdb4ab67 624 * is using the instance for receiving.
Jonathan Austin 1:8aa5cdb4ab67 625 */
Jonathan Austin 1:8aa5cdb4ab67 626 int MicroBitSerial::read(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 627 {
Jonathan Austin 1:8aa5cdb4ab67 628 if(rxInUse())
Jonathan Austin 1:8aa5cdb4ab67 629 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 630
Jonathan Austin 1:8aa5cdb4ab67 631 lockRx();
Jonathan Austin 1:8aa5cdb4ab67 632
Jonathan Austin 1:8aa5cdb4ab67 633 //lazy initialisation of our rx buffer
Jonathan Austin 1:8aa5cdb4ab67 634 if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 635 {
Jonathan Austin 1:8aa5cdb4ab67 636 int result = initialiseRx();
Jonathan Austin 1:8aa5cdb4ab67 637
Jonathan Austin 1:8aa5cdb4ab67 638 if(result != MICROBIT_OK)
Jonathan Austin 1:8aa5cdb4ab67 639 return result;
Jonathan Austin 1:8aa5cdb4ab67 640 }
Jonathan Austin 1:8aa5cdb4ab67 641
Jonathan Austin 1:8aa5cdb4ab67 642 int bufferIndex = 0;
Jonathan Austin 1:8aa5cdb4ab67 643
Jonathan Austin 1:8aa5cdb4ab67 644 int temp = 0;
Jonathan Austin 1:8aa5cdb4ab67 645
Jonathan Austin 1:8aa5cdb4ab67 646 if(mode == ASYNC)
Jonathan Austin 1:8aa5cdb4ab67 647 {
Jonathan Austin 1:8aa5cdb4ab67 648 while((temp = getChar(mode)) != MICROBIT_NO_DATA && bufferIndex < bufferLen)
Jonathan Austin 1:8aa5cdb4ab67 649 {
Jonathan Austin 1:8aa5cdb4ab67 650 buffer[bufferIndex] = (char)temp;
Jonathan Austin 1:8aa5cdb4ab67 651 bufferIndex++;
Jonathan Austin 1:8aa5cdb4ab67 652 }
Jonathan Austin 1:8aa5cdb4ab67 653 }
Jonathan Austin 1:8aa5cdb4ab67 654
Jonathan Austin 1:8aa5cdb4ab67 655 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 656 {
Jonathan Austin 1:8aa5cdb4ab67 657 while(bufferIndex < bufferLen)
Jonathan Austin 1:8aa5cdb4ab67 658 {
Jonathan Austin 1:8aa5cdb4ab67 659 buffer[bufferIndex] = (char)getChar(mode);
Jonathan Austin 1:8aa5cdb4ab67 660 bufferIndex++;
Jonathan Austin 1:8aa5cdb4ab67 661 }
Jonathan Austin 1:8aa5cdb4ab67 662 }
Jonathan Austin 1:8aa5cdb4ab67 663
Jonathan Austin 1:8aa5cdb4ab67 664 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 665 {
Jonathan Austin 1:8aa5cdb4ab67 666 if(bufferLen > rxBufferedSize())
Jonathan Austin 1:8aa5cdb4ab67 667 eventAfter(bufferLen - rxBufferedSize(), mode);
Jonathan Austin 1:8aa5cdb4ab67 668
Jonathan Austin 1:8aa5cdb4ab67 669 while(bufferIndex < bufferLen)
Jonathan Austin 1:8aa5cdb4ab67 670 {
Jonathan Austin 1:8aa5cdb4ab67 671 buffer[bufferIndex] = (char)getChar(mode);
Jonathan Austin 1:8aa5cdb4ab67 672 bufferIndex++;
Jonathan Austin 1:8aa5cdb4ab67 673 }
Jonathan Austin 1:8aa5cdb4ab67 674 }
Jonathan Austin 1:8aa5cdb4ab67 675
Jonathan Austin 1:8aa5cdb4ab67 676 unlockRx();
Jonathan Austin 1:8aa5cdb4ab67 677
Jonathan Austin 1:8aa5cdb4ab67 678 return bufferIndex;
Jonathan Austin 1:8aa5cdb4ab67 679 }
Jonathan Austin 1:8aa5cdb4ab67 680
Jonathan Austin 1:8aa5cdb4ab67 681
Jonathan Austin 1:8aa5cdb4ab67 682 /**
Jonathan Austin 1:8aa5cdb4ab67 683 * Reads until one of the delimeters matches a character in the rxBuff
Jonathan Austin 1:8aa5cdb4ab67 684 *
Jonathan Austin 1:8aa5cdb4ab67 685 * @param delimeters a ManagedString containing a sequence of delimeter characters e.g. ManagedString("\r\n")
Jonathan Austin 1:8aa5cdb4ab67 686 *
Jonathan Austin 1:8aa5cdb4ab67 687 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 688 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 689 *
Jonathan Austin 1:8aa5cdb4ab67 690 * ASYNC - If one of the delimeters matches a character already in the rxBuff
Jonathan Austin 1:8aa5cdb4ab67 691 * this method will return a ManagedString up to the delimeter.
Jonathan Austin 1:8aa5cdb4ab67 692 * Otherwise, it will return an Empty ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 693 *
Jonathan Austin 1:8aa5cdb4ab67 694 * SYNC_SPINWAIT - If one of the delimeters matches a character already in the rxBuff
Jonathan Austin 1:8aa5cdb4ab67 695 * this method will return a ManagedString up to the delimeter.
Jonathan Austin 1:8aa5cdb4ab67 696 * Otherwise, this method will spin (lock up the processor) until a
Jonathan Austin 1:8aa5cdb4ab67 697 * received character matches one of the delimeters.
Jonathan Austin 1:8aa5cdb4ab67 698 *
Jonathan Austin 1:8aa5cdb4ab67 699 * SYNC_SLEEP - If one of the delimeters matches a character already in the rxBuff
Jonathan Austin 1:8aa5cdb4ab67 700 * this method will return a ManagedString up to the delimeter.
Jonathan Austin 1:8aa5cdb4ab67 701 * Otherwise, the calling fiber sleeps until a character matching one
Jonathan Austin 1:8aa5cdb4ab67 702 * of the delimeters is seen.
Jonathan Austin 1:8aa5cdb4ab67 703 *
Jonathan Austin 1:8aa5cdb4ab67 704 * Defaults to SYNC_SLEEP.
Jonathan Austin 1:8aa5cdb4ab67 705 *
Jonathan Austin 1:8aa5cdb4ab67 706 * @return A ManagedString containing the characters up to a delimeter, or an Empty ManagedString,
Jonathan Austin 1:8aa5cdb4ab67 707 * if another fiber is currently using this instance for reception.
Jonathan Austin 1:8aa5cdb4ab67 708 *
Jonathan Austin 1:8aa5cdb4ab67 709 * @note delimeters are matched on a per byte basis.
Jonathan Austin 1:8aa5cdb4ab67 710 */
Jonathan Austin 1:8aa5cdb4ab67 711 ManagedString MicroBitSerial::readUntil(ManagedString delimeters, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 712 {
Jonathan Austin 1:8aa5cdb4ab67 713
Jonathan Austin 1:8aa5cdb4ab67 714 if(rxInUse())
Jonathan Austin 1:8aa5cdb4ab67 715 return ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 716
Jonathan Austin 1:8aa5cdb4ab67 717 //lazy initialisation of our rx buffer
Jonathan Austin 1:8aa5cdb4ab67 718 if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT))
Jonathan Austin 1:8aa5cdb4ab67 719 {
Jonathan Austin 1:8aa5cdb4ab67 720 int result = initialiseRx();
Jonathan Austin 1:8aa5cdb4ab67 721
Jonathan Austin 1:8aa5cdb4ab67 722 if(result != MICROBIT_OK)
Jonathan Austin 1:8aa5cdb4ab67 723 return result;
Jonathan Austin 1:8aa5cdb4ab67 724 }
Jonathan Austin 1:8aa5cdb4ab67 725
Jonathan Austin 1:8aa5cdb4ab67 726 lockRx();
Jonathan Austin 1:8aa5cdb4ab67 727
Jonathan Austin 1:8aa5cdb4ab67 728 int localTail = rxBuffTail;
Jonathan Austin 1:8aa5cdb4ab67 729 int preservedTail = rxBuffTail;
Jonathan Austin 1:8aa5cdb4ab67 730
Jonathan Austin 1:8aa5cdb4ab67 731 int foundIndex = -1;
Jonathan Austin 1:8aa5cdb4ab67 732
Jonathan Austin 1:8aa5cdb4ab67 733 //ASYNC mode just iterates through our stored characters checking for any matches.
Jonathan Austin 1:8aa5cdb4ab67 734 while(localTail != rxBuffHead && foundIndex == -1)
Jonathan Austin 1:8aa5cdb4ab67 735 {
Jonathan Austin 1:8aa5cdb4ab67 736 //we use localTail to prevent modification of the actual tail.
Jonathan Austin 1:8aa5cdb4ab67 737 char c = rxBuff[localTail];
Jonathan Austin 1:8aa5cdb4ab67 738
Jonathan Austin 1:8aa5cdb4ab67 739 for(int delimeterIterator = 0; delimeterIterator < delimeters.length(); delimeterIterator++)
Jonathan Austin 1:8aa5cdb4ab67 740 if(delimeters.charAt(delimeterIterator) == c)
Jonathan Austin 1:8aa5cdb4ab67 741 foundIndex = localTail;
Jonathan Austin 1:8aa5cdb4ab67 742
Jonathan Austin 1:8aa5cdb4ab67 743 localTail = (localTail + 1) % rxBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 744 }
Jonathan Austin 1:8aa5cdb4ab67 745
Jonathan Austin 1:8aa5cdb4ab67 746 //if our mode is SYNC_SPINWAIT and we didn't see any matching characters in our buffer
Jonathan Austin 1:8aa5cdb4ab67 747 //spin until we find a match!
Jonathan Austin 1:8aa5cdb4ab67 748 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 749 {
Jonathan Austin 1:8aa5cdb4ab67 750 while(foundIndex == -1)
Jonathan Austin 1:8aa5cdb4ab67 751 {
Jonathan Austin 1:8aa5cdb4ab67 752 while(localTail == rxBuffHead);
Jonathan Austin 1:8aa5cdb4ab67 753
Jonathan Austin 1:8aa5cdb4ab67 754 char c = rxBuff[localTail];
Jonathan Austin 1:8aa5cdb4ab67 755
Jonathan Austin 1:8aa5cdb4ab67 756 for(int delimeterIterator = 0; delimeterIterator < delimeters.length(); delimeterIterator++)
Jonathan Austin 1:8aa5cdb4ab67 757 if(delimeters.charAt(delimeterIterator) == c)
Jonathan Austin 1:8aa5cdb4ab67 758 foundIndex = localTail;
Jonathan Austin 1:8aa5cdb4ab67 759
Jonathan Austin 1:8aa5cdb4ab67 760 localTail = (localTail + 1) % rxBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 761 }
Jonathan Austin 1:8aa5cdb4ab67 762 }
Jonathan Austin 1:8aa5cdb4ab67 763
Jonathan Austin 1:8aa5cdb4ab67 764 //if our mode is SYNC_SLEEP, we set up an event to be fired when we see a
Jonathan Austin 1:8aa5cdb4ab67 765 //matching character.
Jonathan Austin 1:8aa5cdb4ab67 766 if(mode == SYNC_SLEEP && foundIndex == -1)
Jonathan Austin 1:8aa5cdb4ab67 767 {
Jonathan Austin 1:8aa5cdb4ab67 768 eventOn(delimeters, mode);
Jonathan Austin 1:8aa5cdb4ab67 769
Jonathan Austin 1:8aa5cdb4ab67 770 foundIndex = rxBuffHead - 1;
Jonathan Austin 1:8aa5cdb4ab67 771
Jonathan Austin 1:8aa5cdb4ab67 772 this->delimeters = ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 773 }
Jonathan Austin 1:8aa5cdb4ab67 774
Jonathan Austin 1:8aa5cdb4ab67 775 if(foundIndex >= 0)
Jonathan Austin 1:8aa5cdb4ab67 776 {
Jonathan Austin 1:8aa5cdb4ab67 777 //calculate our local buffer size
Jonathan Austin 1:8aa5cdb4ab67 778 int localBuffSize = (preservedTail > foundIndex) ? (rxBuffSize - preservedTail) + foundIndex : foundIndex - preservedTail;
Jonathan Austin 1:8aa5cdb4ab67 779
LancasterUniversity 3:d86a4ddc1867 780 uint8_t localBuff[localBuffSize + 1];
Jonathan Austin 1:8aa5cdb4ab67 781
LancasterUniversity 8:ec4465853952 782 memclr(&localBuff, localBuffSize + 1);
LancasterUniversity 8:ec4465853952 783
Jonathan Austin 1:8aa5cdb4ab67 784 circularCopy(rxBuff, rxBuffSize, localBuff, preservedTail, foundIndex);
Jonathan Austin 1:8aa5cdb4ab67 785
Jonathan Austin 1:8aa5cdb4ab67 786 //plus one for the character we listened for...
Jonathan Austin 1:8aa5cdb4ab67 787 rxBuffTail = (rxBuffTail + localBuffSize + 1) % rxBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 788
Jonathan Austin 1:8aa5cdb4ab67 789 unlockRx();
Jonathan Austin 1:8aa5cdb4ab67 790
Jonathan Austin 1:8aa5cdb4ab67 791 return ManagedString((char *)localBuff, localBuffSize);
Jonathan Austin 1:8aa5cdb4ab67 792 }
Jonathan Austin 1:8aa5cdb4ab67 793
Jonathan Austin 1:8aa5cdb4ab67 794 unlockRx();
Jonathan Austin 1:8aa5cdb4ab67 795
Jonathan Austin 1:8aa5cdb4ab67 796 return ManagedString();
Jonathan Austin 1:8aa5cdb4ab67 797 }
Jonathan Austin 1:8aa5cdb4ab67 798
Jonathan Austin 1:8aa5cdb4ab67 799 /**
Jonathan Austin 1:8aa5cdb4ab67 800 * A wrapper around the inherited method "baud" so we can trap the baud rate
Jonathan Austin 1:8aa5cdb4ab67 801 * as it changes and restore it if redirect() is called.
Jonathan Austin 1:8aa5cdb4ab67 802 *
Jonathan Austin 1:8aa5cdb4ab67 803 * @param baudrate the new baudrate. See:
Jonathan Austin 1:8aa5cdb4ab67 804 * - https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c
Jonathan Austin 1:8aa5cdb4ab67 805 * for permitted baud rates.
Jonathan Austin 1:8aa5cdb4ab67 806 *
Jonathan Austin 1:8aa5cdb4ab67 807 * @return MICROBIT_INVALID_PARAMETER if baud rate is less than 0, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 808 *
Jonathan Austin 1:8aa5cdb4ab67 809 * @note the underlying implementation chooses the first allowable rate at or above that requested.
Jonathan Austin 1:8aa5cdb4ab67 810 */
Jonathan Austin 1:8aa5cdb4ab67 811 void MicroBitSerial::baud(int baudrate)
Jonathan Austin 1:8aa5cdb4ab67 812 {
Jonathan Austin 1:8aa5cdb4ab67 813 if(baudrate < 0)
Jonathan Austin 1:8aa5cdb4ab67 814 return;
Jonathan Austin 1:8aa5cdb4ab67 815
Jonathan Austin 1:8aa5cdb4ab67 816 this->baudrate = baudrate;
Jonathan Austin 1:8aa5cdb4ab67 817
Jonathan Austin 1:8aa5cdb4ab67 818 RawSerial::baud(baudrate);
Jonathan Austin 1:8aa5cdb4ab67 819 }
Jonathan Austin 1:8aa5cdb4ab67 820
Jonathan Austin 1:8aa5cdb4ab67 821 /**
Jonathan Austin 1:8aa5cdb4ab67 822 * A way of dynamically configuring the serial instance to use pins other than USBTX and USBRX.
Jonathan Austin 1:8aa5cdb4ab67 823 *
Jonathan Austin 1:8aa5cdb4ab67 824 * @param tx the new transmission pin.
Jonathan Austin 1:8aa5cdb4ab67 825 *
Jonathan Austin 1:8aa5cdb4ab67 826 * @param rx the new reception pin.
Jonathan Austin 1:8aa5cdb4ab67 827 *
Jonathan Austin 1:8aa5cdb4ab67 828 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently transmitting or receiving, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 829 */
Jonathan Austin 1:8aa5cdb4ab67 830 int MicroBitSerial::redirect(PinName tx, PinName rx)
Jonathan Austin 1:8aa5cdb4ab67 831 {
Jonathan Austin 1:8aa5cdb4ab67 832 if(txInUse() || rxInUse())
Jonathan Austin 1:8aa5cdb4ab67 833 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 834
Jonathan Austin 1:8aa5cdb4ab67 835 lockTx();
Jonathan Austin 1:8aa5cdb4ab67 836 lockRx();
Jonathan Austin 1:8aa5cdb4ab67 837
Jonathan Austin 1:8aa5cdb4ab67 838 if(txBufferedSize() > 0)
LancasterUniversity 6:2e1c2e0d8c7a 839 detach(Serial::TxIrq);
Jonathan Austin 1:8aa5cdb4ab67 840
LancasterUniversity 6:2e1c2e0d8c7a 841 detach(Serial::RxIrq);
Jonathan Austin 1:8aa5cdb4ab67 842
Jonathan Austin 1:8aa5cdb4ab67 843 serial_init(&_serial, tx, rx);
Jonathan Austin 1:8aa5cdb4ab67 844
LancasterUniversity 6:2e1c2e0d8c7a 845 attach(this, &MicroBitSerial::dataReceived, Serial::RxIrq);
Jonathan Austin 1:8aa5cdb4ab67 846
Jonathan Austin 1:8aa5cdb4ab67 847 if(txBufferedSize() > 0)
LancasterUniversity 6:2e1c2e0d8c7a 848 attach(this, &MicroBitSerial::dataWritten, Serial::TxIrq);
Jonathan Austin 1:8aa5cdb4ab67 849
Jonathan Austin 1:8aa5cdb4ab67 850 this->baud(this->baudrate);
Jonathan Austin 1:8aa5cdb4ab67 851
Jonathan Austin 1:8aa5cdb4ab67 852 unlockRx();
Jonathan Austin 1:8aa5cdb4ab67 853 unlockTx();
Jonathan Austin 1:8aa5cdb4ab67 854
Jonathan Austin 1:8aa5cdb4ab67 855 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 856 }
Jonathan Austin 1:8aa5cdb4ab67 857
Jonathan Austin 1:8aa5cdb4ab67 858 /**
Jonathan Austin 1:8aa5cdb4ab67 859 * Configures an event to be fired after "len" characters.
Jonathan Austin 1:8aa5cdb4ab67 860 *
LancasterUniversity 66:2fc7d7c2fffc 861 * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_HEAD_MATCH.
LancasterUniversity 66:2fc7d7c2fffc 862 *
Jonathan Austin 1:8aa5cdb4ab67 863 * @param len the number of characters to wait before triggering the event.
Jonathan Austin 1:8aa5cdb4ab67 864 *
Jonathan Austin 1:8aa5cdb4ab67 865 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 866 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 867 *
Jonathan Austin 1:8aa5cdb4ab67 868 * ASYNC - Will configure the event and return immediately.
Jonathan Austin 1:8aa5cdb4ab67 869 *
Jonathan Austin 1:8aa5cdb4ab67 870 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 871 *
Jonathan Austin 1:8aa5cdb4ab67 872 * SYNC_SLEEP - Will configure the event and block the current fiber until the
Jonathan Austin 1:8aa5cdb4ab67 873 * event is received.
Jonathan Austin 1:8aa5cdb4ab67 874 *
Jonathan Austin 1:8aa5cdb4ab67 875 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 876 */
Jonathan Austin 1:8aa5cdb4ab67 877 int MicroBitSerial::eventAfter(int len, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 878 {
Jonathan Austin 1:8aa5cdb4ab67 879 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 880 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 881
Jonathan Austin 1:8aa5cdb4ab67 882 //configure our head match...
Jonathan Austin 1:8aa5cdb4ab67 883 this->rxBuffHeadMatch = (rxBuffHead + len) % rxBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 884
Jonathan Austin 1:8aa5cdb4ab67 885 //block!
Jonathan Austin 1:8aa5cdb4ab67 886 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 887 fiber_wait_for_event(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_HEAD_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 888
Jonathan Austin 1:8aa5cdb4ab67 889 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 890 }
Jonathan Austin 1:8aa5cdb4ab67 891
Jonathan Austin 1:8aa5cdb4ab67 892 /**
Jonathan Austin 1:8aa5cdb4ab67 893 * Configures an event to be fired on a match with one of the delimeters.
Jonathan Austin 1:8aa5cdb4ab67 894 *
LancasterUniversity 66:2fc7d7c2fffc 895 * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_DELIM_MATCH.
LancasterUniversity 66:2fc7d7c2fffc 896 *
LancasterUniversity 66:2fc7d7c2fffc 897 * @param delimeters the characters to match received characters against e.g. ManagedString("\n")
Jonathan Austin 1:8aa5cdb4ab67 898 *
Jonathan Austin 1:8aa5cdb4ab67 899 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
Jonathan Austin 1:8aa5cdb4ab67 900 * gives a different behaviour:
Jonathan Austin 1:8aa5cdb4ab67 901 *
Jonathan Austin 1:8aa5cdb4ab67 902 * ASYNC - Will configure the event and return immediately.
Jonathan Austin 1:8aa5cdb4ab67 903 *
Jonathan Austin 1:8aa5cdb4ab67 904 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 905 *
Jonathan Austin 1:8aa5cdb4ab67 906 * SYNC_SLEEP - Will configure the event and block the current fiber until the
Jonathan Austin 1:8aa5cdb4ab67 907 * event is received.
Jonathan Austin 1:8aa5cdb4ab67 908 *
Jonathan Austin 1:8aa5cdb4ab67 909 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 910 *
Jonathan Austin 1:8aa5cdb4ab67 911 * @note delimeters are matched on a per byte basis.
Jonathan Austin 1:8aa5cdb4ab67 912 */
Jonathan Austin 1:8aa5cdb4ab67 913 int MicroBitSerial::eventOn(ManagedString delimeters, MicroBitSerialMode mode)
Jonathan Austin 1:8aa5cdb4ab67 914 {
Jonathan Austin 1:8aa5cdb4ab67 915 if(mode == SYNC_SPINWAIT)
Jonathan Austin 1:8aa5cdb4ab67 916 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 917
Jonathan Austin 1:8aa5cdb4ab67 918 //configure our head match...
Jonathan Austin 1:8aa5cdb4ab67 919 this->delimeters = delimeters;
Jonathan Austin 1:8aa5cdb4ab67 920
Jonathan Austin 1:8aa5cdb4ab67 921 //block!
Jonathan Austin 1:8aa5cdb4ab67 922 if(mode == SYNC_SLEEP)
Jonathan Austin 1:8aa5cdb4ab67 923 fiber_wait_for_event(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_DELIM_MATCH);
Jonathan Austin 1:8aa5cdb4ab67 924
Jonathan Austin 1:8aa5cdb4ab67 925 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 926 }
Jonathan Austin 1:8aa5cdb4ab67 927
Jonathan Austin 1:8aa5cdb4ab67 928 /**
Jonathan Austin 1:8aa5cdb4ab67 929 * Determines whether there is any data waiting in our Rx buffer.
Jonathan Austin 1:8aa5cdb4ab67 930 *
Jonathan Austin 1:8aa5cdb4ab67 931 * @return 1 if we have space, 0 if we do not.
Jonathan Austin 1:8aa5cdb4ab67 932 *
Jonathan Austin 1:8aa5cdb4ab67 933 * @note We do not wrap the super's readable() method as we don't want to
Jonathan Austin 1:8aa5cdb4ab67 934 * interfere with communities that use manual calls to serial.readable().
Jonathan Austin 1:8aa5cdb4ab67 935 */
Jonathan Austin 1:8aa5cdb4ab67 936 int MicroBitSerial::isReadable()
Jonathan Austin 1:8aa5cdb4ab67 937 {
Jonathan Austin 1:8aa5cdb4ab67 938 return (rxBuffTail != rxBuffHead) ? 1 : 0;
Jonathan Austin 1:8aa5cdb4ab67 939 }
Jonathan Austin 1:8aa5cdb4ab67 940
Jonathan Austin 1:8aa5cdb4ab67 941 /**
Jonathan Austin 1:8aa5cdb4ab67 942 * Determines if we have space in our txBuff.
Jonathan Austin 1:8aa5cdb4ab67 943 *
Jonathan Austin 1:8aa5cdb4ab67 944 * @return 1 if we have space, 0 if we do not.
Jonathan Austin 1:8aa5cdb4ab67 945 *
Jonathan Austin 1:8aa5cdb4ab67 946 * @note We do not wrap the super's writeable() method as we don't want to
Jonathan Austin 1:8aa5cdb4ab67 947 * interfere with communities that use manual calls to serial.writeable().
Jonathan Austin 1:8aa5cdb4ab67 948 */
Jonathan Austin 1:8aa5cdb4ab67 949 int MicroBitSerial::isWriteable()
Jonathan Austin 1:8aa5cdb4ab67 950 {
Jonathan Austin 1:8aa5cdb4ab67 951 return (txBuffHead != (txBuffTail - 1)) ? 1 : 0;
Jonathan Austin 1:8aa5cdb4ab67 952 }
Jonathan Austin 1:8aa5cdb4ab67 953
Jonathan Austin 1:8aa5cdb4ab67 954 /**
Jonathan Austin 1:8aa5cdb4ab67 955 * Reconfigures the size of our rxBuff
Jonathan Austin 1:8aa5cdb4ab67 956 *
Jonathan Austin 1:8aa5cdb4ab67 957 * @param size the new size for our rxBuff
Jonathan Austin 1:8aa5cdb4ab67 958 *
Jonathan Austin 1:8aa5cdb4ab67 959 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
Jonathan Austin 1:8aa5cdb4ab67 960 * for reception, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 961 */
Jonathan Austin 1:8aa5cdb4ab67 962 int MicroBitSerial::setRxBufferSize(uint8_t size)
Jonathan Austin 1:8aa5cdb4ab67 963 {
Jonathan Austin 1:8aa5cdb4ab67 964 if(rxInUse())
Jonathan Austin 1:8aa5cdb4ab67 965 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 966
Jonathan Austin 1:8aa5cdb4ab67 967 lockRx();
Jonathan Austin 1:8aa5cdb4ab67 968
LancasterUniversity 66:2fc7d7c2fffc 969 // + 1 so there is a usable buffer size, of the size the user requested.
LancasterUniversity 66:2fc7d7c2fffc 970 this->rxBuffSize = size + 1;
Jonathan Austin 1:8aa5cdb4ab67 971
Jonathan Austin 1:8aa5cdb4ab67 972 int result = initialiseRx();
Jonathan Austin 1:8aa5cdb4ab67 973
Jonathan Austin 1:8aa5cdb4ab67 974 unlockRx();
Jonathan Austin 1:8aa5cdb4ab67 975
Jonathan Austin 1:8aa5cdb4ab67 976 return result;
Jonathan Austin 1:8aa5cdb4ab67 977 }
Jonathan Austin 1:8aa5cdb4ab67 978
Jonathan Austin 1:8aa5cdb4ab67 979 /**
Jonathan Austin 1:8aa5cdb4ab67 980 * Reconfigures the size of our txBuff
Jonathan Austin 1:8aa5cdb4ab67 981 *
Jonathan Austin 1:8aa5cdb4ab67 982 * @param size the new size for our txBuff
Jonathan Austin 1:8aa5cdb4ab67 983 *
Jonathan Austin 1:8aa5cdb4ab67 984 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
Jonathan Austin 1:8aa5cdb4ab67 985 * for transmission, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 986 */
Jonathan Austin 1:8aa5cdb4ab67 987 int MicroBitSerial::setTxBufferSize(uint8_t size)
Jonathan Austin 1:8aa5cdb4ab67 988 {
Jonathan Austin 1:8aa5cdb4ab67 989 if(txInUse())
Jonathan Austin 1:8aa5cdb4ab67 990 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 991
Jonathan Austin 1:8aa5cdb4ab67 992 lockTx();
Jonathan Austin 1:8aa5cdb4ab67 993
LancasterUniversity 66:2fc7d7c2fffc 994 // + 1 so there is a usable buffer size, of the size the user requested.
LancasterUniversity 66:2fc7d7c2fffc 995 this->txBuffSize = size + 1;
Jonathan Austin 1:8aa5cdb4ab67 996
Jonathan Austin 1:8aa5cdb4ab67 997 int result = initialiseTx();
Jonathan Austin 1:8aa5cdb4ab67 998
Jonathan Austin 1:8aa5cdb4ab67 999 unlockTx();
Jonathan Austin 1:8aa5cdb4ab67 1000
Jonathan Austin 1:8aa5cdb4ab67 1001 return result;
Jonathan Austin 1:8aa5cdb4ab67 1002 }
Jonathan Austin 1:8aa5cdb4ab67 1003
Jonathan Austin 1:8aa5cdb4ab67 1004 /**
Jonathan Austin 1:8aa5cdb4ab67 1005 * The size of our rx buffer in bytes.
Jonathan Austin 1:8aa5cdb4ab67 1006 *
Jonathan Austin 1:8aa5cdb4ab67 1007 * @return the current size of rxBuff in bytes
Jonathan Austin 1:8aa5cdb4ab67 1008 */
Jonathan Austin 1:8aa5cdb4ab67 1009 int MicroBitSerial::getRxBufferSize()
Jonathan Austin 1:8aa5cdb4ab67 1010 {
Jonathan Austin 1:8aa5cdb4ab67 1011 return this->rxBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 1012 }
Jonathan Austin 1:8aa5cdb4ab67 1013
Jonathan Austin 1:8aa5cdb4ab67 1014 /**
Jonathan Austin 1:8aa5cdb4ab67 1015 * The size of our tx buffer in bytes.
Jonathan Austin 1:8aa5cdb4ab67 1016 *
Jonathan Austin 1:8aa5cdb4ab67 1017 * @return the current size of txBuff in bytes
Jonathan Austin 1:8aa5cdb4ab67 1018 */
Jonathan Austin 1:8aa5cdb4ab67 1019 int MicroBitSerial::getTxBufferSize()
Jonathan Austin 1:8aa5cdb4ab67 1020 {
Jonathan Austin 1:8aa5cdb4ab67 1021 return this->txBuffSize;
Jonathan Austin 1:8aa5cdb4ab67 1022 }
Jonathan Austin 1:8aa5cdb4ab67 1023
Jonathan Austin 1:8aa5cdb4ab67 1024 /**
Jonathan Austin 1:8aa5cdb4ab67 1025 * Sets the tail to match the head of our circular buffer for reception,
Jonathan Austin 1:8aa5cdb4ab67 1026 * effectively clearing the reception buffer.
Jonathan Austin 1:8aa5cdb4ab67 1027 *
Jonathan Austin 1:8aa5cdb4ab67 1028 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
Jonathan Austin 1:8aa5cdb4ab67 1029 * for reception, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 1030 */
Jonathan Austin 1:8aa5cdb4ab67 1031 int MicroBitSerial::clearRxBuffer()
Jonathan Austin 1:8aa5cdb4ab67 1032 {
Jonathan Austin 1:8aa5cdb4ab67 1033 if(rxInUse())
Jonathan Austin 1:8aa5cdb4ab67 1034 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 1035
Jonathan Austin 1:8aa5cdb4ab67 1036 lockRx();
Jonathan Austin 1:8aa5cdb4ab67 1037
Jonathan Austin 1:8aa5cdb4ab67 1038 rxBuffTail = rxBuffHead;
Jonathan Austin 1:8aa5cdb4ab67 1039
Jonathan Austin 1:8aa5cdb4ab67 1040 unlockRx();
Jonathan Austin 1:8aa5cdb4ab67 1041
Jonathan Austin 1:8aa5cdb4ab67 1042 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 1043 }
Jonathan Austin 1:8aa5cdb4ab67 1044
Jonathan Austin 1:8aa5cdb4ab67 1045 /**
Jonathan Austin 1:8aa5cdb4ab67 1046 * Sets the tail to match the head of our circular buffer for transmission,
Jonathan Austin 1:8aa5cdb4ab67 1047 * effectively clearing the transmission buffer.
Jonathan Austin 1:8aa5cdb4ab67 1048 *
Jonathan Austin 1:8aa5cdb4ab67 1049 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
Jonathan Austin 1:8aa5cdb4ab67 1050 * for transmission, otherwise MICROBIT_OK.
Jonathan Austin 1:8aa5cdb4ab67 1051 */
Jonathan Austin 1:8aa5cdb4ab67 1052 int MicroBitSerial::clearTxBuffer()
Jonathan Austin 1:8aa5cdb4ab67 1053 {
Jonathan Austin 1:8aa5cdb4ab67 1054 if(txInUse())
Jonathan Austin 1:8aa5cdb4ab67 1055 return MICROBIT_SERIAL_IN_USE;
Jonathan Austin 1:8aa5cdb4ab67 1056
Jonathan Austin 1:8aa5cdb4ab67 1057 lockTx();
Jonathan Austin 1:8aa5cdb4ab67 1058
Jonathan Austin 1:8aa5cdb4ab67 1059 txBuffTail = txBuffHead;
Jonathan Austin 1:8aa5cdb4ab67 1060
Jonathan Austin 1:8aa5cdb4ab67 1061 unlockTx();
Jonathan Austin 1:8aa5cdb4ab67 1062
Jonathan Austin 1:8aa5cdb4ab67 1063 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 1064 }
Jonathan Austin 1:8aa5cdb4ab67 1065
Jonathan Austin 1:8aa5cdb4ab67 1066 /**
Jonathan Austin 1:8aa5cdb4ab67 1067 * The number of bytes currently stored in our rx buffer waiting to be digested,
Jonathan Austin 1:8aa5cdb4ab67 1068 * by the user.
Jonathan Austin 1:8aa5cdb4ab67 1069 *
Jonathan Austin 1:8aa5cdb4ab67 1070 * @return The currently buffered number of bytes in our rxBuff.
Jonathan Austin 1:8aa5cdb4ab67 1071 */
Jonathan Austin 1:8aa5cdb4ab67 1072 int MicroBitSerial::rxBufferedSize()
Jonathan Austin 1:8aa5cdb4ab67 1073 {
Jonathan Austin 1:8aa5cdb4ab67 1074 if(rxBuffTail > rxBuffHead)
Jonathan Austin 1:8aa5cdb4ab67 1075 return (rxBuffSize - rxBuffTail) + rxBuffHead;
Jonathan Austin 1:8aa5cdb4ab67 1076
Jonathan Austin 1:8aa5cdb4ab67 1077 return rxBuffHead - rxBuffTail;
Jonathan Austin 1:8aa5cdb4ab67 1078 }
Jonathan Austin 1:8aa5cdb4ab67 1079
Jonathan Austin 1:8aa5cdb4ab67 1080 /**
Jonathan Austin 1:8aa5cdb4ab67 1081 * The number of bytes currently stored in our tx buffer waiting to be transmitted
Jonathan Austin 1:8aa5cdb4ab67 1082 * by the hardware.
Jonathan Austin 1:8aa5cdb4ab67 1083 *
Jonathan Austin 1:8aa5cdb4ab67 1084 * @return The currently buffered number of bytes in our txBuff.
Jonathan Austin 1:8aa5cdb4ab67 1085 */
Jonathan Austin 1:8aa5cdb4ab67 1086 int MicroBitSerial::txBufferedSize()
Jonathan Austin 1:8aa5cdb4ab67 1087 {
Jonathan Austin 1:8aa5cdb4ab67 1088 if(txBuffTail > txBuffHead)
Jonathan Austin 1:8aa5cdb4ab67 1089 return (txBuffSize - txBuffTail) + txBuffHead;
Jonathan Austin 1:8aa5cdb4ab67 1090
Jonathan Austin 1:8aa5cdb4ab67 1091 return txBuffHead - txBuffTail;
Jonathan Austin 1:8aa5cdb4ab67 1092 }
Jonathan Austin 1:8aa5cdb4ab67 1093
Jonathan Austin 1:8aa5cdb4ab67 1094 /**
Jonathan Austin 1:8aa5cdb4ab67 1095 * Determines if the serial bus is currently in use by another fiber for reception.
Jonathan Austin 1:8aa5cdb4ab67 1096 *
Jonathan Austin 1:8aa5cdb4ab67 1097 * @return The state of our mutex lock for reception.
Jonathan Austin 1:8aa5cdb4ab67 1098 *
Jonathan Austin 1:8aa5cdb4ab67 1099 * @note Only one fiber can call read at a time
Jonathan Austin 1:8aa5cdb4ab67 1100 */
Jonathan Austin 1:8aa5cdb4ab67 1101 int MicroBitSerial::rxInUse()
Jonathan Austin 1:8aa5cdb4ab67 1102 {
Jonathan Austin 1:8aa5cdb4ab67 1103 return (status & MICROBIT_SERIAL_RX_IN_USE);
Jonathan Austin 1:8aa5cdb4ab67 1104 }
Jonathan Austin 1:8aa5cdb4ab67 1105
Jonathan Austin 1:8aa5cdb4ab67 1106 /**
Jonathan Austin 1:8aa5cdb4ab67 1107 * Determines if the serial bus is currently in use by another fiber for transmission.
Jonathan Austin 1:8aa5cdb4ab67 1108 *
Jonathan Austin 1:8aa5cdb4ab67 1109 * @return The state of our mutex lock for transmition.
Jonathan Austin 1:8aa5cdb4ab67 1110 *
Jonathan Austin 1:8aa5cdb4ab67 1111 * @note Only one fiber can call send at a time
Jonathan Austin 1:8aa5cdb4ab67 1112 */
Jonathan Austin 1:8aa5cdb4ab67 1113 int MicroBitSerial::txInUse()
Jonathan Austin 1:8aa5cdb4ab67 1114 {
Jonathan Austin 1:8aa5cdb4ab67 1115 return (status & MICROBIT_SERIAL_TX_IN_USE);
Jonathan Austin 1:8aa5cdb4ab67 1116 }
Jonathan Austin 1:8aa5cdb4ab67 1117
Jonathan Austin 1:8aa5cdb4ab67 1118 /**
Jonathan Austin 1:8aa5cdb4ab67 1119 * Detaches a previously configured interrupt
Jonathan Austin 1:8aa5cdb4ab67 1120 *
Jonathan Austin 1:8aa5cdb4ab67 1121 * @param interruptType one of Serial::RxIrq or Serial::TxIrq
Jonathan Austin 1:8aa5cdb4ab67 1122 */
Jonathan Austin 1:8aa5cdb4ab67 1123 void MicroBitSerial::detach(Serial::IrqType interruptType)
Jonathan Austin 1:8aa5cdb4ab67 1124 {
Jonathan Austin 1:8aa5cdb4ab67 1125 //we detach by sending a bad value to attach, for some weird reason...
Jonathan Austin 1:8aa5cdb4ab67 1126 attach((MicroBitSerial *)NULL, &MicroBitSerial::dataReceived, interruptType);
LancasterUniversity 3:d86a4ddc1867 1127 }