Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
source/AsyncSerial.cpp@17:5dd6bcc93a8a, 2015-04-17 (annotated)
- Committer:
- Marcus Chang 
- Date:
- Fri Apr 17 11:08:42 2015 +0100
- Revision:
- 17:5dd6bcc93a8a
- Parent:
- 16:55e6fbfc1e9d
- Child:
- 18:9127f9fae61f
Added checks to flow control pin setup.
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| marcuschang | 16:55e6fbfc1e9d | 1 | /* mbed Microcontroller Library | 
| marcuschang | 16:55e6fbfc1e9d | 2 | * Copyright (c) 2006-2015 ARM Limited | 
| marcuschang | 16:55e6fbfc1e9d | 3 | * | 
| marcuschang | 16:55e6fbfc1e9d | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
| marcuschang | 16:55e6fbfc1e9d | 5 | * you may not use this file except in compliance with the License. | 
| marcuschang | 16:55e6fbfc1e9d | 6 | * You may obtain a copy of the License at | 
| marcuschang | 16:55e6fbfc1e9d | 7 | * | 
| marcuschang | 16:55e6fbfc1e9d | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | 
| marcuschang | 16:55e6fbfc1e9d | 9 | * | 
| marcuschang | 16:55e6fbfc1e9d | 10 | * Unless required by applicable law or agreed to in writing, software | 
| marcuschang | 16:55e6fbfc1e9d | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
| marcuschang | 16:55e6fbfc1e9d | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
| marcuschang | 16:55e6fbfc1e9d | 13 | * See the License for the specific language governing permissions and | 
| marcuschang | 16:55e6fbfc1e9d | 14 | * limitations under the License. | 
| marcuschang | 16:55e6fbfc1e9d | 15 | */ | 
| marcuschang | 16:55e6fbfc1e9d | 16 | |
| marcuschang | 0:dfed780dc91a | 17 | #include "AsyncSerial/AsyncSerial.h" | 
| marcuschang | 0:dfed780dc91a | 18 | |
| marcuschang | 0:dfed780dc91a | 19 | #include "mbed.h" | 
| marcuschang | 0:dfed780dc91a | 20 | |
| marcuschang | 9:e183765bd81b | 21 | #define MINIMUM_TIMEOUT 1 | 
| marcuschang | 9:e183765bd81b | 22 | |
| marcuschang | 0:dfed780dc91a | 23 | AsyncSerial::AsyncSerial(PinName tx, PinName rx, PinName rts, PinName cts) | 
| marcuschang | 0:dfed780dc91a | 24 | : SerialBase(tx, rx), | 
| Marcus Chang | 1:a3f39ec7d5f2 | 25 | |
| marcuschang | 0:dfed780dc91a | 26 | sendBuffer(NULL), | 
| marcuschang | 0:dfed780dc91a | 27 | sendLength(0), | 
| Marcus Chang | 1:a3f39ec7d5f2 | 28 | sendIndex(0), | 
| Marcus Chang | 1:a3f39ec7d5f2 | 29 | |
| Marcus Chang | 4:e0a0eef4ca18 | 30 | receiveBuffer(NULL), | 
| Marcus Chang | 4:e0a0eef4ca18 | 31 | receiveMaxLength(0), | 
| Marcus Chang | 4:e0a0eef4ca18 | 32 | receiveIndex(0), | 
| Marcus Chang | 10:9d3ae421081b | 33 | receiveStatus(AsyncSerial::RECEIVE_TIMEOUT), | 
| Marcus Chang | 12:b45908320b9c | 34 | receiveResult(), | 
| marcuschang | 13:dbb23efed611 | 35 | timeout(), | 
| Marcus Chang | 4:e0a0eef4ca18 | 36 | |
| Marcus Chang | 4:e0a0eef4ca18 | 37 | insideCondition(false), | 
| Marcus Chang | 4:e0a0eef4ca18 | 38 | conditionStartBuffer(NULL), | 
| Marcus Chang | 4:e0a0eef4ca18 | 39 | conditionStartLength(0), | 
| Marcus Chang | 4:e0a0eef4ca18 | 40 | conditionEndBuffer(NULL), | 
| Marcus Chang | 4:e0a0eef4ca18 | 41 | conditionEndLength(0), | 
| marcuschang | 0:dfed780dc91a | 42 | conditionIndex(0), | 
| Marcus Chang | 12:b45908320b9c | 43 | |
| Marcus Chang | 12:b45908320b9c | 44 | sendHandler(), | 
| Marcus Chang | 12:b45908320b9c | 45 | receiveHandler(), | 
| marcuschang | 13:dbb23efed611 | 46 | waitHandler() | 
| Marcus Chang | 1:a3f39ec7d5f2 | 47 | { | 
| Marcus Chang | 12:b45908320b9c | 48 | // register ISR for receiving and sending | 
| marcuschang | 0:dfed780dc91a | 49 | SerialBase::attach<AsyncSerial>(this, &AsyncSerial::getReady, SerialBase::RxIrq); | 
| marcuschang | 0:dfed780dc91a | 50 | SerialBase::attach<AsyncSerial>(this, &AsyncSerial::putDone, SerialBase::TxIrq); | 
| Marcus Chang | 10:9d3ae421081b | 51 | |
| Marcus Chang | 10:9d3ae421081b | 52 | #if DEVICE_SERIAL_FC | 
| Marcus Chang | 17:5dd6bcc93a8a | 53 | if ((rts != NC) && (cts != NC)) | 
| Marcus Chang | 17:5dd6bcc93a8a | 54 | { | 
| Marcus Chang | 17:5dd6bcc93a8a | 55 | SerialBase::set_flow_control(SerialBase::RTSCTS, rts, cts); | 
| Marcus Chang | 17:5dd6bcc93a8a | 56 | } | 
| Marcus Chang | 10:9d3ae421081b | 57 | #endif | 
| marcuschang | 0:dfed780dc91a | 58 | } | 
| marcuschang | 0:dfed780dc91a | 59 | |
| Marcus Chang | 12:b45908320b9c | 60 | /* Tx ISR | 
| Marcus Chang | 12:b45908320b9c | 61 | */ | 
| marcuschang | 0:dfed780dc91a | 62 | void AsyncSerial::putDone() | 
| marcuschang | 0:dfed780dc91a | 63 | { | 
| Marcus Chang | 12:b45908320b9c | 64 | // sendIndex points to the next byte to send | 
| marcuschang | 9:e183765bd81b | 65 | sendIndex++; | 
| Marcus Chang | 1:a3f39ec7d5f2 | 66 | |
| marcuschang | 9:e183765bd81b | 67 | if (sendIndex < sendLength) | 
| marcuschang | 9:e183765bd81b | 68 | { | 
| Marcus Chang | 12:b45908320b9c | 69 | // send next character if there is still more to send | 
| marcuschang | 9:e183765bd81b | 70 | SerialBase::_base_putc(sendBuffer[sendIndex]); | 
| marcuschang | 9:e183765bd81b | 71 | } | 
| marcuschang | 9:e183765bd81b | 72 | else | 
| marcuschang | 9:e183765bd81b | 73 | { | 
| Marcus Chang | 12:b45908320b9c | 74 | // else signal callback function | 
| Marcus Chang | 12:b45908320b9c | 75 | sendHandler.call(); | 
| marcuschang | 0:dfed780dc91a | 76 | } | 
| marcuschang | 0:dfed780dc91a | 77 | } | 
| marcuschang | 0:dfed780dc91a | 78 | |
| Marcus Chang | 12:b45908320b9c | 79 | /* Rx ISR | 
| Marcus Chang | 12:b45908320b9c | 80 | */ | 
| marcuschang | 0:dfed780dc91a | 81 | void AsyncSerial::getReady() | 
| Marcus Chang | 10:9d3ae421081b | 82 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 83 | // read character from buffer | 
| Marcus Chang | 15:4d7d96cacc18 | 84 | uint8_t input = SerialBase::_base_getc(); | 
| Marcus Chang | 15:4d7d96cacc18 | 85 | |
| Marcus Chang | 15:4d7d96cacc18 | 86 | DEBUG("%c", input); | 
| Marcus Chang | 15:4d7d96cacc18 | 87 | |
| Marcus Chang | 15:4d7d96cacc18 | 88 | // check if start condition has been met | 
| Marcus Chang | 15:4d7d96cacc18 | 89 | if (insideCondition) | 
| Marcus Chang | 1:a3f39ec7d5f2 | 90 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 91 | /* If stop condition has been set, check if the | 
| Marcus Chang | 15:4d7d96cacc18 | 92 | character matches. If it does increment counter | 
| Marcus Chang | 15:4d7d96cacc18 | 93 | to point to next character in sequence. Otherwise | 
| Marcus Chang | 15:4d7d96cacc18 | 94 | reset sequence search. | 
| Marcus Chang | 15:4d7d96cacc18 | 95 | */ | 
| Marcus Chang | 15:4d7d96cacc18 | 96 | if (conditionEndBuffer != NULL) | 
| Marcus Chang | 15:4d7d96cacc18 | 97 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 98 | if (input == conditionEndBuffer[conditionIndex]) | 
| Marcus Chang | 15:4d7d96cacc18 | 99 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 100 | conditionIndex++; | 
| Marcus Chang | 1:a3f39ec7d5f2 | 101 | |
| Marcus Chang | 15:4d7d96cacc18 | 102 | /* End condition has been met. | 
| Marcus Chang | 15:4d7d96cacc18 | 103 | Set receive status to indicate sequence has been found | 
| Marcus Chang | 15:4d7d96cacc18 | 104 | and re-arm timer. The timeout is responsible for | 
| Marcus Chang | 15:4d7d96cacc18 | 105 | signaling the callback function and is useful for | 
| Marcus Chang | 15:4d7d96cacc18 | 106 | decoupling the callback from the receive ISR. | 
| Marcus Chang | 15:4d7d96cacc18 | 107 | */ | 
| Marcus Chang | 15:4d7d96cacc18 | 108 | if (conditionIndex == conditionEndLength) | 
| Marcus Chang | 15:4d7d96cacc18 | 109 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 110 | receiveStatus = AsyncSerial::RECEIVE_FOUND; | 
| Marcus Chang | 15:4d7d96cacc18 | 111 | timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, MINIMUM_TIMEOUT); | 
| Marcus Chang | 15:4d7d96cacc18 | 112 | } | 
| Marcus Chang | 15:4d7d96cacc18 | 113 | } | 
| Marcus Chang | 15:4d7d96cacc18 | 114 | else | 
| Marcus Chang | 15:4d7d96cacc18 | 115 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 116 | // Character didn't match sequence. Start over. | 
| Marcus Chang | 15:4d7d96cacc18 | 117 | conditionIndex = 0; | 
| Marcus Chang | 15:4d7d96cacc18 | 118 | } | 
| Marcus Chang | 15:4d7d96cacc18 | 119 | } | 
| marcuschang | 7:5ba3a01e13c4 | 120 | |
| Marcus Chang | 15:4d7d96cacc18 | 121 | /* A receive buffer is available. | 
| Marcus Chang | 15:4d7d96cacc18 | 122 | Store character in buffer and check if buffer is full, | 
| Marcus Chang | 15:4d7d96cacc18 | 123 | set receive status and re-arm timeout if it is. | 
| Marcus Chang | 15:4d7d96cacc18 | 124 | */ | 
| Marcus Chang | 15:4d7d96cacc18 | 125 | if (receiveBuffer != NULL) | 
| Marcus Chang | 10:9d3ae421081b | 126 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 127 | receiveBuffer[receiveIndex] = input; | 
| Marcus Chang | 15:4d7d96cacc18 | 128 | receiveIndex++; | 
| Marcus Chang | 15:4d7d96cacc18 | 129 | |
| Marcus Chang | 15:4d7d96cacc18 | 130 | /* If end condition has been met we still store the character | 
| Marcus Chang | 15:4d7d96cacc18 | 131 | but we do not change the receive status nor re-arm the timer. | 
| Marcus Chang | 12:b45908320b9c | 132 | */ | 
| Marcus Chang | 15:4d7d96cacc18 | 133 | if ((receiveIndex == receiveMaxLength) && (receiveStatus != AsyncSerial::RECEIVE_FOUND)) | 
| marcuschang | 0:dfed780dc91a | 134 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 135 | receiveStatus = AsyncSerial::RECEIVE_FULL; | 
| Marcus Chang | 15:4d7d96cacc18 | 136 | timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, MINIMUM_TIMEOUT); | 
| Marcus Chang | 15:4d7d96cacc18 | 137 | } | 
| Marcus Chang | 15:4d7d96cacc18 | 138 | } | 
| Marcus Chang | 15:4d7d96cacc18 | 139 | } | 
| Marcus Chang | 15:4d7d96cacc18 | 140 | /* Start condition has not been met. | 
| Marcus Chang | 15:4d7d96cacc18 | 141 | */ | 
| Marcus Chang | 15:4d7d96cacc18 | 142 | else | 
| Marcus Chang | 15:4d7d96cacc18 | 143 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 144 | if (conditionStartBuffer != NULL) | 
| Marcus Chang | 15:4d7d96cacc18 | 145 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 146 | if (input == conditionStartBuffer[conditionIndex]) | 
| Marcus Chang | 15:4d7d96cacc18 | 147 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 148 | conditionIndex++; | 
| Marcus Chang | 4:e0a0eef4ca18 | 149 | |
| Marcus Chang | 15:4d7d96cacc18 | 150 | /* Set condition flag and reset index since it is reused. | 
| Marcus Chang | 15:4d7d96cacc18 | 151 | */ | 
| Marcus Chang | 15:4d7d96cacc18 | 152 | if (conditionIndex == conditionStartLength) | 
| Marcus Chang | 4:e0a0eef4ca18 | 153 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 154 | insideCondition = true; | 
| Marcus Chang | 4:e0a0eef4ca18 | 155 | conditionIndex = 0; | 
| Marcus Chang | 4:e0a0eef4ca18 | 156 | } | 
| Marcus Chang | 4:e0a0eef4ca18 | 157 | } | 
| Marcus Chang | 15:4d7d96cacc18 | 158 | else | 
| marcuschang | 9:e183765bd81b | 159 | { | 
| Marcus Chang | 15:4d7d96cacc18 | 160 | // Character didn't match sequence. Start over. | 
| Marcus Chang | 15:4d7d96cacc18 | 161 | conditionIndex = 0; | 
| marcuschang | 0:dfed780dc91a | 162 | } | 
| marcuschang | 0:dfed780dc91a | 163 | } | 
| marcuschang | 0:dfed780dc91a | 164 | } | 
| marcuschang | 0:dfed780dc91a | 165 | } | 
| marcuschang | 0:dfed780dc91a | 166 | |
| Marcus Chang | 12:b45908320b9c | 167 | /* Common function for signaling receive done handler or wait done handler. | 
| Marcus Chang | 12:b45908320b9c | 168 | */ | 
| marcuschang | 5:aecd37846dcc | 169 | void AsyncSerial::getDone(uint8_t status) | 
| Marcus Chang | 1:a3f39ec7d5f2 | 170 | { | 
| marcuschang | 11:6b99dbf1b65d | 171 | DEBUG("getDone: %d\r\n", status); | 
| marcuschang | 7:5ba3a01e13c4 | 172 | |
| Marcus Chang | 12:b45908320b9c | 173 | /* Check whether to call the wait handler or the receive handler. | 
| Marcus Chang | 12:b45908320b9c | 174 | */ | 
| Marcus Chang | 12:b45908320b9c | 175 | if (receiveBuffer == NULL) | 
| marcuschang | 0:dfed780dc91a | 176 | { | 
| marcuschang | 11:6b99dbf1b65d | 177 | waitHandler.call(status); | 
| marcuschang | 0:dfed780dc91a | 178 | } | 
| Marcus Chang | 6:9d48f2197243 | 179 | else | 
| Marcus Chang | 1:a3f39ec7d5f2 | 180 | { | 
| Marcus Chang | 10:9d3ae421081b | 181 | receiveResult.buffer = receiveBuffer; | 
| Marcus Chang | 10:9d3ae421081b | 182 | receiveResult.length = receiveIndex; | 
| Marcus Chang | 10:9d3ae421081b | 183 | receiveResult.status = status; | 
| Marcus Chang | 10:9d3ae421081b | 184 | |
| Marcus Chang | 10:9d3ae421081b | 185 | receiveHandler.call(&receiveResult); | 
| Marcus Chang | 1:a3f39ec7d5f2 | 186 | } | 
| marcuschang | 0:dfed780dc91a | 187 | } | 
| marcuschang | 0:dfed780dc91a | 188 | |
| Marcus Chang | 12:b45908320b9c | 189 | /* Send block of data. Function pointer interface. | 
| Marcus Chang | 12:b45908320b9c | 190 | */ | 
| marcuschang | 7:5ba3a01e13c4 | 191 | void AsyncSerial::send(send_done_t handler, const char* buffer, uint16_t length) | 
| marcuschang | 0:dfed780dc91a | 192 | { | 
| Marcus Chang | 12:b45908320b9c | 193 | sendHandler.attach(handler); | 
| marcuschang | 11:6b99dbf1b65d | 194 | send(buffer, length); | 
| marcuschang | 0:dfed780dc91a | 195 | } | 
| marcuschang | 0:dfed780dc91a | 196 | |
| Marcus Chang | 12:b45908320b9c | 197 | /* Common send block of data function. | 
| Marcus Chang | 12:b45908320b9c | 198 | */ | 
| marcuschang | 7:5ba3a01e13c4 | 199 | void AsyncSerial::send(const char* buffer, uint16_t length) | 
| marcuschang | 0:dfed780dc91a | 200 | { | 
| Marcus Chang | 12:b45908320b9c | 201 | /* Signal callback function immediately if there is nothing to send. | 
| Marcus Chang | 12:b45908320b9c | 202 | */ | 
| marcuschang | 11:6b99dbf1b65d | 203 | if ((buffer != NULL) && (length != 0)) | 
| Marcus Chang | 12:b45908320b9c | 204 | { | 
| Marcus Chang | 12:b45908320b9c | 205 | // Store book keeping variables | 
| marcuschang | 11:6b99dbf1b65d | 206 | sendBuffer = buffer; | 
| marcuschang | 11:6b99dbf1b65d | 207 | sendLength = length; | 
| marcuschang | 11:6b99dbf1b65d | 208 | sendIndex = 0; | 
| Marcus Chang | 12:b45908320b9c | 209 | |
| Marcus Chang | 12:b45908320b9c | 210 | // Send first character. ISR sends the rest. | 
| marcuschang | 11:6b99dbf1b65d | 211 | SerialBase::_base_putc(sendBuffer[sendIndex]); | 
| Marcus Chang | 12:b45908320b9c | 212 | |
| marcuschang | 11:6b99dbf1b65d | 213 | DEBUG("send: %p %d\r\n", buffer, length); | 
| marcuschang | 11:6b99dbf1b65d | 214 | } | 
| marcuschang | 11:6b99dbf1b65d | 215 | else | 
| marcuschang | 11:6b99dbf1b65d | 216 | { | 
| marcuschang | 11:6b99dbf1b65d | 217 | sendHandler.call(); | 
| marcuschang | 11:6b99dbf1b65d | 218 | } | 
| marcuschang | 0:dfed780dc91a | 219 | } | 
| marcuschang | 0:dfed780dc91a | 220 | |
| Marcus Chang | 12:b45908320b9c | 221 | /* Receiving block of data. Function pointer interface. | 
| Marcus Chang | 12:b45908320b9c | 222 | */ | 
| marcuschang | 13:dbb23efed611 | 223 | void AsyncSerial::receive(receive_done_t _handler, | 
| marcuschang | 13:dbb23efed611 | 224 | uint8_t* _receiveBuffer, uint16_t _maxLength, | 
| marcuschang | 7:5ba3a01e13c4 | 225 | const char* _conditionStartBuffer, uint16_t _conditionStartLength, | 
| marcuschang | 7:5ba3a01e13c4 | 226 | const char* _conditionEndBuffer, uint16_t _conditionEndLength, | 
| marcuschang | 13:dbb23efed611 | 227 | uint32_t _timeoutMilli) | 
| Marcus Chang | 10:9d3ae421081b | 228 | { | 
| marcuschang | 13:dbb23efed611 | 229 | receiveHandler.attach(_handler); | 
| marcuschang | 13:dbb23efed611 | 230 | |
| Marcus Chang | 12:b45908320b9c | 231 | /* Signal callback function immediately if buffer and maxLength are invalid. | 
| Marcus Chang | 12:b45908320b9c | 232 | */ | 
| marcuschang | 13:dbb23efed611 | 233 | if ((_receiveBuffer == NULL) || (_maxLength == 0)) | 
| Marcus Chang | 12:b45908320b9c | 234 | { | 
| Marcus Chang | 12:b45908320b9c | 235 | receiveResult.buffer = NULL; | 
| Marcus Chang | 12:b45908320b9c | 236 | receiveResult.length = 0; | 
| Marcus Chang | 12:b45908320b9c | 237 | receiveResult.status = AsyncSerial::RECEIVE_FULL; | 
| Marcus Chang | 1:a3f39ec7d5f2 | 238 | |
| Marcus Chang | 12:b45908320b9c | 239 | receiveHandler.call(&receiveResult); | 
| Marcus Chang | 4:e0a0eef4ca18 | 240 | } | 
| Marcus Chang | 4:e0a0eef4ca18 | 241 | else | 
| Marcus Chang | 4:e0a0eef4ca18 | 242 | { | 
| marcuschang | 13:dbb23efed611 | 243 | receive(_receiveBuffer, _maxLength, | 
| marcuschang | 13:dbb23efed611 | 244 | _conditionStartBuffer, _conditionStartLength, | 
| marcuschang | 13:dbb23efed611 | 245 | _conditionEndBuffer, _conditionEndLength, | 
| marcuschang | 13:dbb23efed611 | 246 | _timeoutMilli); | 
| marcuschang | 13:dbb23efed611 | 247 | } | 
| marcuschang | 13:dbb23efed611 | 248 | } | 
| Marcus Chang | 4:e0a0eef4ca18 | 249 | |
| marcuschang | 13:dbb23efed611 | 250 | /* Common receive function. | 
| marcuschang | 13:dbb23efed611 | 251 | */ | 
| marcuschang | 13:dbb23efed611 | 252 | void AsyncSerial::receive(uint8_t* _receiveBuffer, uint16_t _maxLength, | 
| marcuschang | 13:dbb23efed611 | 253 | const char* _conditionStartBuffer, uint16_t _conditionStartLength, | 
| marcuschang | 13:dbb23efed611 | 254 | const char* _conditionEndBuffer, uint16_t _conditionEndLength, | 
| marcuschang | 13:dbb23efed611 | 255 | uint32_t _timeoutMilli) | 
| marcuschang | 13:dbb23efed611 | 256 | { | 
| marcuschang | 13:dbb23efed611 | 257 | // Book keeping variables for reception | 
| marcuschang | 13:dbb23efed611 | 258 | receiveBuffer = _receiveBuffer; | 
| marcuschang | 13:dbb23efed611 | 259 | receiveMaxLength = _maxLength; | 
| marcuschang | 13:dbb23efed611 | 260 | receiveIndex = 0; | 
| marcuschang | 13:dbb23efed611 | 261 | receiveStatus = AsyncSerial::RECEIVE_TIMEOUT; | 
| Marcus Chang | 12:b45908320b9c | 262 | |
| marcuschang | 13:dbb23efed611 | 263 | // Book keeping variables for conditions | 
| marcuschang | 13:dbb23efed611 | 264 | conditionStartBuffer = _conditionStartBuffer; | 
| marcuschang | 13:dbb23efed611 | 265 | conditionStartLength = _conditionStartLength; | 
| marcuschang | 13:dbb23efed611 | 266 | conditionEndBuffer = _conditionEndBuffer; | 
| marcuschang | 13:dbb23efed611 | 267 | conditionEndLength = _conditionEndLength; | 
| marcuschang | 13:dbb23efed611 | 268 | conditionIndex = 0; | 
| Marcus Chang | 12:b45908320b9c | 269 | |
| marcuschang | 13:dbb23efed611 | 270 | // Check if optional start condition is set | 
| marcuschang | 13:dbb23efed611 | 271 | if ((_conditionStartBuffer != NULL) && (_conditionStartLength != 0)) | 
| marcuschang | 13:dbb23efed611 | 272 | { | 
| marcuschang | 13:dbb23efed611 | 273 | insideCondition = false; | 
| marcuschang | 13:dbb23efed611 | 274 | } | 
| marcuschang | 13:dbb23efed611 | 275 | else | 
| marcuschang | 13:dbb23efed611 | 276 | { | 
| marcuschang | 13:dbb23efed611 | 277 | insideCondition = true; | 
| marcuschang | 11:6b99dbf1b65d | 278 | } | 
| marcuschang | 11:6b99dbf1b65d | 279 | |
| marcuschang | 13:dbb23efed611 | 280 | // Clear buffer. This re-arms the rx interrupts. | 
| marcuschang | 13:dbb23efed611 | 281 | while (SerialBase::readable()) | 
| marcuschang | 13:dbb23efed611 | 282 | { | 
| marcuschang | 13:dbb23efed611 | 283 | SerialBase::_base_getc(); | 
| marcuschang | 13:dbb23efed611 | 284 | } | 
| marcuschang | 13:dbb23efed611 | 285 | |
| marcuschang | 13:dbb23efed611 | 286 | // Arm timer and start receiving. | 
| marcuschang | 13:dbb23efed611 | 287 | timeout.attach_us<AsyncSerial>(this, &AsyncSerial::receiveTimeout, _timeoutMilli * 1000); | 
| marcuschang | 13:dbb23efed611 | 288 | |
| marcuschang | 13:dbb23efed611 | 289 | DEBUG("receive: %p\r\n", _receiveBuffer); | 
| marcuschang | 0:dfed780dc91a | 290 | } | 
| marcuschang | 0:dfed780dc91a | 291 | |
| Marcus Chang | 12:b45908320b9c | 292 | /* Wait until timeout or sequence is detected. | 
| Marcus Chang | 12:b45908320b9c | 293 | */ | 
| marcuschang | 7:5ba3a01e13c4 | 294 | void AsyncSerial::wait(wait_done_t handler, | 
| marcuschang | 7:5ba3a01e13c4 | 295 | const char* conditionEndBuffer, uint16_t conditionEndLength, | 
| Marcus Chang | 6:9d48f2197243 | 296 | uint32_t timeoutMilli) | 
| Marcus Chang | 6:9d48f2197243 | 297 | { | 
| marcuschang | 11:6b99dbf1b65d | 298 | waitHandler.attach(handler); | 
| Marcus Chang | 6:9d48f2197243 | 299 | |
| marcuschang | 11:6b99dbf1b65d | 300 | receive(NULL, 0, | 
| marcuschang | 11:6b99dbf1b65d | 301 | NULL, 0, | 
| marcuschang | 11:6b99dbf1b65d | 302 | conditionEndBuffer, conditionEndLength, | 
| marcuschang | 11:6b99dbf1b65d | 303 | timeoutMilli); | 
| Marcus Chang | 6:9d48f2197243 | 304 | } | 
| Marcus Chang | 6:9d48f2197243 | 305 | |
| Marcus Chang | 12:b45908320b9c | 306 | /* Timeout fired. Call common receive done function. | 
| Marcus Chang | 12:b45908320b9c | 307 | */ | 
| marcuschang | 5:aecd37846dcc | 308 | void AsyncSerial::receiveTimeout() | 
| marcuschang | 5:aecd37846dcc | 309 | { | 
| marcuschang | 11:6b99dbf1b65d | 310 | DEBUG("timeout\r\n"); | 
| Marcus Chang | 10:9d3ae421081b | 311 | |
| marcuschang | 9:e183765bd81b | 312 | getDone(receiveStatus); | 
| marcuschang | 5:aecd37846dcc | 313 | } | 
| marcuschang | 5:aecd37846dcc | 314 | 

