Marcus Chang / AsyncSerial
Committer:
marcuschang
Date:
Fri Apr 10 13:05:30 2015 +0000
Revision:
9:e183765bd81b
Parent:
8:de7aaaf557ba
Child:
10:9d3ae421081b
Fixed sleep bug. Use timeout to decouple receiveDone with callback function.

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