Marcus Chang / AsyncSerial
Committer:
marcuschang
Date:
Tue Apr 07 12:40:44 2015 +0000
Revision:
8:de7aaaf557ba
Parent:
7:5ba3a01e13c4
Child:
9:e183765bd81b
Fixed bug in callback registration.

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