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@1:a3f39ec7d5f2, 2015-03-30 (annotated)
- Committer:
- Marcus Chang
- Date:
- Mon Mar 30 17:12:30 2015 +0100
- Revision:
- 1:a3f39ec7d5f2
- Parent:
- 0:dfed780dc91a
- Child:
- 2:efec63739aa3
Object callback
Who changed what in which revision?
| User | Revision | Line number | New 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 | template<class T> |
| marcuschang | 0:dfed780dc91a | 6 | AsyncSerial::AsyncSerial(PinName tx, PinName rx, PinName rts, PinName cts) |
| marcuschang | 0:dfed780dc91a | 7 | : SerialBase(tx, rx), |
| Marcus Chang |
1:a3f39ec7d5f2 | 8 | |
| marcuschang | 0:dfed780dc91a | 9 | sendBuffer(NULL), |
| marcuschang | 0:dfed780dc91a | 10 | sendLength(0), |
| Marcus Chang |
1:a3f39ec7d5f2 | 11 | sendIndex(0), |
| Marcus Chang |
1:a3f39ec7d5f2 | 12 | |
| marcuschang | 0:dfed780dc91a | 13 | sendDoneHandler(NULL), |
| Marcus Chang |
1:a3f39ec7d5f2 | 14 | sendObject(NULL), |
| Marcus Chang |
1:a3f39ec7d5f2 | 15 | sendMember(), |
| Marcus Chang |
1:a3f39ec7d5f2 | 16 | sendDoneObject(NULL), |
| Marcus Chang |
1:a3f39ec7d5f2 | 17 | |
| marcuschang | 0:dfed780dc91a | 18 | receiveBuffer(NULL), |
| marcuschang | 0:dfed780dc91a | 19 | receiveMaxLength(0), |
| Marcus Chang |
1:a3f39ec7d5f2 | 20 | receiveIndex(0), |
| Marcus Chang |
1:a3f39ec7d5f2 | 21 | |
| 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 |
1:a3f39ec7d5f2 | 26 | |
| marcuschang | 0:dfed780dc91a | 27 | conditionBuffer(NULL), |
| marcuschang | 0:dfed780dc91a | 28 | conditionLength(0), |
| marcuschang | 0:dfed780dc91a | 29 | conditionIndex(0), |
| marcuschang | 0:dfed780dc91a | 30 | timeout() |
| Marcus Chang |
1:a3f39ec7d5f2 | 31 | { |
| marcuschang | 0:dfed780dc91a | 32 | SerialBase::attach<AsyncSerial>(this, &AsyncSerial::getReady, SerialBase::RxIrq); |
| marcuschang | 0:dfed780dc91a | 33 | SerialBase::attach<AsyncSerial>(this, &AsyncSerial::putDone, SerialBase::TxIrq); |
| marcuschang | 0:dfed780dc91a | 34 | } |
| marcuschang | 0:dfed780dc91a | 35 | |
| marcuschang | 0:dfed780dc91a | 36 | void AsyncSerial::putDone() |
| marcuschang | 0:dfed780dc91a | 37 | { |
| marcuschang | 0:dfed780dc91a | 38 | if (sendLength > 0) |
| marcuschang | 0:dfed780dc91a | 39 | { |
| marcuschang | 0:dfed780dc91a | 40 | sendIndex++; |
| Marcus Chang |
1:a3f39ec7d5f2 | 41 | |
| marcuschang | 0:dfed780dc91a | 42 | if (sendIndex < sendLength) |
| marcuschang | 0:dfed780dc91a | 43 | { |
| marcuschang | 0:dfed780dc91a | 44 | SerialBase::_base_putc(sendBuffer[sendIndex]); |
| marcuschang | 0:dfed780dc91a | 45 | } |
| marcuschang | 0:dfed780dc91a | 46 | else |
| marcuschang | 0:dfed780dc91a | 47 | { |
| Marcus Chang |
1:a3f39ec7d5f2 | 48 | sendLength = 0; |
| Marcus Chang |
1:a3f39ec7d5f2 | 49 | |
| marcuschang | 0:dfed780dc91a | 50 | if (sendDoneHandler) |
| marcuschang | 0:dfed780dc91a | 51 | { |
| marcuschang | 0:dfed780dc91a | 52 | sendDoneHandler(sendBuffer, sendLength); |
| marcuschang | 0:dfed780dc91a | 53 | sendDoneHandler = NULL; |
| Marcus Chang |
1:a3f39ec7d5f2 | 54 | } |
| Marcus Chang |
1:a3f39ec7d5f2 | 55 | else if (sendObject) |
| Marcus Chang |
1:a3f39ec7d5f2 | 56 | { |
| Marcus Chang |
1:a3f39ec7d5f2 | 57 | sendDoneObject(sendObject, sendMember, sendBuffer, sendLength); |
| Marcus Chang |
1:a3f39ec7d5f2 | 58 | sendObject = NULL; |
| marcuschang | 0:dfed780dc91a | 59 | } |
| marcuschang | 0:dfed780dc91a | 60 | } |
| marcuschang | 0:dfed780dc91a | 61 | } |
| marcuschang | 0:dfed780dc91a | 62 | } |
| marcuschang | 0:dfed780dc91a | 63 | |
| marcuschang | 0:dfed780dc91a | 64 | void AsyncSerial::getReady() |
| marcuschang | 0:dfed780dc91a | 65 | { |
| marcuschang | 0:dfed780dc91a | 66 | uint8_t input = SerialBase::_base_getc(); |
| Marcus Chang |
1:a3f39ec7d5f2 | 67 | |
| marcuschang | 0:dfed780dc91a | 68 | if (receiveMaxLength > 0) |
| Marcus Chang |
1:a3f39ec7d5f2 | 69 | { |
| marcuschang | 0:dfed780dc91a | 70 | receiveBuffer[receiveIndex] = input; |
| marcuschang | 0:dfed780dc91a | 71 | receiveIndex++; |
| Marcus Chang |
1:a3f39ec7d5f2 | 72 | |
| marcuschang | 0:dfed780dc91a | 73 | if (receiveIndex == receiveMaxLength) |
| marcuschang | 0:dfed780dc91a | 74 | { |
| marcuschang | 0:dfed780dc91a | 75 | timeout.detach(); |
| marcuschang | 0:dfed780dc91a | 76 | getDone(); |
| marcuschang | 0:dfed780dc91a | 77 | } |
| marcuschang | 0:dfed780dc91a | 78 | else if (conditionLength > 0) |
| marcuschang | 0:dfed780dc91a | 79 | { |
| marcuschang | 0:dfed780dc91a | 80 | if (receiveBuffer[receiveIndex - 1] == conditionBuffer[conditionIndex]) |
| marcuschang | 0:dfed780dc91a | 81 | { |
| marcuschang | 0:dfed780dc91a | 82 | conditionIndex++; |
| Marcus Chang |
1:a3f39ec7d5f2 | 83 | |
| marcuschang | 0:dfed780dc91a | 84 | if (conditionIndex == conditionLength) |
| marcuschang | 0:dfed780dc91a | 85 | { |
| marcuschang | 0:dfed780dc91a | 86 | timeout.detach(); |
| marcuschang | 0:dfed780dc91a | 87 | getDone(); |
| marcuschang | 0:dfed780dc91a | 88 | } |
| marcuschang | 0:dfed780dc91a | 89 | } |
| marcuschang | 0:dfed780dc91a | 90 | else |
| marcuschang | 0:dfed780dc91a | 91 | { |
| marcuschang | 0:dfed780dc91a | 92 | conditionIndex = 0; |
| marcuschang | 0:dfed780dc91a | 93 | } |
| marcuschang | 0:dfed780dc91a | 94 | } |
| marcuschang | 0:dfed780dc91a | 95 | } |
| marcuschang | 0:dfed780dc91a | 96 | } |
| marcuschang | 0:dfed780dc91a | 97 | |
| marcuschang | 0:dfed780dc91a | 98 | void AsyncSerial::getDone() |
| Marcus Chang |
1:a3f39ec7d5f2 | 99 | { |
| marcuschang | 0:dfed780dc91a | 100 | receiveMaxLength = 0; |
| marcuschang | 0:dfed780dc91a | 101 | |
| marcuschang | 0:dfed780dc91a | 102 | if (receiveDoneHandler) |
| marcuschang | 0:dfed780dc91a | 103 | { |
| marcuschang | 0:dfed780dc91a | 104 | receiveDoneHandler(receiveBuffer, receiveIndex); |
| marcuschang | 0:dfed780dc91a | 105 | receiveDoneHandler = NULL; |
| marcuschang | 0:dfed780dc91a | 106 | } |
| Marcus Chang |
1:a3f39ec7d5f2 | 107 | else if (receiveObject) |
| Marcus Chang |
1:a3f39ec7d5f2 | 108 | { |
| Marcus Chang |
1:a3f39ec7d5f2 | 109 | receiveDoneObject(receiveObject, receiveMember, receiveBuffer, receiveIndex); |
| Marcus Chang |
1:a3f39ec7d5f2 | 110 | receiveObject = NULL; |
| Marcus Chang |
1:a3f39ec7d5f2 | 111 | } |
| marcuschang | 0:dfed780dc91a | 112 | } |
| marcuschang | 0:dfed780dc91a | 113 | |
| marcuschang | 0:dfed780dc91a | 114 | void AsyncSerial::send(send_done_t handler, uint8_t* buffer, uint16_t length) |
| marcuschang | 0:dfed780dc91a | 115 | { |
| marcuschang | 0:dfed780dc91a | 116 | if (handler && buffer && length) |
| Marcus Chang |
1:a3f39ec7d5f2 | 117 | { |
| marcuschang | 0:dfed780dc91a | 118 | sendDoneHandler = handler; |
| Marcus Chang |
1:a3f39ec7d5f2 | 119 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 120 | sendObject = NULL; |
| Marcus Chang |
1:a3f39ec7d5f2 | 121 | sendMember = 0; |
| Marcus Chang |
1:a3f39ec7d5f2 | 122 | |
| marcuschang | 0:dfed780dc91a | 123 | send(buffer, length); |
| marcuschang | 0:dfed780dc91a | 124 | } |
| marcuschang | 0:dfed780dc91a | 125 | } |
| marcuschang | 0:dfed780dc91a | 126 | |
| marcuschang | 0:dfed780dc91a | 127 | template<typename T> |
| Marcus Chang |
1:a3f39ec7d5f2 | 128 | void AsyncSerial::send(T *object, void (T::*member)(void), uint8_t* buffer, uint16_t length) |
| marcuschang | 0:dfed780dc91a | 129 | { |
| marcuschang | 0:dfed780dc91a | 130 | if (object && member && buffer && length) |
| marcuschang | 0:dfed780dc91a | 131 | { |
| marcuschang | 0:dfed780dc91a | 132 | sendObject = static_cast<void*>(object); |
| Marcus Chang |
1:a3f39ec7d5f2 | 133 | memcpy(sendMember, &member, sizeof(member)); |
| Marcus Chang |
1:a3f39ec7d5f2 | 134 | sendDoneObject = &AsyncSerial::membercaller<T>; |
| marcuschang | 0:dfed780dc91a | 135 | |
| marcuschang | 0:dfed780dc91a | 136 | sendDoneHandler = 0; |
| Marcus Chang |
1:a3f39ec7d5f2 | 137 | |
| marcuschang | 0:dfed780dc91a | 138 | send(buffer, length); |
| marcuschang | 0:dfed780dc91a | 139 | } |
| marcuschang | 0:dfed780dc91a | 140 | } |
| marcuschang | 0:dfed780dc91a | 141 | |
| marcuschang | 0:dfed780dc91a | 142 | void AsyncSerial::send(uint8_t* buffer, uint16_t length) |
| marcuschang | 0:dfed780dc91a | 143 | { |
| marcuschang | 0:dfed780dc91a | 144 | sendBuffer = buffer; |
| marcuschang | 0:dfed780dc91a | 145 | sendLength = length; |
| marcuschang | 0:dfed780dc91a | 146 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 147 | sendIndex = 0; |
| marcuschang | 0:dfed780dc91a | 148 | SerialBase::_base_putc(sendBuffer[sendIndex]); |
| marcuschang | 0:dfed780dc91a | 149 | } |
| marcuschang | 0:dfed780dc91a | 150 | |
| marcuschang | 0:dfed780dc91a | 151 | |
| marcuschang | 0:dfed780dc91a | 152 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 153 | void AsyncSerial::receive(receive_done_t handler, |
| Marcus Chang |
1:a3f39ec7d5f2 | 154 | uint8_t* buffer, uint16_t maxLength, |
| Marcus Chang |
1:a3f39ec7d5f2 | 155 | const uint8_t* conditionBuffer, uint16_t conditionLength, |
| marcuschang | 0:dfed780dc91a | 156 | uint32_t timeoutMilli) |
| marcuschang | 0:dfed780dc91a | 157 | { |
| Marcus Chang |
1:a3f39ec7d5f2 | 158 | if (handler) |
| Marcus Chang |
1:a3f39ec7d5f2 | 159 | { |
| Marcus Chang |
1:a3f39ec7d5f2 | 160 | receiveDoneHandler = handler; |
| Marcus Chang |
1:a3f39ec7d5f2 | 161 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 162 | receiveObject = NULL; |
| Marcus Chang |
1:a3f39ec7d5f2 | 163 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 164 | receive(buffer, maxLength, conditionBuffer, conditionLength, timeoutMilli); |
| Marcus Chang |
1:a3f39ec7d5f2 | 165 | } |
| Marcus Chang |
1:a3f39ec7d5f2 | 166 | } |
| marcuschang | 0:dfed780dc91a | 167 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 168 | template<typename T> |
| Marcus Chang |
1:a3f39ec7d5f2 | 169 | void AsyncSerial::receive(T *object, void (T::*member)(uint8_t*, uint16_t), |
| Marcus Chang |
1:a3f39ec7d5f2 | 170 | uint8_t* buffer, uint16_t maxLength, |
| Marcus Chang |
1:a3f39ec7d5f2 | 171 | const uint8_t* conditionBuffer, uint16_t conditionLength, |
| Marcus Chang |
1:a3f39ec7d5f2 | 172 | uint32_t timeoutMilli) |
| Marcus Chang |
1:a3f39ec7d5f2 | 173 | { |
| Marcus Chang |
1:a3f39ec7d5f2 | 174 | if (object && member && receiveBuffer && maxLength) |
| Marcus Chang |
1:a3f39ec7d5f2 | 175 | { |
| Marcus Chang |
1:a3f39ec7d5f2 | 176 | receiveObject = static_cast<void*>(object); |
| Marcus Chang |
1:a3f39ec7d5f2 | 177 | memcpy(receiveMember, (uint8_t*) &member, sizeof(member)); |
| Marcus Chang |
1:a3f39ec7d5f2 | 178 | receiveDoneObject = &AsyncSerial::membercaller<T>; |
| Marcus Chang |
1:a3f39ec7d5f2 | 179 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 180 | receiveDoneHandler = NULL; |
| Marcus Chang |
1:a3f39ec7d5f2 | 181 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 182 | receive(buffer, maxLength, conditionBuffer, conditionLength, timeoutMilli); |
| Marcus Chang |
1:a3f39ec7d5f2 | 183 | } |
| Marcus Chang |
1:a3f39ec7d5f2 | 184 | } |
| Marcus Chang |
1:a3f39ec7d5f2 | 185 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 186 | void AsyncSerial::receive(uint8_t* receiveBuffer, uint16_t maxLength, |
| Marcus Chang |
1:a3f39ec7d5f2 | 187 | const uint8_t* conditionBuffer, uint16_t conditionLength, |
| Marcus Chang |
1:a3f39ec7d5f2 | 188 | uint32_t timeoutMilli) |
| Marcus Chang |
1:a3f39ec7d5f2 | 189 | { |
| marcuschang | 0:dfed780dc91a | 190 | receiveBuffer = buffer; |
| marcuschang | 0:dfed780dc91a | 191 | receiveMaxLength = maxLength; |
| marcuschang | 0:dfed780dc91a | 192 | receiveIndex = 0; |
| Marcus Chang |
1:a3f39ec7d5f2 | 193 | |
| marcuschang | 0:dfed780dc91a | 194 | conditionBuffer = _conditionBuffer; |
| marcuschang | 0:dfed780dc91a | 195 | conditionLength = _conditionLength; |
| marcuschang | 0:dfed780dc91a | 196 | conditionIndex = 0; |
| Marcus Chang |
1:a3f39ec7d5f2 | 197 | |
| marcuschang | 0:dfed780dc91a | 198 | timeout.attach_us<AsyncSerial>(this, &AsyncSerial::getDone, timeoutMilli * 1000); |
| marcuschang | 0:dfed780dc91a | 199 | } |
| marcuschang | 0:dfed780dc91a | 200 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 201 | template<typename T> |
| Marcus Chang |
1:a3f39ec7d5f2 | 202 | static void AsyncSerial::membercaller(void* object, uint8_t* member, uint8_t* buffer, uint16_t length) |
| Marcus Chang |
1:a3f39ec7d5f2 | 203 | { |
| Marcus Chang |
1:a3f39ec7d5f2 | 204 | T* o = static_cast<T*>(object); |
| Marcus Chang |
1:a3f39ec7d5f2 | 205 | void (T::*m)(uint8_t*, uint16_t); |
| Marcus Chang |
1:a3f39ec7d5f2 | 206 | memcpy(&m, member, sizeof(m)); |
| Marcus Chang |
1:a3f39ec7d5f2 | 207 | (o->*m)(buffer, length); |
| Marcus Chang |
1:a3f39ec7d5f2 | 208 | } |
| Marcus Chang |
1:a3f39ec7d5f2 | 209 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 210 | int AsyncSerial::getc() |
| marcuschang | 0:dfed780dc91a | 211 | { |
| marcuschang | 0:dfed780dc91a | 212 | return SerialBase::_base_getc(); |
| marcuschang | 0:dfed780dc91a | 213 | } |
| marcuschang | 0:dfed780dc91a | 214 | |
| Marcus Chang |
1:a3f39ec7d5f2 | 215 | int AsyncSerial::putc(int c) |
| marcuschang | 0:dfed780dc91a | 216 | { |
| marcuschang | 0:dfed780dc91a | 217 | return SerialBase::_base_putc(c); |
| marcuschang | 0:dfed780dc91a | 218 | } |
| marcuschang | 0:dfed780dc91a | 219 | |
| marcuschang | 0:dfed780dc91a | 220 |

