Marcus Chang / AsyncSerial
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?

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 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