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-10
- Revision:
- 10:9d3ae421081b
- Parent:
- 9:e183765bd81b
- Child:
- 11:6b99dbf1b65d
File content as of revision 10:9d3ae421081b:
#include "AsyncSerial/AsyncSerial.h"
#include "mbed.h"
#define MINIMUM_TIMEOUT 1
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),
receiveHandler(),
receiveResult(),
#if 0
receiveDoneHandler(NULL),
receiveObject(NULL),
receiveMember(),
receiveDoneObject(NULL),
#endif
waitDoneHandler(NULL),
waitObject(NULL),
waitMember(),
waitDoneObject(NULL),
isReceiving(false),
receiveBuffer(NULL),
receiveMaxLength(0),
receiveIndex(0),
receiveStatus(AsyncSerial::RECEIVE_TIMEOUT),
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);
#if DEVICE_SERIAL_FC
// SerialBase::set_flow_control(SerialBase::RTSCTS, rts, cts);
#endif
}
void AsyncSerial::putDone()
{
sendIndex++;
if (sendIndex < sendLength)
{
SerialBase::_base_putc(sendBuffer[sendIndex]);
}
else
{
if (sendDoneHandler)
{
sendDoneHandler();
}
else if (sendObject)
{
sendDoneObject(sendObject, sendMember);
}
}
}
void AsyncSerial::getReady()
{
if (isReceiving)
{
uint8_t input = SerialBase::_base_getc();
DEBUG("%c", input);
if (insideCondition)
{
if (conditionEndBuffer != NULL)
{
if (input == conditionEndBuffer[conditionIndex])
{
conditionIndex++;
if (conditionIndex == conditionEndLength)
{
receiveStatus = AsyncSerial::RECEIVE_FOUND;
timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, MINIMUM_TIMEOUT);
}
}
else
{
conditionIndex = 0;
}
}
if (receiveBuffer != NULL)
{
receiveBuffer[receiveIndex] = input;
receiveIndex++;
if ((receiveIndex == receiveMaxLength) && (receiveStatus != AsyncSerial::RECEIVE_FOUND))
{
receiveStatus = AsyncSerial::RECEIVE_FULL;
timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, MINIMUM_TIMEOUT);
}
}
}
else
{
if (conditionStartBuffer != NULL)
{
if (input == conditionStartBuffer[conditionIndex])
{
conditionIndex++;
if (conditionIndex == conditionStartLength)
{
insideCondition = true;
conditionIndex = 0;
}
}
else
{
conditionIndex = 0;
}
}
}
}
}
void AsyncSerial::getDone(uint8_t status)
{
isReceiving = false;
DEBUG("getDone: %X %X %X\r\n", this, waitDoneHandler, waitObject);
if ((receiveBuffer == NULL) && (conditionStartBuffer == NULL))
{
if (waitDoneHandler)
{
waitDoneHandler(status);
}
else if (waitObject)
{
waitDoneObject(waitObject, waitMember, status);
}
}
else
{
receiveResult.buffer = receiveBuffer;
receiveResult.length = receiveIndex;
receiveResult.status = status;
receiveHandler.call(&receiveResult);
}
}
void AsyncSerial::send(send_done_t handler, const char* buffer, uint16_t length)
{
if (handler && buffer && length)
{
sendDoneHandler = handler;
sendObject = NULL;
send(buffer, length);
}
}
void AsyncSerial::send(const char* buffer, uint16_t length)
{
sendBuffer = buffer;
sendLength = length;
sendIndex = 0;
SerialBase::_base_putc(sendBuffer[sendIndex]);
DEBUG("send: %X\r\n", waitObject);
}
void AsyncSerial::receive(receive_done_t handler,
uint8_t* buffer, uint16_t maxLength,
const char* conditionStartBuffer, uint16_t conditionStartLength,
const char* 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 char* _conditionStartBuffer, uint16_t _conditionStartLength,
const char* _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;
}
receiveStatus = AsyncSerial::RECEIVE_TIMEOUT;
timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, timeoutMilli * 1000);
isReceiving = true;
DEBUG("receive: %p\r\n", receiveBuffer);
}
void AsyncSerial::wait(wait_done_t handler,
const char* conditionEndBuffer, uint16_t conditionEndLength,
uint32_t timeoutMilli)
{
if (handler)
{
waitDoneHandler = handler;
waitObject = NULL;
receive(NULL, 0,
NULL, 0,
conditionEndBuffer, conditionEndLength,
timeoutMilli);
}
}
void AsyncSerial::receiveTimeout()
{
DEBUG("timeout: %X %X\r\n", this, waitObject);
getDone(receiveStatus);
}
int AsyncSerial::getc()
{
return SerialBase::_base_getc();
}
int AsyncSerial::putc(int c)
{
return SerialBase::_base_putc(c);
}

