Attempting to publish a tree
Dependencies: BLE_API mbed-dev-bin nRF51822
Fork of microbit-dal by
MicroBitSerial.h
00001 /* 00002 The MIT License (MIT) 00003 00004 Copyright (c) 2016 British Broadcasting Corporation. 00005 This software is provided by Lancaster University by arrangement with the BBC. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a 00008 copy of this software and associated documentation files (the "Software"), 00009 to deal in the Software without restriction, including without limitation 00010 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 and/or sell copies of the Software, and to permit persons to whom the 00012 Software is furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00023 DEALINGS IN THE SOFTWARE. 00024 */ 00025 00026 #ifndef MICROBIT_SERIAL_H 00027 #define MICROBIT_SERIAL_H 00028 00029 #include "mbed.h" 00030 #include "ManagedString.h" 00031 00032 #define MICROBIT_SERIAL_DEFAULT_BAUD_RATE 115200 00033 #define MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE 20 00034 00035 #define MICROBIT_SERIAL_EVT_DELIM_MATCH 1 00036 #define MICROBIT_SERIAL_EVT_HEAD_MATCH 2 00037 #define MICROBIT_SERIAL_EVT_RX_FULL 3 00038 00039 #define MICROBIT_SERIAL_RX_IN_USE 1 00040 #define MICROBIT_SERIAL_TX_IN_USE 2 00041 #define MICROBIT_SERIAL_RX_BUFF_INIT 4 00042 #define MICROBIT_SERIAL_TX_BUFF_INIT 8 00043 00044 00045 enum MicroBitSerialMode 00046 { 00047 ASYNC, 00048 SYNC_SPINWAIT, 00049 SYNC_SLEEP 00050 }; 00051 00052 /** 00053 * Class definition for MicroBitSerial. 00054 * 00055 * Represents an instance of RawSerial which accepts micro:bit specific data types. 00056 */ 00057 class MicroBitSerial : public RawSerial 00058 { 00059 00060 //holds that state of the mutex locks for all MicroBitSerial instances. 00061 static uint8_t status; 00062 00063 //holds the state of the baudrate for all MicroBitSerial instances. 00064 static int baudrate; 00065 00066 //delimeters used for matching on receive. 00067 ManagedString delimeters; 00068 00069 //a variable used when a user calls the eventAfter() method. 00070 int rxBuffHeadMatch; 00071 00072 uint8_t *rxBuff; 00073 uint8_t rxBuffSize; 00074 volatile uint16_t rxBuffHead; 00075 uint16_t rxBuffTail; 00076 00077 00078 uint8_t *txBuff; 00079 uint8_t txBuffSize; 00080 uint16_t txBuffHead; 00081 volatile uint16_t txBuffTail; 00082 00083 /** 00084 * An internal interrupt callback for MicroBitSerial configured for when a 00085 * character is received. 00086 * 00087 * Each time a character is received fill our circular buffer! 00088 */ 00089 void dataReceived(); 00090 00091 /** 00092 * An internal interrupt callback for MicroBitSerial. 00093 * 00094 * Each time the Serial module's buffer is empty, write a character if we have 00095 * characters to write. 00096 */ 00097 void dataWritten(); 00098 00099 /** 00100 * An internal method to configure an interrupt on tx buffer and also 00101 * a best effort copy operation to move bytes from a user buffer to our txBuff 00102 * 00103 * @param string a pointer to the first character of the users' buffer. 00104 * 00105 * @param len the length of the string, and ultimately the maximum number of bytes 00106 * that will be copied dependent on the state of txBuff 00107 * 00108 * @return the number of bytes copied into the buffer. 00109 */ 00110 int setTxInterrupt(uint8_t *string, int len); 00111 00112 /** 00113 * Locks the mutex so that others can't use this serial instance for reception 00114 */ 00115 void lockRx(); 00116 00117 /** 00118 * Locks the mutex so that others can't use this serial instance for transmission 00119 */ 00120 void lockTx(); 00121 00122 /** 00123 * Unlocks the mutex so that others can use this serial instance for reception 00124 */ 00125 void unlockRx(); 00126 00127 /** 00128 * Unlocks the mutex so that others can use this serial instance for transmission 00129 */ 00130 void unlockTx(); 00131 00132 /** 00133 * We do not want to always have our buffers initialised, especially if users to not 00134 * use them. We only bring them up on demand. 00135 */ 00136 int initialiseRx(); 00137 00138 /** 00139 * We do not want to always have our buffers initialised, especially if users to not 00140 * use them. We only bring them up on demand. 00141 */ 00142 int initialiseTx(); 00143 00144 /** 00145 * An internal method that either spin waits if mode is set to SYNC_SPINWAIT 00146 * or puts the fiber to sleep if the mode is set to SYNC_SLEEP 00147 * 00148 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP 00149 */ 00150 void send(MicroBitSerialMode mode); 00151 00152 /** 00153 * Reads a single character from the rxBuff 00154 * 00155 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00156 * gives a different behaviour: 00157 * 00158 * ASYNC - A character is read from the rxBuff if available, if there 00159 * are no characters to be read, a value of zero is returned immediately. 00160 * 00161 * SYNC_SPINWAIT - A character is read from the rxBuff if available, if there 00162 * are no characters to be read, this method will spin 00163 * (lock up the processor) until a character is available. 00164 * 00165 * SYNC_SLEEP - A character is read from the rxBuff if available, if there 00166 * are no characters to be read, the calling fiber sleeps 00167 * until there is a character available. 00168 * 00169 * Defaults to SYNC_SLEEP. 00170 * 00171 * @return a character from the circular buffer, or MICROBIT_NO_DATA is there 00172 * are no characters in the buffer. 00173 */ 00174 int getChar(MicroBitSerialMode mode); 00175 00176 /** 00177 * An internal method that copies values from a circular buffer to a linear buffer. 00178 * 00179 * @param circularBuff a pointer to the source circular buffer 00180 * 00181 * @param circularBuffSize the size of the circular buffer 00182 * 00183 * @param linearBuff a pointer to the destination linear buffer 00184 * 00185 * @param tailPosition the tail position in the circular buffer you want to copy from 00186 * 00187 * @param headPosition the head position in the circular buffer you want to copy to 00188 * 00189 * @note this method assumes that the linear buffer has the appropriate amount of 00190 * memory to contain the copy operation 00191 */ 00192 void circularCopy(uint8_t *circularBuff, uint8_t circularBuffSize, uint8_t *linearBuff, uint16_t tailPosition, uint16_t headPosition); 00193 00194 public: 00195 00196 /** 00197 * Constructor. 00198 * Create an instance of MicroBitSerial 00199 * 00200 * @param tx the Pin to be used for transmission 00201 * 00202 * @param rx the Pin to be used for receiving data 00203 * 00204 * @param rxBufferSize the size of the buffer to be used for receiving bytes 00205 * 00206 * @param txBufferSize the size of the buffer to be used for transmitting bytes 00207 * 00208 * @code 00209 * MicroBitSerial serial(USBTX, USBRX); 00210 * @endcode 00211 * @note the default baud rate is 115200. More API details can be found: 00212 * -https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/api/SerialBase.h 00213 * -https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/api/RawSerial.h 00214 * 00215 * Buffers aren't allocated until the first send or receive respectively. 00216 */ 00217 MicroBitSerial(PinName tx, PinName rx, uint8_t rxBufferSize = MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE, uint8_t txBufferSize = MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE); 00218 00219 /** 00220 * Sends a single character over the serial line. 00221 * 00222 * @param c the character to send 00223 * 00224 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00225 * gives a different behaviour: 00226 * 00227 * ASYNC - the character is copied into the txBuff and returns immediately. 00228 * 00229 * SYNC_SPINWAIT - the character is copied into the txBuff and this method 00230 * will spin (lock up the processor) until the character has 00231 * been sent. 00232 * 00233 * SYNC_SLEEP - the character is copied into the txBuff and the fiber sleeps 00234 * until the character has been sent. This allows other fibers 00235 * to continue execution. 00236 * 00237 * Defaults to SYNC_SLEEP. 00238 * 00239 * @return the number of bytes written, or MICROBIT_SERIAL_IN_USE if another fiber 00240 * is using the serial instance for transmission. 00241 */ 00242 int sendChar(char c, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE); 00243 00244 /** 00245 * Sends a ManagedString over the serial line. 00246 * 00247 * @param s the string to send 00248 * 00249 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00250 * gives a different behaviour: 00251 * 00252 * ASYNC - bytes are copied into the txBuff and returns immediately. 00253 * 00254 * SYNC_SPINWAIT - bytes are copied into the txBuff and this method 00255 * will spin (lock up the processor) until all bytes 00256 * have been sent. 00257 * 00258 * SYNC_SLEEP - bytes are copied into the txBuff and the fiber sleeps 00259 * until all bytes have been sent. This allows other fibers 00260 * to continue execution. 00261 * 00262 * Defaults to SYNC_SLEEP. 00263 * 00264 * @return the number of bytes written, or MICROBIT_SERIAL_IN_USE if another fiber 00265 * is using the serial instance for transmission. 00266 */ 00267 int send(ManagedString s, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE); 00268 00269 /** 00270 * Sends a buffer of known length over the serial line. 00271 * 00272 * @param buffer a pointer to the first character of the buffer 00273 * 00274 * @param len the number of bytes that are safely available to read. 00275 * 00276 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00277 * gives a different behaviour: 00278 * 00279 * ASYNC - bytes are copied into the txBuff and returns immediately. 00280 * 00281 * SYNC_SPINWAIT - bytes are copied into the txBuff and this method 00282 * will spin (lock up the processor) until all bytes 00283 * have been sent. 00284 * 00285 * SYNC_SLEEP - bytes are copied into the txBuff and the fiber sleeps 00286 * until all bytes have been sent. This allows other fibers 00287 * to continue execution. 00288 * 00289 * Defaults to SYNC_SLEEP. 00290 * 00291 * @return the number of bytes written, or MICROBIT_SERIAL_IN_USE if another fiber 00292 * is using the serial instance for transmission. 00293 */ 00294 int send(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE); 00295 00296 /** 00297 * Reads a single character from the rxBuff 00298 * 00299 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00300 * gives a different behaviour: 00301 * 00302 * ASYNC - A character is read from the rxBuff if available, if there 00303 * are no characters to be read, a value of MICROBIT_NO_DATA is returned immediately. 00304 * 00305 * SYNC_SPINWAIT - A character is read from the rxBuff if available, if there 00306 * are no characters to be read, this method will spin 00307 * (lock up the processor) until a character is available. 00308 * 00309 * SYNC_SLEEP - A character is read from the rxBuff if available, if there 00310 * are no characters to be read, the calling fiber sleeps 00311 * until there is a character available. 00312 * 00313 * Defaults to SYNC_SLEEP. 00314 * 00315 * @return a character, MICROBIT_SERIAL_IN_USE if another fiber is using the serial instance for reception, 00316 * MICROBIT_NO_RESOURCES if buffer allocation did not complete successfully, or MICROBIT_NO_DATA if 00317 * the rx buffer is empty and the mode given is ASYNC. 00318 */ 00319 int read(MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE); 00320 00321 /** 00322 * Reads multiple characters from the rxBuff and returns them as a ManagedString 00323 * 00324 * @param size the number of characters to read. 00325 * 00326 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00327 * gives a different behaviour: 00328 * 00329 * ASYNC - If the desired number of characters are available, this will return 00330 * a ManagedString with the expected size. Otherwise, it will read however 00331 * many characters there are available. 00332 * 00333 * SYNC_SPINWAIT - If the desired number of characters are available, this will return 00334 * a ManagedString with the expected size. Otherwise, this method will spin 00335 * (lock up the processor) until the desired number of characters have been read. 00336 * 00337 * SYNC_SLEEP - If the desired number of characters are available, this will return 00338 * a ManagedString with the expected size. Otherwise, the calling fiber sleeps 00339 * until the desired number of characters have been read. 00340 * 00341 * Defaults to SYNC_SLEEP. 00342 * 00343 * @return A ManagedString, or an empty ManagedString if an error was encountered during the read. 00344 */ 00345 ManagedString read(int size, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE); 00346 00347 /** 00348 * Reads multiple characters from the rxBuff and fills a user buffer. 00349 * 00350 * @param buffer a pointer to a user allocated buffer. 00351 * 00352 * @param bufferLen the amount of data that can be safely stored 00353 * 00354 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00355 * gives a different behaviour: 00356 * 00357 * ASYNC - If the desired number of characters are available, this will fill 00358 * the given buffer. Otherwise, it will fill the buffer with however 00359 * many characters there are available. 00360 * 00361 * SYNC_SPINWAIT - If the desired number of characters are available, this will fill 00362 * the given buffer. Otherwise, this method will spin (lock up the processor) 00363 * and fill the buffer until the desired number of characters have been read. 00364 * 00365 * SYNC_SLEEP - If the desired number of characters are available, this will fill 00366 * the given buffer. Otherwise, the calling fiber sleeps 00367 * until the desired number of characters have been read. 00368 * 00369 * Defaults to SYNC_SLEEP. 00370 * 00371 * @return the number of characters read, or MICROBIT_SERIAL_IN_USE if another fiber 00372 * is using the instance for receiving. 00373 */ 00374 int read(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE); 00375 00376 /** 00377 * Reads until one of the delimeters matches a character in the rxBuff 00378 * 00379 * @param delimeters a ManagedString containing a sequence of delimeter characters e.g. ManagedString("\r\n") 00380 * 00381 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00382 * gives a different behaviour: 00383 * 00384 * ASYNC - If one of the delimeters matches a character already in the rxBuff 00385 * this method will return a ManagedString up to the delimeter. 00386 * Otherwise, it will return an Empty ManagedString. 00387 * 00388 * SYNC_SPINWAIT - If one of the delimeters matches a character already in the rxBuff 00389 * this method will return a ManagedString up to the delimeter. 00390 * Otherwise, this method will spin (lock up the processor) until a 00391 * received character matches one of the delimeters. 00392 * 00393 * SYNC_SLEEP - If one of the delimeters matches a character already in the rxBuff 00394 * this method will return a ManagedString up to the delimeter. 00395 * Otherwise, the calling fiber sleeps until a character matching one 00396 * of the delimeters is seen. 00397 * 00398 * Defaults to SYNC_SLEEP. 00399 * 00400 * @return A ManagedString containing the characters up to a delimeter, or an Empty ManagedString, 00401 * if another fiber is currently using this instance for reception. 00402 * 00403 * @note delimeters are matched on a per byte basis. 00404 */ 00405 ManagedString readUntil(ManagedString delimeters, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE); 00406 00407 /** 00408 * A wrapper around the inherited method "baud" so we can trap the baud rate 00409 * as it changes and restore it if redirect() is called. 00410 * 00411 * @param baudrate the new baudrate. See: 00412 * - https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c 00413 * for permitted baud rates. 00414 * 00415 * @return MICROBIT_INVALID_PARAMETER if baud rate is less than 0, otherwise MICROBIT_OK. 00416 * 00417 * @note the underlying implementation chooses the first allowable rate at or above that requested. 00418 */ 00419 void baud(int baudrate); 00420 00421 /** 00422 * A way of dynamically configuring the serial instance to use pins other than USBTX and USBRX. 00423 * 00424 * @param tx the new transmission pin. 00425 * 00426 * @param rx the new reception pin. 00427 * 00428 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently transmitting or receiving, otherwise MICROBIT_OK. 00429 */ 00430 int redirect(PinName tx, PinName rx); 00431 00432 /** 00433 * Configures an event to be fired after "len" characters. 00434 * 00435 * @param len the number of characters to wait before triggering the event. 00436 * 00437 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00438 * gives a different behaviour: 00439 * 00440 * ASYNC - Will configure the event and return immediately. 00441 * 00442 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER 00443 * 00444 * SYNC_SLEEP - Will configure the event and block the current fiber until the 00445 * event is received. 00446 * 00447 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK. 00448 */ 00449 int eventAfter(int len, MicroBitSerialMode mode = ASYNC); 00450 00451 /** 00452 * Configures an event to be fired on a match with one of the delimeters. 00453 * 00454 * @param delimeters the characters to match received characters against e.g. ManagedString("\r\n") 00455 * 00456 * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode 00457 * gives a different behaviour: 00458 * 00459 * ASYNC - Will configure the event and return immediately. 00460 * 00461 * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER 00462 * 00463 * SYNC_SLEEP - Will configure the event and block the current fiber until the 00464 * event is received. 00465 * 00466 * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK. 00467 * 00468 * @note delimeters are matched on a per byte basis. 00469 */ 00470 int eventOn(ManagedString delimeters, MicroBitSerialMode mode = ASYNC); 00471 00472 /** 00473 * Determines whether there is any data waiting in our Rx buffer. 00474 * 00475 * @return 1 if we have space, 0 if we do not. 00476 * 00477 * @note We do not wrap the super's readable() method as we don't want to 00478 * interfere with communities that use manual calls to serial.readable(). 00479 */ 00480 int isReadable(); 00481 00482 /** 00483 * Determines if we have space in our txBuff. 00484 * 00485 * @return 1 if we have space, 0 if we do not. 00486 * 00487 * @note We do not wrap the super's writeable() method as we don't want to 00488 * interfere with communities that use manual calls to serial.writeable(). 00489 */ 00490 int isWriteable(); 00491 00492 /** 00493 * Reconfigures the size of our rxBuff 00494 * 00495 * @param size the new size for our rxBuff 00496 * 00497 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance 00498 * for reception, otherwise MICROBIT_OK. 00499 */ 00500 int setRxBufferSize(uint8_t size); 00501 00502 /** 00503 * Reconfigures the size of our txBuff 00504 * 00505 * @param size the new size for our txBuff 00506 * 00507 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance 00508 * for transmission, otherwise MICROBIT_OK. 00509 */ 00510 int setTxBufferSize(uint8_t size); 00511 00512 /** 00513 * The size of our rx buffer in bytes. 00514 * 00515 * @return the current size of rxBuff in bytes 00516 */ 00517 int getRxBufferSize(); 00518 00519 /** 00520 * The size of our tx buffer in bytes. 00521 * 00522 * @return the current size of txBuff in bytes 00523 */ 00524 int getTxBufferSize(); 00525 00526 /** 00527 * Sets the tail to match the head of our circular buffer for reception, 00528 * effectively clearing the reception buffer. 00529 * 00530 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance 00531 * for reception, otherwise MICROBIT_OK. 00532 */ 00533 int clearRxBuffer(); 00534 00535 /** 00536 * Sets the tail to match the head of our circular buffer for transmission, 00537 * effectively clearing the transmission buffer. 00538 * 00539 * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance 00540 * for transmission, otherwise MICROBIT_OK. 00541 */ 00542 int clearTxBuffer(); 00543 00544 /** 00545 * The number of bytes currently stored in our rx buffer waiting to be digested, 00546 * by the user. 00547 * 00548 * @return The currently buffered number of bytes in our rxBuff. 00549 */ 00550 int rxBufferedSize(); 00551 00552 /** 00553 * The number of bytes currently stored in our tx buffer waiting to be transmitted 00554 * by the hardware. 00555 * 00556 * @return The currently buffered number of bytes in our txBuff. 00557 */ 00558 int txBufferedSize(); 00559 00560 /** 00561 * Determines if the serial bus is currently in use by another fiber for reception. 00562 * 00563 * @return The state of our mutex lock for reception. 00564 * 00565 * @note Only one fiber can call read at a time 00566 */ 00567 int rxInUse(); 00568 00569 /** 00570 * Determines if the serial bus is currently in use by another fiber for transmission. 00571 * 00572 * @return The state of our mutex lock for transmition. 00573 * 00574 * @note Only one fiber can call send at a time 00575 */ 00576 int txInUse(); 00577 00578 /** 00579 * Detaches a previously configured interrupt 00580 * 00581 * @param interruptType one of Serial::RxIrq or Serial::TxIrq 00582 */ 00583 void detach(Serial::IrqType interuptType); 00584 00585 }; 00586 00587 #endif
Generated on Tue Jul 12 2022 19:58:09 by 1.7.2