Asynchronous Serial Library with flow control and tag detection.
source/AsyncSerial.cpp
- Committer:
- marcuschang
- Date:
- 2015-04-01
- Revision:
- 3:af3caa18e928
- Parent:
- 2:efec63739aa3
- Child:
- 4:e0a0eef4ca18
File content as of revision 3:af3caa18e928:
#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), receiveBuffer(NULL), receiveMaxLength(0), receiveIndex(0), receiveDoneHandler(NULL), receiveObject(NULL), receiveMember(), receiveDoneObject(NULL), conditionBuffer(NULL), conditionLength(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() { uint8_t input = SerialBase::_base_getc(); if (receiveMaxLength > 0) { receiveBuffer[receiveIndex] = input; receiveIndex++; if (receiveIndex == receiveMaxLength) { timeout.detach(); getDone(); } else if (conditionLength > 0) { if (receiveBuffer[receiveIndex - 1] == conditionBuffer[conditionIndex]) { conditionIndex++; if (conditionIndex == conditionLength) { timeout.detach(); getDone(); } } else { conditionIndex = 0; } } } } void AsyncSerial::getDone() { receiveMaxLength = 0; if (receiveDoneHandler) { receiveDoneHandler(receiveBuffer, receiveIndex); receiveDoneHandler = NULL; } else if (receiveObject) { receiveDoneObject(receiveObject, receiveMember, receiveBuffer, receiveIndex); 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* conditionBuffer, uint16_t conditionLength, uint32_t timeoutMilli) { if (handler) { receiveDoneHandler = handler; receiveObject = NULL; receive(buffer, maxLength, conditionBuffer, conditionLength, timeoutMilli); } } void AsyncSerial::receive(uint8_t* buffer, uint16_t maxLength, const uint8_t* _conditionBuffer, uint16_t _conditionLength, uint32_t timeoutMilli) { receiveBuffer = buffer; receiveMaxLength = maxLength; receiveIndex = 0; conditionBuffer = _conditionBuffer; conditionLength = _conditionLength; conditionIndex = 0; timeout.attach_us<AsyncSerial>(this, &AsyncSerial::getDone, timeoutMilli * 1000); } int AsyncSerial::getc() { return SerialBase::_base_getc(); } int AsyncSerial::putc(int c) { return SerialBase::_base_putc(c); }