/** * Reads a number of characters from the rxBuffer and fills user given buffer. * * @param buf a pointer to a buffer of len bytes. * @param len the size of the user allocated buffer * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode * gives a different behaviour: * * ASYNC - Will attempt to read all available characters, and return immediately * until the buffer limit is reached * * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER * * SYNC_SLEEP - Will first of all determine whether the given number of characters * are available in our buffer, if not, it will set an event and sleep * until the number of characters are avaialable. * * @return the number of characters digested */ int MicroBitUARTService::read(uint8_t *buf, int len, MicroBitSerialMode mode) { if(mode == SYNC_SPINWAIT) return MICROBIT_INVALID_PARAMETER; int i = 0; if(mode == ASYNC) { int c; while((c = getc(mode)) > 0 && i < len) { buf[i] = c; i++; } } if(mode == SYNC_SLEEP) { if(len > rxBufferedSize()) eventAfter(len - rxBufferedSize(), mode); while(i < len) { buf[i] = (char)getc(mode); i++; } } return i; }
/** * Reads multiple characters from the rxBuff and fills a user buffer. * * @param buffer a pointer to a user allocated buffer. * * @param bufferLen the amount of data that can be safely stored * * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode * gives a different behaviour: * * ASYNC - If the desired number of characters are available, this will fill * the given buffer. Otherwise, it will fill the buffer with however * many characters there are available. * * SYNC_SPINWAIT - If the desired number of characters are available, this will fill * the given buffer. Otherwise, this method will spin (lock up the processor) * and fill the buffer until the desired number of characters have been read. * * SYNC_SLEEP - If the desired number of characters are available, this will fill * the given buffer. Otherwise, the calling fiber sleeps * until the desired number of characters have been read. * * Defaults to SYNC_SLEEP. * * @return the number of characters read, or MICROBIT_SERIAL_IN_USE if another fiber * is using the instance for receiving. */ int MicroBitSerial::read(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode) { if(rxInUse()) return MICROBIT_SERIAL_IN_USE; lockRx(); //lazy initialisation of our rx buffer if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT)) { int result = initialiseRx(); if(result != MICROBIT_OK) return result; } int bufferIndex = 0; int temp = 0; if(mode == ASYNC) { while((temp = getChar(mode)) != MICROBIT_NO_DATA && bufferIndex < bufferLen) { buffer[bufferIndex] = (char)temp; bufferIndex++; } } if(mode == SYNC_SPINWAIT) { while(bufferIndex < bufferLen) { buffer[bufferIndex] = (char)getChar(mode); bufferIndex++; } } if(mode == SYNC_SLEEP) { if(bufferLen > rxBufferedSize()) eventAfter(bufferLen - rxBufferedSize(), mode); while(bufferIndex < bufferLen) { buffer[bufferIndex] = (char)getChar(mode); bufferIndex++; } } unlockRx(); return bufferIndex; }
/** * Retreives a single character from our RxBuffer. * * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode * gives a different behaviour: * * ASYNC - Will attempt to read a single character, and return immediately * * SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER * * SYNC_SLEEP - Will configure the event and block the current fiber until the * event is received. * * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, a character or MICROBIT_NO_DATA */ int MicroBitUARTService::getc(MicroBitSerialMode mode) { if(mode == SYNC_SPINWAIT) return MICROBIT_INVALID_PARAMETER; if(mode == ASYNC) { if(!isReadable()) return MICROBIT_NO_DATA; } if(mode == SYNC_SLEEP) { if(!isReadable()) eventAfter(1, mode); } char c = rxBuffer[rxBufferTail]; rxBufferTail = (rxBufferTail + 1) % rxBufferSize; return c; }
/** * Reads a single character from the rxBuff * * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode * gives a different behaviour: * * ASYNC - A character is read from the rxBuff if available, if there * are no characters to be read, a value of zero is returned immediately. * * SYNC_SPINWAIT - A character is read from the rxBuff if available, if there * are no characters to be read, this method will spin * (lock up the processor) until a character is available. * * SYNC_SLEEP - A character is read from the rxBuff if available, if there * are no characters to be read, the calling fiber sleeps * until there is a character available. * * Defaults to SYNC_SLEEP. * * @return a character from the circular buffer, or MICROBIT_NO_DATA is there * are no characters in the buffer. */ int MicroBitSerial::getChar(MicroBitSerialMode mode) { if(mode == ASYNC) { if(!isReadable()) return MICROBIT_NO_DATA; } if(mode == SYNC_SPINWAIT) while(!isReadable()); if(mode == SYNC_SLEEP) { if(!isReadable()) eventAfter(1, mode); } char c = rxBuff[rxBuffTail]; rxBuffTail = (rxBuffTail + 1) % rxBuffSize; return c; }