Marcus Chang / AsyncSerial
Committer:
Marcus Chang
Date:
Wed Apr 01 17:44:12 2015 +0100
Revision:
6:9d48f2197243
Parent:
5:aecd37846dcc
Child:
7:5ba3a01e13c4
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
Marcus Chang 6:9d48f2197243 131 if ((receiveBuffer == NULL) && (conditionStartBuffer == 0))
marcuschang 0:dfed780dc91a 132 {
Marcus Chang 6:9d48f2197243 133 if (waitDoneHandler)
Marcus Chang 6:9d48f2197243 134 {
Marcus Chang 6:9d48f2197243 135 waitDoneHandler();
Marcus Chang 6:9d48f2197243 136 waitDoneHandler = NULL;
Marcus Chang 6:9d48f2197243 137 }
Marcus Chang 6:9d48f2197243 138 else if (waitObject)
Marcus Chang 6:9d48f2197243 139 {
Marcus Chang 6:9d48f2197243 140 waitDoneObject(waitObject, waitMember);
Marcus Chang 6:9d48f2197243 141 waitObject = NULL;
Marcus Chang 6:9d48f2197243 142 }
marcuschang 0:dfed780dc91a 143 }
Marcus Chang 6:9d48f2197243 144 else
Marcus Chang 1:a3f39ec7d5f2 145 {
Marcus Chang 6:9d48f2197243 146 if (receiveDoneHandler)
Marcus Chang 6:9d48f2197243 147 {
Marcus Chang 6:9d48f2197243 148 receiveDoneHandler(receiveBuffer, receiveIndex, status);
Marcus Chang 6:9d48f2197243 149 receiveDoneHandler = NULL;
Marcus Chang 6:9d48f2197243 150 }
Marcus Chang 6:9d48f2197243 151 else if (receiveObject)
Marcus Chang 6:9d48f2197243 152 {
Marcus Chang 6:9d48f2197243 153 receiveDoneObject(receiveObject, receiveMember, receiveBuffer, receiveIndex, status);
Marcus Chang 6:9d48f2197243 154 receiveObject = NULL;
Marcus Chang 6:9d48f2197243 155 }
Marcus Chang 1:a3f39ec7d5f2 156 }
marcuschang 0:dfed780dc91a 157 }
marcuschang 0:dfed780dc91a 158
marcuschang 3:af3caa18e928 159 void AsyncSerial::send(send_done_t handler, const uint8_t* buffer, uint16_t length)
marcuschang 0:dfed780dc91a 160 {
marcuschang 0:dfed780dc91a 161 if (handler && buffer && length)
Marcus Chang 1:a3f39ec7d5f2 162 {
marcuschang 0:dfed780dc91a 163 sendDoneHandler = handler;
Marcus Chang 1:a3f39ec7d5f2 164
Marcus Chang 1:a3f39ec7d5f2 165 sendObject = NULL;
Marcus Chang 1:a3f39ec7d5f2 166
marcuschang 0:dfed780dc91a 167 send(buffer, length);
marcuschang 0:dfed780dc91a 168 }
marcuschang 0:dfed780dc91a 169 }
marcuschang 0:dfed780dc91a 170
marcuschang 3:af3caa18e928 171 void AsyncSerial::send(const uint8_t* buffer, uint16_t length)
marcuschang 0:dfed780dc91a 172 {
marcuschang 0:dfed780dc91a 173 sendBuffer = buffer;
marcuschang 0:dfed780dc91a 174 sendLength = length;
marcuschang 0:dfed780dc91a 175
Marcus Chang 1:a3f39ec7d5f2 176 sendIndex = 0;
marcuschang 0:dfed780dc91a 177 SerialBase::_base_putc(sendBuffer[sendIndex]);
marcuschang 0:dfed780dc91a 178 }
marcuschang 0:dfed780dc91a 179
Marcus Chang 1:a3f39ec7d5f2 180 void AsyncSerial::receive(receive_done_t handler,
Marcus Chang 1:a3f39ec7d5f2 181 uint8_t* buffer, uint16_t maxLength,
Marcus Chang 4:e0a0eef4ca18 182 const uint8_t* conditionStartBuffer, uint16_t conditionStartLength,
Marcus Chang 4:e0a0eef4ca18 183 const uint8_t* conditionEndBuffer, uint16_t conditionEndLength,
marcuschang 0:dfed780dc91a 184 uint32_t timeoutMilli)
marcuschang 0:dfed780dc91a 185 {
Marcus Chang 1:a3f39ec7d5f2 186 if (handler)
Marcus Chang 1:a3f39ec7d5f2 187 {
Marcus Chang 1:a3f39ec7d5f2 188 receiveDoneHandler = handler;
Marcus Chang 1:a3f39ec7d5f2 189
Marcus Chang 1:a3f39ec7d5f2 190 receiveObject = NULL;
Marcus Chang 1:a3f39ec7d5f2 191
Marcus Chang 4:e0a0eef4ca18 192 receive(buffer, maxLength,
Marcus Chang 4:e0a0eef4ca18 193 conditionStartBuffer, conditionStartLength,
Marcus Chang 4:e0a0eef4ca18 194 conditionEndBuffer, conditionEndLength,
Marcus Chang 4:e0a0eef4ca18 195 timeoutMilli);
Marcus Chang 1:a3f39ec7d5f2 196 }
Marcus Chang 1:a3f39ec7d5f2 197 }
marcuschang 0:dfed780dc91a 198
marcuschang 2:efec63739aa3 199 void AsyncSerial::receive(uint8_t* buffer, uint16_t maxLength,
Marcus Chang 4:e0a0eef4ca18 200 const uint8_t* _conditionStartBuffer, uint16_t _conditionStartLength,
Marcus Chang 4:e0a0eef4ca18 201 const uint8_t* _conditionEndBuffer, uint16_t _conditionEndLength,
Marcus Chang 1:a3f39ec7d5f2 202 uint32_t timeoutMilli)
Marcus Chang 1:a3f39ec7d5f2 203 {
marcuschang 0:dfed780dc91a 204 receiveBuffer = buffer;
marcuschang 0:dfed780dc91a 205 receiveMaxLength = maxLength;
marcuschang 0:dfed780dc91a 206 receiveIndex = 0;
Marcus Chang 1:a3f39ec7d5f2 207
Marcus Chang 6:9d48f2197243 208 conditionStartBuffer = _conditionStartBuffer;
Marcus Chang 6:9d48f2197243 209 conditionStartLength = _conditionStartLength;
Marcus Chang 4:e0a0eef4ca18 210 conditionEndBuffer = _conditionEndBuffer;
Marcus Chang 4:e0a0eef4ca18 211 conditionEndLength = _conditionEndLength;
marcuschang 0:dfed780dc91a 212 conditionIndex = 0;
Marcus Chang 1:a3f39ec7d5f2 213
Marcus Chang 4:e0a0eef4ca18 214 if ((_conditionStartBuffer != NULL) && (_conditionStartLength != 0))
Marcus Chang 4:e0a0eef4ca18 215 {
Marcus Chang 4:e0a0eef4ca18 216 insideCondition = false;
Marcus Chang 4:e0a0eef4ca18 217 }
Marcus Chang 4:e0a0eef4ca18 218 else
Marcus Chang 4:e0a0eef4ca18 219 {
Marcus Chang 4:e0a0eef4ca18 220 insideCondition = true;
Marcus Chang 4:e0a0eef4ca18 221 }
Marcus Chang 4:e0a0eef4ca18 222
marcuschang 5:aecd37846dcc 223 timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, timeoutMilli * 1000);
Marcus Chang 4:e0a0eef4ca18 224 isReceiving = true;
marcuschang 0:dfed780dc91a 225 }
marcuschang 0:dfed780dc91a 226
Marcus Chang 6:9d48f2197243 227 void AsyncSerial::wait(wait_handler_t handler,
Marcus Chang 6:9d48f2197243 228 const uint8_t* conditionEndBuffer, uint16_t conditionEndLength,
Marcus Chang 6:9d48f2197243 229 uint32_t timeoutMilli)
Marcus Chang 6:9d48f2197243 230 {
Marcus Chang 6:9d48f2197243 231 if (handler)
Marcus Chang 6:9d48f2197243 232 {
Marcus Chang 6:9d48f2197243 233 waitDoneHandler = handler;
Marcus Chang 6:9d48f2197243 234
Marcus Chang 6:9d48f2197243 235 waitObject = NULL;
Marcus Chang 6:9d48f2197243 236
Marcus Chang 6:9d48f2197243 237 receive(NULL, 0,
Marcus Chang 6:9d48f2197243 238 NULL, 0,
Marcus Chang 6:9d48f2197243 239 conditionEndBuffer, conditionEndLength,
Marcus Chang 6:9d48f2197243 240 timeoutMilli);
Marcus Chang 6:9d48f2197243 241 }
Marcus Chang 6:9d48f2197243 242 }
Marcus Chang 6:9d48f2197243 243
marcuschang 5:aecd37846dcc 244 void AsyncSerial::receiveTimeout()
marcuschang 5:aecd37846dcc 245 {
marcuschang 5:aecd37846dcc 246 getDone(AsyncSerial::RECEIVE_TIMEOUT);
marcuschang 5:aecd37846dcc 247 }
marcuschang 5:aecd37846dcc 248
Marcus Chang 1:a3f39ec7d5f2 249 int AsyncSerial::getc()
marcuschang 0:dfed780dc91a 250 {
marcuschang 0:dfed780dc91a 251 return SerialBase::_base_getc();
marcuschang 0:dfed780dc91a 252 }
marcuschang 0:dfed780dc91a 253
Marcus Chang 1:a3f39ec7d5f2 254 int AsyncSerial::putc(int c)
marcuschang 0:dfed780dc91a 255 {
marcuschang 0:dfed780dc91a 256 return SerialBase::_base_putc(c);
marcuschang 0:dfed780dc91a 257 }
marcuschang 0:dfed780dc91a 258
marcuschang 0:dfed780dc91a 259