Marcus Chang / AsyncSerial
Committer:
Marcus Chang
Date:
Fri Apr 10 14:35:58 2015 +0100
Revision:
10:9d3ae421081b
Parent:
9:e183765bd81b
Child:
11:6b99dbf1b65d
Change callbacks to function pointer objects.

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