Marcus Chang / AsyncSerial
Committer:
marcuschang
Date:
Fri Apr 17 09:12:22 2015 +0000
Revision:
16:55e6fbfc1e9d
Parent:
15:4d7d96cacc18
Child:
17:5dd6bcc93a8a
Added copyright header.

Who changed what in which revision?

UserRevisionLine numberNew 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 #ifndef __ASYNCSERIAL_H__
marcuschang 0:dfed780dc91a 18 #define __ASYNCSERIAL_H__
marcuschang 0:dfed780dc91a 19
marcuschang 0:dfed780dc91a 20 #include "mbed.h"
marcuschang 11:6b99dbf1b65d 21 #include "FunctionPointer.h"
Marcus Chang 10:9d3ae421081b 22 #include "AsyncSerial/FunctionPointerWithContext.h"
marcuschang 0:dfed780dc91a 23
marcuschang 9:e183765bd81b 24 #define NDEBUG 1
marcuschang 0:dfed780dc91a 25
marcuschang 7:5ba3a01e13c4 26 #ifdef NDEBUG
marcuschang 7:5ba3a01e13c4 27 #define DEBUG(...) /* nothing */
marcuschang 7:5ba3a01e13c4 28 #else
marcuschang 7:5ba3a01e13c4 29 #define DEBUG(...) { printf(__VA_ARGS__); }
marcuschang 7:5ba3a01e13c4 30 #endif // NDEBUG
marcuschang 0:dfed780dc91a 31
Marcus Chang 12:b45908320b9c 32 /* Asynchronous Serial Driver
marcuschang 0:dfed780dc91a 33
Marcus Chang 12:b45908320b9c 34 This library can:
Marcus Chang 12:b45908320b9c 35 Send a block of data (pointer + length) asynchronously
Marcus Chang 12:b45908320b9c 36 * optional callback
Marcus Chang 12:b45908320b9c 37
Marcus Chang 12:b45908320b9c 38 Receive a block of data asynchronously with timeout:
Marcus Chang 12:b45908320b9c 39 * optional start condition (pointer + length)
Marcus Chang 12:b45908320b9c 40 * optional stop condition (pointer + length)
Marcus Chang 12:b45908320b9c 41
Marcus Chang 12:b45908320b9c 42 Call a function when a certain condition (pointer + length) is detected.
Marcus Chang 12:b45908320b9c 43 */
marcuschang 0:dfed780dc91a 44 class AsyncSerial : public SerialBase
marcuschang 0:dfed780dc91a 45 {
marcuschang 0:dfed780dc91a 46 public:
Marcus Chang 12:b45908320b9c 47 /* Receive Status:
Marcus Chang 12:b45908320b9c 48 Found: Stop condition caused the callback.
Marcus Chang 12:b45908320b9c 49 Full: The buffer is full.
Marcus Chang 12:b45908320b9c 50 Timeout: Time ran out before stop condition and buffer was filled.
Marcus Chang 12:b45908320b9c 51 */
marcuschang 5:aecd37846dcc 52 typedef enum {
marcuschang 5:aecd37846dcc 53 RECEIVE_FOUND,
marcuschang 5:aecd37846dcc 54 RECEIVE_FULL,
marcuschang 5:aecd37846dcc 55 RECEIVE_TIMEOUT
marcuschang 5:aecd37846dcc 56 } receive_status_t;
Marcus Chang 6:9d48f2197243 57
Marcus Chang 12:b45908320b9c 58 /* Struct used in receive callback function to pass arguments.
Marcus Chang 12:b45908320b9c 59 */
Marcus Chang 10:9d3ae421081b 60 typedef struct {
Marcus Chang 10:9d3ae421081b 61 uint8_t* buffer;
Marcus Chang 10:9d3ae421081b 62 uint16_t length;
Marcus Chang 10:9d3ae421081b 63 uint8_t status;
Marcus Chang 10:9d3ae421081b 64 } receive_params_t;
Marcus Chang 10:9d3ae421081b 65
Marcus Chang 12:b45908320b9c 66 // Callback function type definitions.
marcuschang 11:6b99dbf1b65d 67 typedef void (*send_done_t)(void);
marcuschang 11:6b99dbf1b65d 68 typedef void (*receive_done_t)(receive_params_t* result);
marcuschang 11:6b99dbf1b65d 69 typedef void (*wait_done_t)(uint8_t status);
marcuschang 11:6b99dbf1b65d 70
Marcus Chang 12:b45908320b9c 71 /* Constructor.
Marcus Chang 12:b45908320b9c 72
Marcus Chang 12:b45908320b9c 73 Tx: Transmit pin
Marcus Chang 12:b45908320b9c 74 Rx: Receive pin
Marcus Chang 12:b45908320b9c 75 Rts: Optional RTS flow control pin
Marcus Chang 12:b45908320b9c 76 Cts: Optional CTS flow control pin
Marcus Chang 12:b45908320b9c 77 */
marcuschang 14:29bc15f9343f 78 AsyncSerial(PinName tx, PinName rx, PinName rts = NC, PinName cts = NC);
marcuschang 0:dfed780dc91a 79
Marcus Chang 12:b45908320b9c 80 /* Send block of data.
Marcus Chang 12:b45908320b9c 81
marcuschang 13:dbb23efed611 82 send_done_t handler : Callback function
marcuschang 13:dbb23efed611 83 T* object/member : Callback object and member function
Marcus Chang 12:b45908320b9c 84
marcuschang 13:dbb23efed611 85 const char* buffer : Pointer to block to be send.
marcuschang 13:dbb23efed611 86 uint16_t length : Length of block in bytes.
Marcus Chang 12:b45908320b9c 87 */
Marcus Chang 12:b45908320b9c 88 void send(send_done_t handler, const char* buffer, uint16_t length);
marcuschang 0:dfed780dc91a 89
marcuschang 0:dfed780dc91a 90 template<typename T>
marcuschang 9:e183765bd81b 91 void send(T* object, void (T::*member)(void),
marcuschang 7:5ba3a01e13c4 92 const char* buffer, uint16_t length)
marcuschang 2:efec63739aa3 93 {
marcuschang 11:6b99dbf1b65d 94 sendHandler.attach(object, member);
marcuschang 11:6b99dbf1b65d 95 send(buffer, length);
marcuschang 2:efec63739aa3 96 }
marcuschang 0:dfed780dc91a 97
Marcus Chang 12:b45908320b9c 98 /* Receive block of data.
Marcus Chang 12:b45908320b9c 99
Marcus Chang 12:b45908320b9c 100 send_done_t handler : Callback function
Marcus Chang 12:b45908320b9c 101 T* object/member : Callback object and member function
Marcus Chang 12:b45908320b9c 102
marcuschang 13:dbb23efed611 103 const char* _receiveBuffer: Pointer to receive buffer.
marcuschang 13:dbb23efed611 104 uint16_t _maxLength : Maximumm number of bytes to receive.
Marcus Chang 12:b45908320b9c 105
marcuschang 13:dbb23efed611 106 const char* _conditionStartBuffer : Optional start condition for when to start
marcuschang 13:dbb23efed611 107 uint16_t _conditionStartLength : storing data in the receive buffer. Pass
marcuschang 13:dbb23efed611 108 NULL pointer and 0 length to disable.
Marcus Chang 12:b45908320b9c 109
marcuschang 13:dbb23efed611 110 const char* _conditionEndBuffer : Optional stop condition for when to stop
marcuschang 13:dbb23efed611 111 uint16_t _conditionEndLength : receiving data and signal callback function.
marcuschang 13:dbb23efed611 112 Pass NULL pointer and 0 length to disable.
Marcus Chang 12:b45908320b9c 113
marcuschang 13:dbb23efed611 114 uint32_t _timeoutMilli : Timeout in milliseconds.
Marcus Chang 12:b45908320b9c 115 */
Marcus Chang 1:a3f39ec7d5f2 116 void receive(receive_done_t handler,
marcuschang 13:dbb23efed611 117 uint8_t* _receiveBuffer, uint16_t _maxLength,
marcuschang 13:dbb23efed611 118 const char* _conditionStartBuffer, uint16_t _conditionStartLength,
marcuschang 13:dbb23efed611 119 const char* _conditionEndBuffer, uint16_t _conditionEndLength,
marcuschang 13:dbb23efed611 120 uint32_t _timeoutMilli);
marcuschang 0:dfed780dc91a 121
marcuschang 0:dfed780dc91a 122 template<typename T>
Marcus Chang 10:9d3ae421081b 123 void receive(T* object, void (T::*member)(receive_params_t*),
marcuschang 13:dbb23efed611 124 uint8_t* _receiveBuffer, uint16_t _maxLength,
marcuschang 13:dbb23efed611 125 const char* _conditionStartBuffer, uint16_t _conditionStartLength,
marcuschang 13:dbb23efed611 126 const char* _conditionEndBuffer, uint16_t _conditionEndLength,
marcuschang 13:dbb23efed611 127 uint32_t _timeoutMilli)
marcuschang 2:efec63739aa3 128 {
Marcus Chang 10:9d3ae421081b 129 receiveHandler.attach(object, member);
marcuschang 2:efec63739aa3 130
marcuschang 13:dbb23efed611 131 /* Signal callback function immediately if buffer and maxLength are invalid.
marcuschang 13:dbb23efed611 132 */
marcuschang 13:dbb23efed611 133 if ((_receiveBuffer == NULL) || (_maxLength == 0))
marcuschang 13:dbb23efed611 134 {
marcuschang 13:dbb23efed611 135 receiveResult.buffer = NULL;
marcuschang 13:dbb23efed611 136 receiveResult.length = 0;
marcuschang 13:dbb23efed611 137 receiveResult.status = AsyncSerial::RECEIVE_FULL;
Marcus Chang 15:4d7d96cacc18 138
marcuschang 13:dbb23efed611 139 receiveHandler.call(&receiveResult);
marcuschang 13:dbb23efed611 140 }
marcuschang 13:dbb23efed611 141 else
marcuschang 13:dbb23efed611 142 {
marcuschang 13:dbb23efed611 143 receive(_receiveBuffer, _maxLength,
marcuschang 13:dbb23efed611 144 _conditionStartBuffer, _conditionStartLength,
marcuschang 13:dbb23efed611 145 _conditionEndBuffer, _conditionEndLength,
marcuschang 13:dbb23efed611 146 _timeoutMilli);
marcuschang 13:dbb23efed611 147 }
marcuschang 2:efec63739aa3 148 }
marcuschang 0:dfed780dc91a 149
Marcus Chang 12:b45908320b9c 150
Marcus Chang 12:b45908320b9c 151 /* Register callback function to be called when a specific sequence is detected
Marcus Chang 12:b45908320b9c 152 or the time has run out. No data is stored.
Marcus Chang 12:b45908320b9c 153
Marcus Chang 12:b45908320b9c 154 send_done_t handler : Callback function
Marcus Chang 12:b45908320b9c 155 T* object/member : Callback object and member function
Marcus Chang 12:b45908320b9c 156
marcuschang 13:dbb23efed611 157 const char* _conditionEndBuffer : Sequence to be detected.
marcuschang 13:dbb23efed611 158 uint16_t _conditionEndLength :
Marcus Chang 12:b45908320b9c 159
marcuschang 13:dbb23efed611 160 uint32_t _timeoutMilli : Timeout in milliseconds.
Marcus Chang 12:b45908320b9c 161 */
Marcus Chang 6:9d48f2197243 162 void wait(wait_done_t handler,
marcuschang 13:dbb23efed611 163 const char* _conditionEndBuffer, uint16_t _conditionEndLength,
marcuschang 13:dbb23efed611 164 uint32_t _timeoutMilli);
Marcus Chang 6:9d48f2197243 165
Marcus Chang 6:9d48f2197243 166 template<typename T>
marcuschang 7:5ba3a01e13c4 167 void wait(T* object, void (T::*member)(uint8_t),
marcuschang 13:dbb23efed611 168 const char* _conditionEndBuffer, uint16_t _conditionEndLength,
marcuschang 13:dbb23efed611 169 uint32_t _timeoutMilli)
Marcus Chang 10:9d3ae421081b 170 {
marcuschang 11:6b99dbf1b65d 171 waitHandler.attach(object, member);
Marcus Chang 12:b45908320b9c 172
marcuschang 11:6b99dbf1b65d 173 receive(NULL, 0,
marcuschang 11:6b99dbf1b65d 174 NULL, 0,
marcuschang 13:dbb23efed611 175 _conditionEndBuffer, _conditionEndLength,
marcuschang 13:dbb23efed611 176 _timeoutMilli);
Marcus Chang 6:9d48f2197243 177 }
Marcus Chang 6:9d48f2197243 178
marcuschang 3:af3caa18e928 179 /* Send buffer with length but without registering a callback function.
marcuschang 3:af3caa18e928 180 Useful in conjunction with the receive callback.
marcuschang 3:af3caa18e928 181 */
marcuschang 7:5ba3a01e13c4 182 void send(const char* buffer, uint16_t length);
marcuschang 3:af3caa18e928 183
marcuschang 0:dfed780dc91a 184 private:
Marcus Chang 12:b45908320b9c 185 /* Main receive function.
Marcus Chang 12:b45908320b9c 186
Marcus Chang 12:b45908320b9c 187 All receive and wait calls are set up using this function.
Marcus Chang 12:b45908320b9c 188 */
marcuschang 13:dbb23efed611 189 void receive(uint8_t* _receiveBuffer, uint16_t _maxLength,
marcuschang 13:dbb23efed611 190 const char* _conditionStartBuffer, uint16_t _conditionStartLength,
marcuschang 13:dbb23efed611 191 const char* _conditionEndBuffer, uint16_t _conditionEndLength,
marcuschang 13:dbb23efed611 192 uint32_t _timeoutMilli);
marcuschang 3:af3caa18e928 193
Marcus Chang 12:b45908320b9c 194 /* Interrupt Service Routines for sending and receiving individual
Marcus Chang 12:b45908320b9c 195 characters and timeout handling.
Marcus Chang 12:b45908320b9c 196 */
marcuschang 0:dfed780dc91a 197 void putDone();
marcuschang 0:dfed780dc91a 198 void getReady();
marcuschang 5:aecd37846dcc 199 void receiveTimeout();
marcuschang 0:dfed780dc91a 200
Marcus Chang 12:b45908320b9c 201 /* Common function for signaling receive and wait callback functions.
Marcus Chang 12:b45908320b9c 202 */
Marcus Chang 12:b45908320b9c 203 void getDone(uint8_t status);
Marcus Chang 1:a3f39ec7d5f2 204
Marcus Chang 12:b45908320b9c 205 /* Book keeping variables for sending data.
Marcus Chang 12:b45908320b9c 206 */
Marcus Chang 12:b45908320b9c 207 const char* sendBuffer;
Marcus Chang 12:b45908320b9c 208 uint16_t sendLength;
Marcus Chang 12:b45908320b9c 209 uint16_t sendIndex;
Marcus Chang 6:9d48f2197243 210
Marcus Chang 12:b45908320b9c 211 /* Book keeping variables for receiving data.
Marcus Chang 12:b45908320b9c 212 */
Marcus Chang 12:b45908320b9c 213 uint8_t* receiveBuffer;
Marcus Chang 12:b45908320b9c 214 uint16_t receiveMaxLength;
Marcus Chang 12:b45908320b9c 215 uint16_t receiveIndex;
Marcus Chang 12:b45908320b9c 216 receive_status_t receiveStatus;
Marcus Chang 12:b45908320b9c 217 receive_params_t receiveResult;
Marcus Chang 12:b45908320b9c 218 Timeout timeout;
Marcus Chang 4:e0a0eef4ca18 219
Marcus Chang 12:b45908320b9c 220 /* Book keeping variables for detecting start and stop conditions.
Marcus Chang 12:b45908320b9c 221 */
Marcus Chang 12:b45908320b9c 222 bool insideCondition;
Marcus Chang 12:b45908320b9c 223 const char* conditionStartBuffer;
Marcus Chang 12:b45908320b9c 224 uint16_t conditionStartLength;
Marcus Chang 12:b45908320b9c 225 const char* conditionEndBuffer;
Marcus Chang 12:b45908320b9c 226 uint16_t conditionEndLength;
Marcus Chang 12:b45908320b9c 227 uint16_t conditionIndex;
Marcus Chang 1:a3f39ec7d5f2 228
Marcus Chang 12:b45908320b9c 229 /* Objects storing callback function.
Marcus Chang 12:b45908320b9c 230 */
Marcus Chang 12:b45908320b9c 231 FunctionPointer sendHandler;
Marcus Chang 12:b45908320b9c 232 FunctionPointerWithContext<receive_params_t*> receiveHandler;
Marcus Chang 12:b45908320b9c 233 FunctionPointerWithContext<uint8_t> waitHandler;
marcuschang 0:dfed780dc91a 234 };
marcuschang 0:dfed780dc91a 235
marcuschang 0:dfed780dc91a 236 #endif // __ASYNCSERIAL_H__