Asynchronous Serial Library with flow control and tag detection.

Committer:
marcuschang
Date:
Wed Apr 01 16:28:02 2015 +0000
Revision:
5:aecd37846dcc
Parent:
4:e0a0eef4ca18
Child:
6:9d48f2197243
checkpoint

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcuschang 0:dfed780dc91a 1 #include "AsyncSerial/AsyncSerial.h"
marcuschang 0:dfed780dc91a 2
marcuschang 0:dfed780dc91a 3 #include "mbed.h"
marcuschang 0:dfed780dc91a 4
marcuschang 0:dfed780dc91a 5 AsyncSerial::AsyncSerial(PinName tx, PinName rx, PinName rts, PinName cts)
marcuschang 0:dfed780dc91a 6 : SerialBase(tx, rx),
Marcus Chang 1:a3f39ec7d5f2 7
marcuschang 0:dfed780dc91a 8 sendBuffer(NULL),
marcuschang 0:dfed780dc91a 9 sendLength(0),
Marcus Chang 1:a3f39ec7d5f2 10 sendIndex(0),
Marcus Chang 1:a3f39ec7d5f2 11
marcuschang 0:dfed780dc91a 12 sendDoneHandler(NULL),
Marcus Chang 1:a3f39ec7d5f2 13 sendObject(NULL),
Marcus Chang 1:a3f39ec7d5f2 14 sendMember(),
Marcus Chang 1:a3f39ec7d5f2 15 sendDoneObject(NULL),
Marcus Chang 1:a3f39ec7d5f2 16
marcuschang 0:dfed780dc91a 17 receiveDoneHandler(NULL),
Marcus Chang 1:a3f39ec7d5f2 18 receiveObject(NULL),
Marcus Chang 1:a3f39ec7d5f2 19 receiveMember(),
Marcus Chang 1:a3f39ec7d5f2 20 receiveDoneObject(NULL),
Marcus Chang 1:a3f39ec7d5f2 21
Marcus Chang 4:e0a0eef4ca18 22 isReceiving(false),
Marcus Chang 4:e0a0eef4ca18 23 receiveBuffer(NULL),
Marcus Chang 4:e0a0eef4ca18 24 receiveMaxLength(0),
Marcus Chang 4:e0a0eef4ca18 25 receiveIndex(0),
Marcus Chang 4:e0a0eef4ca18 26
Marcus Chang 4:e0a0eef4ca18 27 insideCondition(false),
Marcus Chang 4:e0a0eef4ca18 28 conditionStartBuffer(NULL),
Marcus Chang 4:e0a0eef4ca18 29 conditionStartLength(0),
Marcus Chang 4:e0a0eef4ca18 30 conditionEndBuffer(NULL),
Marcus Chang 4:e0a0eef4ca18 31 conditionEndLength(0),
marcuschang 0:dfed780dc91a 32 conditionIndex(0),
marcuschang 0:dfed780dc91a 33 timeout()
Marcus Chang 1:a3f39ec7d5f2 34 {
marcuschang 0:dfed780dc91a 35 SerialBase::attach<AsyncSerial>(this, &AsyncSerial::getReady, SerialBase::RxIrq);
marcuschang 0:dfed780dc91a 36 SerialBase::attach<AsyncSerial>(this, &AsyncSerial::putDone, SerialBase::TxIrq);
marcuschang 0:dfed780dc91a 37 }
marcuschang 0:dfed780dc91a 38
marcuschang 0:dfed780dc91a 39 void AsyncSerial::putDone()
marcuschang 0:dfed780dc91a 40 {
marcuschang 0:dfed780dc91a 41 if (sendLength > 0)
marcuschang 0:dfed780dc91a 42 {
marcuschang 0:dfed780dc91a 43 sendIndex++;
Marcus Chang 1:a3f39ec7d5f2 44
marcuschang 0:dfed780dc91a 45 if (sendIndex < sendLength)
marcuschang 0:dfed780dc91a 46 {
marcuschang 0:dfed780dc91a 47 SerialBase::_base_putc(sendBuffer[sendIndex]);
marcuschang 0:dfed780dc91a 48 }
marcuschang 0:dfed780dc91a 49 else
marcuschang 0:dfed780dc91a 50 {
Marcus Chang 1:a3f39ec7d5f2 51 sendLength = 0;
Marcus Chang 1:a3f39ec7d5f2 52
marcuschang 0:dfed780dc91a 53 if (sendDoneHandler)
marcuschang 0:dfed780dc91a 54 {
marcuschang 0:dfed780dc91a 55 sendDoneHandler(sendBuffer, sendLength);
marcuschang 0:dfed780dc91a 56 sendDoneHandler = NULL;
Marcus Chang 1:a3f39ec7d5f2 57 }
Marcus Chang 1:a3f39ec7d5f2 58 else if (sendObject)
Marcus Chang 1:a3f39ec7d5f2 59 {
Marcus Chang 1:a3f39ec7d5f2 60 sendDoneObject(sendObject, sendMember, sendBuffer, sendLength);
Marcus Chang 1:a3f39ec7d5f2 61 sendObject = NULL;
marcuschang 0:dfed780dc91a 62 }
marcuschang 0:dfed780dc91a 63 }
marcuschang 0:dfed780dc91a 64 }
marcuschang 0:dfed780dc91a 65 }
marcuschang 0:dfed780dc91a 66
marcuschang 0:dfed780dc91a 67 void AsyncSerial::getReady()
marcuschang 0:dfed780dc91a 68 {
Marcus Chang 4:e0a0eef4ca18 69 if (isReceiving)
Marcus Chang 1:a3f39ec7d5f2 70 {
Marcus Chang 4:e0a0eef4ca18 71 uint8_t input = SerialBase::_base_getc();
Marcus Chang 1:a3f39ec7d5f2 72
Marcus Chang 4:e0a0eef4ca18 73 if (insideCondition)
marcuschang 0:dfed780dc91a 74 {
Marcus Chang 4:e0a0eef4ca18 75 if (receiveBuffer != NULL)
marcuschang 0:dfed780dc91a 76 {
Marcus Chang 4:e0a0eef4ca18 77 receiveBuffer[receiveIndex] = input;
Marcus Chang 4:e0a0eef4ca18 78 receiveIndex++;
Marcus Chang 1:a3f39ec7d5f2 79
Marcus Chang 4:e0a0eef4ca18 80 if (receiveIndex == receiveMaxLength)
marcuschang 0:dfed780dc91a 81 {
marcuschang 0:dfed780dc91a 82 timeout.detach();
marcuschang 5:aecd37846dcc 83 getDone(AsyncSerial::RECEIVE_FULL);
marcuschang 0:dfed780dc91a 84 }
marcuschang 0:dfed780dc91a 85 }
Marcus Chang 4:e0a0eef4ca18 86
Marcus Chang 4:e0a0eef4ca18 87 if (conditionEndBuffer != NULL)
marcuschang 0:dfed780dc91a 88 {
Marcus Chang 4:e0a0eef4ca18 89 if (input == conditionEndBuffer[conditionIndex])
Marcus Chang 4:e0a0eef4ca18 90 {
Marcus Chang 4:e0a0eef4ca18 91 conditionIndex++;
Marcus Chang 4:e0a0eef4ca18 92
Marcus Chang 4:e0a0eef4ca18 93 if (conditionIndex == conditionEndLength)
Marcus Chang 4:e0a0eef4ca18 94 {
Marcus Chang 4:e0a0eef4ca18 95 timeout.detach();
marcuschang 5:aecd37846dcc 96 getDone(AsyncSerial::RECEIVE_FOUND);
Marcus Chang 4:e0a0eef4ca18 97 }
Marcus Chang 4:e0a0eef4ca18 98 }
Marcus Chang 4:e0a0eef4ca18 99 else
Marcus Chang 4:e0a0eef4ca18 100 {
Marcus Chang 4:e0a0eef4ca18 101 conditionIndex = 0;
Marcus Chang 4:e0a0eef4ca18 102 }
Marcus Chang 4:e0a0eef4ca18 103 }
Marcus Chang 4:e0a0eef4ca18 104 }
Marcus Chang 4:e0a0eef4ca18 105 else
Marcus Chang 4:e0a0eef4ca18 106 {
Marcus Chang 4:e0a0eef4ca18 107 if (conditionStartBuffer != NULL)
Marcus Chang 4:e0a0eef4ca18 108 {
Marcus Chang 4:e0a0eef4ca18 109 if (input == conditionStartBuffer[conditionIndex])
Marcus Chang 4:e0a0eef4ca18 110 {
Marcus Chang 4:e0a0eef4ca18 111 conditionIndex++;
Marcus Chang 4:e0a0eef4ca18 112
Marcus Chang 4:e0a0eef4ca18 113 if (conditionIndex == conditionStartLength)
Marcus Chang 4:e0a0eef4ca18 114 {
Marcus Chang 4:e0a0eef4ca18 115 insideCondition = true;
Marcus Chang 4:e0a0eef4ca18 116 }
Marcus Chang 4:e0a0eef4ca18 117 }
Marcus Chang 4:e0a0eef4ca18 118 else
Marcus Chang 4:e0a0eef4ca18 119 {
Marcus Chang 4:e0a0eef4ca18 120 conditionIndex = 0;
Marcus Chang 4:e0a0eef4ca18 121 }
marcuschang 0:dfed780dc91a 122 }
marcuschang 0:dfed780dc91a 123 }
marcuschang 0:dfed780dc91a 124 }
marcuschang 0:dfed780dc91a 125 }
marcuschang 0:dfed780dc91a 126
marcuschang 5:aecd37846dcc 127 void AsyncSerial::getDone(uint8_t status)
Marcus Chang 1:a3f39ec7d5f2 128 {
Marcus Chang 4:e0a0eef4ca18 129 isReceiving = false;
marcuschang 0:dfed780dc91a 130
marcuschang 0:dfed780dc91a 131 if (receiveDoneHandler)
marcuschang 0:dfed780dc91a 132 {
marcuschang 5:aecd37846dcc 133 receiveDoneHandler(receiveBuffer, receiveIndex, status);
marcuschang 0:dfed780dc91a 134 receiveDoneHandler = NULL;
marcuschang 0:dfed780dc91a 135 }
Marcus Chang 1:a3f39ec7d5f2 136 else if (receiveObject)
Marcus Chang 1:a3f39ec7d5f2 137 {
marcuschang 5:aecd37846dcc 138 receiveDoneObject(receiveObject, receiveMember, receiveBuffer, receiveIndex, status);
Marcus Chang 1:a3f39ec7d5f2 139 receiveObject = NULL;
Marcus Chang 1:a3f39ec7d5f2 140 }
marcuschang 0:dfed780dc91a 141 }
marcuschang 0:dfed780dc91a 142
marcuschang 3:af3caa18e928 143 void AsyncSerial::send(send_done_t handler, const uint8_t* buffer, uint16_t length)
marcuschang 0:dfed780dc91a 144 {
marcuschang 0:dfed780dc91a 145 if (handler && buffer && length)
Marcus Chang 1:a3f39ec7d5f2 146 {
marcuschang 0:dfed780dc91a 147 sendDoneHandler = handler;
Marcus Chang 1:a3f39ec7d5f2 148
Marcus Chang 1:a3f39ec7d5f2 149 sendObject = NULL;
Marcus Chang 1:a3f39ec7d5f2 150
marcuschang 0:dfed780dc91a 151 send(buffer, length);
marcuschang 0:dfed780dc91a 152 }
marcuschang 0:dfed780dc91a 153 }
marcuschang 0:dfed780dc91a 154
marcuschang 3:af3caa18e928 155 void AsyncSerial::send(const uint8_t* buffer, uint16_t length)
marcuschang 0:dfed780dc91a 156 {
marcuschang 0:dfed780dc91a 157 sendBuffer = buffer;
marcuschang 0:dfed780dc91a 158 sendLength = length;
marcuschang 0:dfed780dc91a 159
Marcus Chang 1:a3f39ec7d5f2 160 sendIndex = 0;
marcuschang 0:dfed780dc91a 161 SerialBase::_base_putc(sendBuffer[sendIndex]);
marcuschang 0:dfed780dc91a 162 }
marcuschang 0:dfed780dc91a 163
Marcus Chang 1:a3f39ec7d5f2 164 void AsyncSerial::receive(receive_done_t handler,
Marcus Chang 1:a3f39ec7d5f2 165 uint8_t* buffer, uint16_t maxLength,
Marcus Chang 4:e0a0eef4ca18 166 const uint8_t* conditionStartBuffer, uint16_t conditionStartLength,
Marcus Chang 4:e0a0eef4ca18 167 const uint8_t* conditionEndBuffer, uint16_t conditionEndLength,
marcuschang 0:dfed780dc91a 168 uint32_t timeoutMilli)
marcuschang 0:dfed780dc91a 169 {
Marcus Chang 1:a3f39ec7d5f2 170 if (handler)
Marcus Chang 1:a3f39ec7d5f2 171 {
Marcus Chang 1:a3f39ec7d5f2 172 receiveDoneHandler = handler;
Marcus Chang 1:a3f39ec7d5f2 173
Marcus Chang 1:a3f39ec7d5f2 174 receiveObject = NULL;
Marcus Chang 1:a3f39ec7d5f2 175
Marcus Chang 4:e0a0eef4ca18 176 receive(buffer, maxLength,
Marcus Chang 4:e0a0eef4ca18 177 conditionStartBuffer, conditionStartLength,
Marcus Chang 4:e0a0eef4ca18 178 conditionEndBuffer, conditionEndLength,
Marcus Chang 4:e0a0eef4ca18 179 timeoutMilli);
Marcus Chang 1:a3f39ec7d5f2 180 }
Marcus Chang 1:a3f39ec7d5f2 181 }
marcuschang 0:dfed780dc91a 182
marcuschang 2:efec63739aa3 183 void AsyncSerial::receive(uint8_t* buffer, uint16_t maxLength,
Marcus Chang 4:e0a0eef4ca18 184 const uint8_t* _conditionStartBuffer, uint16_t _conditionStartLength,
Marcus Chang 4:e0a0eef4ca18 185 const uint8_t* _conditionEndBuffer, uint16_t _conditionEndLength,
Marcus Chang 1:a3f39ec7d5f2 186 uint32_t timeoutMilli)
Marcus Chang 1:a3f39ec7d5f2 187 {
marcuschang 0:dfed780dc91a 188 receiveBuffer = buffer;
marcuschang 0:dfed780dc91a 189 receiveMaxLength = maxLength;
marcuschang 0:dfed780dc91a 190 receiveIndex = 0;
Marcus Chang 1:a3f39ec7d5f2 191
Marcus Chang 4:e0a0eef4ca18 192 conditionEndBuffer = _conditionEndBuffer;
Marcus Chang 4:e0a0eef4ca18 193 conditionEndLength = _conditionEndLength;
marcuschang 0:dfed780dc91a 194 conditionIndex = 0;
Marcus Chang 1:a3f39ec7d5f2 195
Marcus Chang 4:e0a0eef4ca18 196 if ((_conditionStartBuffer != NULL) && (_conditionStartLength != 0))
Marcus Chang 4:e0a0eef4ca18 197 {
Marcus Chang 4:e0a0eef4ca18 198 insideCondition = false;
Marcus Chang 4:e0a0eef4ca18 199 conditionStartBuffer = _conditionStartBuffer;
Marcus Chang 4:e0a0eef4ca18 200 conditionStartLength = _conditionStartLength;
Marcus Chang 4:e0a0eef4ca18 201 }
Marcus Chang 4:e0a0eef4ca18 202 else
Marcus Chang 4:e0a0eef4ca18 203 {
Marcus Chang 4:e0a0eef4ca18 204 insideCondition = true;
Marcus Chang 4:e0a0eef4ca18 205 }
Marcus Chang 4:e0a0eef4ca18 206
marcuschang 5:aecd37846dcc 207 timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, timeoutMilli * 1000);
Marcus Chang 4:e0a0eef4ca18 208 isReceiving = true;
marcuschang 0:dfed780dc91a 209 }
marcuschang 0:dfed780dc91a 210
marcuschang 5:aecd37846dcc 211 void AsyncSerial::receiveTimeout()
marcuschang 5:aecd37846dcc 212 {
marcuschang 5:aecd37846dcc 213 getDone(AsyncSerial::RECEIVE_TIMEOUT);
marcuschang 5:aecd37846dcc 214 }
marcuschang 5:aecd37846dcc 215
Marcus Chang 1:a3f39ec7d5f2 216 int AsyncSerial::getc()
marcuschang 0:dfed780dc91a 217 {
marcuschang 0:dfed780dc91a 218 return SerialBase::_base_getc();
marcuschang 0:dfed780dc91a 219 }
marcuschang 0:dfed780dc91a 220
Marcus Chang 1:a3f39ec7d5f2 221 int AsyncSerial::putc(int c)
marcuschang 0:dfed780dc91a 222 {
marcuschang 0:dfed780dc91a 223 return SerialBase::_base_putc(c);
marcuschang 0:dfed780dc91a 224 }
marcuschang 0:dfed780dc91a 225
marcuschang 0:dfed780dc91a 226