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