/**
  * 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;
}
Exemplo n.º 2
0
/**
  * 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;
}
Exemplo n.º 4
0
/**
  * 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;
}