Marcus Chang / AsyncSerial
Committer:
marcuschang
Date:
Fri Apr 10 14:27:21 2015 +0000
Revision:
11:6b99dbf1b65d
Parent:
10:9d3ae421081b
Child:
12:b45908320b9c
Changed all callbacks to use function pointer class.

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