Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
source/AsyncSerial.cpp
- Committer:
- Marcus Chang 
- Date:
- 2015-04-01
- Revision:
- 6:9d48f2197243
- Parent:
- 5:aecd37846dcc
- Child:
- 7:5ba3a01e13c4
File content as of revision 6:9d48f2197243:
#include "AsyncSerial/AsyncSerial.h"
#include "mbed.h"
AsyncSerial::AsyncSerial(PinName tx, PinName rx, PinName rts, PinName cts)
    :   SerialBase(tx, rx),
        sendBuffer(NULL),
        sendLength(0),
        sendIndex(0),
        sendDoneHandler(NULL),
        sendObject(NULL),
        sendMember(),
        sendDoneObject(NULL),
        receiveDoneHandler(NULL),
        receiveObject(NULL),
        receiveMember(),
        receiveDoneObject(NULL),
        isReceiving(false),
        receiveBuffer(NULL),
        receiveMaxLength(0),
        receiveIndex(0),
        insideCondition(false),
        conditionStartBuffer(NULL),
        conditionStartLength(0),
        conditionEndBuffer(NULL),
        conditionEndLength(0),
        conditionIndex(0),
        timeout()
{
    SerialBase::attach<AsyncSerial>(this, &AsyncSerial::getReady, SerialBase::RxIrq);
    SerialBase::attach<AsyncSerial>(this, &AsyncSerial::putDone, SerialBase::TxIrq);
}
void AsyncSerial::putDone()
{
    if (sendLength > 0)
    {
        sendIndex++;
        if (sendIndex < sendLength)
        {
            SerialBase::_base_putc(sendBuffer[sendIndex]);
        }
        else
        {
            sendLength = 0;
            if (sendDoneHandler)
            {
                sendDoneHandler(sendBuffer, sendLength);
                sendDoneHandler = NULL;
            }
            else if (sendObject)
            {
                sendDoneObject(sendObject, sendMember, sendBuffer, sendLength);
                sendObject = NULL;
            }
        }
    }
}
void AsyncSerial::getReady()
{
    if (isReceiving)
    {
        uint8_t input = SerialBase::_base_getc();
        if (insideCondition)
        {
            if (receiveBuffer != NULL)
            {
                receiveBuffer[receiveIndex] = input;
                receiveIndex++;
                if (receiveIndex == receiveMaxLength)
                {
                    timeout.detach();
                    getDone(AsyncSerial::RECEIVE_FULL);
                }
            }
            if (conditionEndBuffer != NULL)
            {
                if (input == conditionEndBuffer[conditionIndex])
                {
                    conditionIndex++;
                    if (conditionIndex == conditionEndLength)
                    {
                        timeout.detach();
                        getDone(AsyncSerial::RECEIVE_FOUND);
                    }
                }
                else
                {
                    conditionIndex = 0;
                }
            }
        }
        else
        {
            if (conditionStartBuffer != NULL)
            {
                if (input == conditionStartBuffer[conditionIndex])
                {
                    conditionIndex++;
                    if (conditionIndex == conditionStartLength)
                    {
                        insideCondition = true;
                    }
                }
                else
                {
                    conditionIndex = 0;
                }
            }
        }
    }
}
void AsyncSerial::getDone(uint8_t status)
{
    isReceiving = false;
    if ((receiveBuffer == NULL) && (conditionStartBuffer == 0))
    {
        if (waitDoneHandler)
        {
            waitDoneHandler();
            waitDoneHandler = NULL;
        }
        else if (waitObject)
        {
            waitDoneObject(waitObject, waitMember);
            waitObject = NULL;
        }
    }
    else
    {
        if (receiveDoneHandler)
        {
            receiveDoneHandler(receiveBuffer, receiveIndex, status);
            receiveDoneHandler = NULL;
        }
        else if (receiveObject)
        {
            receiveDoneObject(receiveObject, receiveMember, receiveBuffer, receiveIndex, status);
            receiveObject = NULL;
        }
    }
}
void AsyncSerial::send(send_done_t handler, const uint8_t* buffer, uint16_t length)
{
    if (handler && buffer && length)
    {
        sendDoneHandler = handler;
        sendObject = NULL;
        send(buffer, length);
    }
}
void AsyncSerial::send(const uint8_t* buffer, uint16_t length)
{
    sendBuffer = buffer;
    sendLength = length;
    sendIndex = 0;
    SerialBase::_base_putc(sendBuffer[sendIndex]);
}
void AsyncSerial::receive(receive_done_t handler,
                          uint8_t* buffer, uint16_t maxLength,
                          const uint8_t* conditionStartBuffer, uint16_t conditionStartLength,
                          const uint8_t* conditionEndBuffer, uint16_t conditionEndLength,
                          uint32_t timeoutMilli)
{
    if (handler)
    {
        receiveDoneHandler = handler;
        receiveObject = NULL;
        receive(buffer, maxLength,
                conditionStartBuffer, conditionStartLength,
                conditionEndBuffer, conditionEndLength,
                timeoutMilli);
    }
}
void AsyncSerial::receive(uint8_t* buffer, uint16_t maxLength,
                          const uint8_t* _conditionStartBuffer, uint16_t _conditionStartLength,
                          const uint8_t* _conditionEndBuffer, uint16_t _conditionEndLength,
                          uint32_t timeoutMilli)
{
    receiveBuffer = buffer;
    receiveMaxLength = maxLength;
    receiveIndex = 0;
    conditionStartBuffer = _conditionStartBuffer;
    conditionStartLength = _conditionStartLength;
    conditionEndBuffer = _conditionEndBuffer;
    conditionEndLength = _conditionEndLength;
    conditionIndex = 0;
    if ((_conditionStartBuffer != NULL) && (_conditionStartLength != 0))
    {
        insideCondition = false;
    }
    else
    {
        insideCondition = true;
    }
    timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, timeoutMilli * 1000);
    isReceiving = true;
}
void AsyncSerial::wait(wait_handler_t handler,
                       const uint8_t* conditionEndBuffer, uint16_t conditionEndLength,
                       uint32_t timeoutMilli)
{
    if (handler)
    {
        waitDoneHandler = handler;
        waitObject = NULL;
        receive(NULL, 0,
                NULL, 0,
                conditionEndBuffer, conditionEndLength,
                timeoutMilli);
    }
}
void AsyncSerial::receiveTimeout()
{
    getDone(AsyncSerial::RECEIVE_TIMEOUT);
}
int AsyncSerial::getc()
{
    return SerialBase::_base_getc();
}
int AsyncSerial::putc(int c)
{
    return SerialBase::_base_putc(c);
}
            
    
