Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Committer:
pspatel321
Date:
Sun Nov 16 02:43:58 2014 +0000
Revision:
32:e70407021ad2
Parent:
31:7eaa5e881b56
Changed watchdog to 110ms from 250ms.  Forgot to change it back.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pspatel321 31:7eaa5e881b56 1 /*
pspatel321 31:7eaa5e881b56 2 Copyright (c) 2010 Andy Kirkham
pspatel321 31:7eaa5e881b56 3
pspatel321 31:7eaa5e881b56 4 Permission is hereby granted, free of charge, to any person obtaining a copy
pspatel321 31:7eaa5e881b56 5 of this software and associated documentation files (the "Software"), to deal
pspatel321 31:7eaa5e881b56 6 in the Software without restriction, including without limitation the rights
pspatel321 31:7eaa5e881b56 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pspatel321 31:7eaa5e881b56 8 copies of the Software, and to permit persons to whom the Software is
pspatel321 31:7eaa5e881b56 9 furnished to do so, subject to the following conditions:
pspatel321 31:7eaa5e881b56 10
pspatel321 31:7eaa5e881b56 11 The above copyright notice and this permission notice shall be included in
pspatel321 31:7eaa5e881b56 12 all copies or substantial portions of the Software.
pspatel321 31:7eaa5e881b56 13
pspatel321 31:7eaa5e881b56 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pspatel321 31:7eaa5e881b56 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pspatel321 31:7eaa5e881b56 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pspatel321 31:7eaa5e881b56 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pspatel321 31:7eaa5e881b56 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pspatel321 31:7eaa5e881b56 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pspatel321 31:7eaa5e881b56 20 THE SOFTWARE.
pspatel321 31:7eaa5e881b56 21
pspatel321 31:7eaa5e881b56 22 @file MODSERIAL.h
pspatel321 31:7eaa5e881b56 23 @purpose Extends Serial to provide fully buffered IO
pspatel321 31:7eaa5e881b56 24 @version see ChangeLog.c
pspatel321 31:7eaa5e881b56 25 @date Nov 2010
pspatel321 31:7eaa5e881b56 26 @author Andy Kirkham
pspatel321 31:7eaa5e881b56 27 */
pspatel321 31:7eaa5e881b56 28
pspatel321 31:7eaa5e881b56 29 #ifndef MODSERIAL_H
pspatel321 31:7eaa5e881b56 30 #define MODSERIAL_H
pspatel321 31:7eaa5e881b56 31
pspatel321 31:7eaa5e881b56 32 /** @defgroup API The MODSERIAL API */
pspatel321 31:7eaa5e881b56 33 /** @defgroup MISC Misc MODSERIAL functions */
pspatel321 31:7eaa5e881b56 34 /** @defgroup INTERNALS MODSERIAL Internals */
pspatel321 31:7eaa5e881b56 35
pspatel321 31:7eaa5e881b56 36 #ifndef MODSERIAL_DEFAULT_RX_BUFFER_SIZE
pspatel321 31:7eaa5e881b56 37 #define MODSERIAL_DEFAULT_RX_BUFFER_SIZE 256
pspatel321 31:7eaa5e881b56 38 #endif
pspatel321 31:7eaa5e881b56 39
pspatel321 31:7eaa5e881b56 40 #ifndef MODSERIAL_DEFAULT_TX_BUFFER_SIZE
pspatel321 31:7eaa5e881b56 41 #define MODSERIAL_DEFAULT_TX_BUFFER_SIZE 256
pspatel321 31:7eaa5e881b56 42 #endif
pspatel321 31:7eaa5e881b56 43
pspatel321 31:7eaa5e881b56 44 #include "mbed.h"
pspatel321 31:7eaa5e881b56 45 #include "serial_api.h"
pspatel321 31:7eaa5e881b56 46
pspatel321 31:7eaa5e881b56 47 namespace AjK {
pspatel321 31:7eaa5e881b56 48
pspatel321 31:7eaa5e881b56 49 // Forward reference.
pspatel321 31:7eaa5e881b56 50 class MODSERIAL;
pspatel321 31:7eaa5e881b56 51
pspatel321 31:7eaa5e881b56 52 /**
pspatel321 31:7eaa5e881b56 53 * @author Andy Kirkham
pspatel321 31:7eaa5e881b56 54 * @see http://mbed.org/cookbook/MODSERIAL
pspatel321 31:7eaa5e881b56 55 * @see example3a.cpp
pspatel321 31:7eaa5e881b56 56 * @see example3b.cpp
pspatel321 31:7eaa5e881b56 57 * @see API
pspatel321 31:7eaa5e881b56 58 *
pspatel321 31:7eaa5e881b56 59 * <b>MODSERIAL_IRQ_INFO</b> is a class used to pass information (and access to protected
pspatel321 31:7eaa5e881b56 60 * MODSERIAL functions) to IRQ callbacks.
pspatel321 31:7eaa5e881b56 61 */
pspatel321 31:7eaa5e881b56 62 class MODSERIAL_IRQ_INFO
pspatel321 31:7eaa5e881b56 63 {
pspatel321 31:7eaa5e881b56 64 public:
pspatel321 31:7eaa5e881b56 65 friend class MODSERIAL;
pspatel321 31:7eaa5e881b56 66
pspatel321 31:7eaa5e881b56 67 MODSERIAL *serial;
pspatel321 31:7eaa5e881b56 68
pspatel321 31:7eaa5e881b56 69 MODSERIAL_IRQ_INFO() { serial = 0; }
pspatel321 31:7eaa5e881b56 70
pspatel321 31:7eaa5e881b56 71 /** rxDiscardLastChar()
pspatel321 31:7eaa5e881b56 72 *
pspatel321 31:7eaa5e881b56 73 * Remove the last char placed into the rx buffer.
pspatel321 31:7eaa5e881b56 74 * This is an operation that can only be performed
pspatel321 31:7eaa5e881b56 75 * by an rxCallback function.
pspatel321 31:7eaa5e881b56 76 * @ingroup API
pspatel321 31:7eaa5e881b56 77 * @return The byte removed from the buffer.
pspatel321 31:7eaa5e881b56 78 */
pspatel321 31:7eaa5e881b56 79 int rxDiscardLastChar(void);
pspatel321 31:7eaa5e881b56 80
pspatel321 31:7eaa5e881b56 81 protected:
pspatel321 31:7eaa5e881b56 82
pspatel321 31:7eaa5e881b56 83 /** setSerial()
pspatel321 31:7eaa5e881b56 84 *
pspatel321 31:7eaa5e881b56 85 * Used internally by MODSERIAL to set the "this" pointer
pspatel321 31:7eaa5e881b56 86 * of the MODSERIAL that created this object.
pspatel321 31:7eaa5e881b56 87 * @ingroup INTERNAL
pspatel321 31:7eaa5e881b56 88 * @param A pointer to a MODSERIAL object instance.
pspatel321 31:7eaa5e881b56 89 */
pspatel321 31:7eaa5e881b56 90 void setSerial(MODSERIAL *s) { serial = s; }
pspatel321 31:7eaa5e881b56 91 };
pspatel321 31:7eaa5e881b56 92
pspatel321 31:7eaa5e881b56 93 // Forward reference dummy class.
pspatel321 31:7eaa5e881b56 94 class MODSERIAL_callback_dummy;
pspatel321 31:7eaa5e881b56 95
pspatel321 31:7eaa5e881b56 96 /**
pspatel321 31:7eaa5e881b56 97 * @author Andy Kirkham
pspatel321 31:7eaa5e881b56 98 * @see http://mbed.org/cookbook/MODSERIAL
pspatel321 31:7eaa5e881b56 99 * @see example3a.cpp
pspatel321 31:7eaa5e881b56 100 * @see example3b.cpp
pspatel321 31:7eaa5e881b56 101 * @see API
pspatel321 31:7eaa5e881b56 102 *
pspatel321 31:7eaa5e881b56 103 * <b>MODSERIAL_callback</b> is a class used to hold application callbacks that
pspatel321 31:7eaa5e881b56 104 * MODSERIAL can invoke on certain events.
pspatel321 31:7eaa5e881b56 105 */
pspatel321 31:7eaa5e881b56 106 class MODSERIAL_callback
pspatel321 31:7eaa5e881b56 107 {
pspatel321 31:7eaa5e881b56 108 protected:
pspatel321 31:7eaa5e881b56 109
pspatel321 31:7eaa5e881b56 110 //! C callback function pointer.
pspatel321 31:7eaa5e881b56 111 void (*c_callback)(MODSERIAL_IRQ_INFO *);
pspatel321 31:7eaa5e881b56 112
pspatel321 31:7eaa5e881b56 113 //! C++ callback object/method pointer (the object part).
pspatel321 31:7eaa5e881b56 114 MODSERIAL_callback_dummy *obj_callback;
pspatel321 31:7eaa5e881b56 115
pspatel321 31:7eaa5e881b56 116 //! C++ callback object/method pointer (the method part).
pspatel321 31:7eaa5e881b56 117 void (MODSERIAL_callback_dummy::*method_callback)(MODSERIAL_IRQ_INFO *);
pspatel321 31:7eaa5e881b56 118
pspatel321 31:7eaa5e881b56 119 public:
pspatel321 31:7eaa5e881b56 120
pspatel321 31:7eaa5e881b56 121 /** Constructor
pspatel321 31:7eaa5e881b56 122 */
pspatel321 31:7eaa5e881b56 123 MODSERIAL_callback() {
pspatel321 31:7eaa5e881b56 124 c_callback = 0;
pspatel321 31:7eaa5e881b56 125 obj_callback = 0;
pspatel321 31:7eaa5e881b56 126 method_callback = 0;
pspatel321 31:7eaa5e881b56 127 }
pspatel321 31:7eaa5e881b56 128
pspatel321 31:7eaa5e881b56 129 /** attach - Overloaded attachment function.
pspatel321 31:7eaa5e881b56 130 *
pspatel321 31:7eaa5e881b56 131 * Attach a C type function pointer as the callback.
pspatel321 31:7eaa5e881b56 132 *
pspatel321 31:7eaa5e881b56 133 * Note, the callback function prototype must be:-
pspatel321 31:7eaa5e881b56 134 * @code
pspatel321 31:7eaa5e881b56 135 * void myCallbackFunction(MODSERIAL_IRQ_INFO *);
pspatel321 31:7eaa5e881b56 136 * @endcode
pspatel321 31:7eaa5e881b56 137 * @param A C function pointer to call.
pspatel321 31:7eaa5e881b56 138 */
pspatel321 31:7eaa5e881b56 139 void attach(void (*function)(MODSERIAL_IRQ_INFO *) = 0) { c_callback = function; }
pspatel321 31:7eaa5e881b56 140
pspatel321 31:7eaa5e881b56 141 /** attach - Overloaded attachment function.
pspatel321 31:7eaa5e881b56 142 *
pspatel321 31:7eaa5e881b56 143 * Attach a C++ type object/method pointer as the callback.
pspatel321 31:7eaa5e881b56 144 *
pspatel321 31:7eaa5e881b56 145 * Note, the callback method prototype must be:-
pspatel321 31:7eaa5e881b56 146 * @code
pspatel321 31:7eaa5e881b56 147 * public:
pspatel321 31:7eaa5e881b56 148 * void myCallbackFunction(MODSERIAL_IRQ_INFO *);
pspatel321 31:7eaa5e881b56 149 * @endcode
pspatel321 31:7eaa5e881b56 150 * @param A C++ object pointer.
pspatel321 31:7eaa5e881b56 151 * @param A C++ method within the object to call.
pspatel321 31:7eaa5e881b56 152 */
pspatel321 31:7eaa5e881b56 153 template<class T>
pspatel321 31:7eaa5e881b56 154 void attach(T* item, void (T::*method)(MODSERIAL_IRQ_INFO *)) {
pspatel321 31:7eaa5e881b56 155 obj_callback = (MODSERIAL_callback_dummy *)item;
pspatel321 31:7eaa5e881b56 156 method_callback = (void (MODSERIAL_callback_dummy::*)(MODSERIAL_IRQ_INFO *))method;
pspatel321 31:7eaa5e881b56 157 }
pspatel321 31:7eaa5e881b56 158
pspatel321 31:7eaa5e881b56 159 /** call - Overloaded callback initiator.
pspatel321 31:7eaa5e881b56 160 *
pspatel321 31:7eaa5e881b56 161 * call the callback function.
pspatel321 31:7eaa5e881b56 162 *
pspatel321 31:7eaa5e881b56 163 * @param A pointer to a MODSERIAL_IRQ_INFO object.
pspatel321 31:7eaa5e881b56 164 */
pspatel321 31:7eaa5e881b56 165 void call(MODSERIAL_IRQ_INFO *arg) {
pspatel321 31:7eaa5e881b56 166 if (c_callback != 0) {
pspatel321 31:7eaa5e881b56 167 (*c_callback)(arg);
pspatel321 31:7eaa5e881b56 168 }
pspatel321 31:7eaa5e881b56 169 else {
pspatel321 31:7eaa5e881b56 170 if (obj_callback != 0 && method_callback != 0) {
pspatel321 31:7eaa5e881b56 171 (obj_callback->*method_callback)(arg);
pspatel321 31:7eaa5e881b56 172 }
pspatel321 31:7eaa5e881b56 173 }
pspatel321 31:7eaa5e881b56 174 }
pspatel321 31:7eaa5e881b56 175 };
pspatel321 31:7eaa5e881b56 176
pspatel321 31:7eaa5e881b56 177 /**
pspatel321 31:7eaa5e881b56 178 * @author Andy Kirkham
pspatel321 31:7eaa5e881b56 179 * @see http://mbed.org/cookbook/MODSERIAL
pspatel321 31:7eaa5e881b56 180 * @see http://mbed.org/handbook/Serial
pspatel321 31:7eaa5e881b56 181 * @see example1.cpp
pspatel321 31:7eaa5e881b56 182 * @see example2.cpp
pspatel321 31:7eaa5e881b56 183 * @see example3a.cpp
pspatel321 31:7eaa5e881b56 184 * @see example3b.cpp
pspatel321 31:7eaa5e881b56 185 * @see example_dma.cpp
pspatel321 31:7eaa5e881b56 186 * @see API
pspatel321 31:7eaa5e881b56 187 *
pspatel321 31:7eaa5e881b56 188 * <b>MODSERIAL</b> extends the Mbed library <a href="/handbook/Serial">Serial</a> to provide fully buffered
pspatel321 31:7eaa5e881b56 189 * TX and RX streams. Buffer length is fully customisable.
pspatel321 31:7eaa5e881b56 190 *
pspatel321 31:7eaa5e881b56 191 * Before using MODSERIAL users should be familar with Mbed's standard <a href="/handbook/Serial">Serial</a>
pspatel321 31:7eaa5e881b56 192 * library object. MODSERIAL is a direct "drop in" replacement for <a href="/handbook/Serial">Serial</a>. Where
pspatel321 31:7eaa5e881b56 193 * previously Serial was used, MODSERIAL can be used as adirect replacement instantly offering standard
pspatel321 31:7eaa5e881b56 194 * TX and RX buffering. By default, both TX and RX buffers are 256 bytes in length.
pspatel321 31:7eaa5e881b56 195 *
pspatel321 31:7eaa5e881b56 196 * @image html /media/uploads/mbedofficial/serial_interfaces.png
pspatel321 31:7eaa5e881b56 197 *
pspatel321 31:7eaa5e881b56 198 * Standard example:
pspatel321 31:7eaa5e881b56 199 * @code
pspatel321 31:7eaa5e881b56 200 * #include "mbed.h"
pspatel321 31:7eaa5e881b56 201 * #include "MODSERIAL.h"
pspatel321 31:7eaa5e881b56 202 *
pspatel321 31:7eaa5e881b56 203 * MODSERIAL pc(USBTX, USBRX); // tx, rx
pspatel321 31:7eaa5e881b56 204 *
pspatel321 31:7eaa5e881b56 205 * int main() {
pspatel321 31:7eaa5e881b56 206 * pc.printf("Hello World!");
pspatel321 31:7eaa5e881b56 207 * while(1) {
pspatel321 31:7eaa5e881b56 208 * pc.putc(pc.getc() + 1);
pspatel321 31:7eaa5e881b56 209 * }
pspatel321 31:7eaa5e881b56 210 * }
pspatel321 31:7eaa5e881b56 211 * @endcode
pspatel321 31:7eaa5e881b56 212 *
pspatel321 31:7eaa5e881b56 213 * Example with alternate buffer length:
pspatel321 31:7eaa5e881b56 214 * @code
pspatel321 31:7eaa5e881b56 215 * #include "mbed.h"
pspatel321 31:7eaa5e881b56 216 * #include "MODSERIAL.h"
pspatel321 31:7eaa5e881b56 217 *
pspatel321 31:7eaa5e881b56 218 * // Make TX and RX buffers 512byes in length
pspatel321 31:7eaa5e881b56 219 * MODSERIAL pc(USBTX, USBRX, 512); // tx, rx
pspatel321 31:7eaa5e881b56 220 *
pspatel321 31:7eaa5e881b56 221 * int main() {
pspatel321 31:7eaa5e881b56 222 * pc.printf("Hello World!");
pspatel321 31:7eaa5e881b56 223 * while(1) {
pspatel321 31:7eaa5e881b56 224 * pc.putc(pc.getc() + 1);
pspatel321 31:7eaa5e881b56 225 * }
pspatel321 31:7eaa5e881b56 226 * }
pspatel321 31:7eaa5e881b56 227 * @endcode
pspatel321 31:7eaa5e881b56 228 *
pspatel321 31:7eaa5e881b56 229 * Example with alternate buffer length:
pspatel321 31:7eaa5e881b56 230 * @code
pspatel321 31:7eaa5e881b56 231 * #include "mbed.h"
pspatel321 31:7eaa5e881b56 232 * #include "MODSERIAL.h"
pspatel321 31:7eaa5e881b56 233 *
pspatel321 31:7eaa5e881b56 234 * // Make TX 1024bytes and RX 512byes in length
pspatel321 31:7eaa5e881b56 235 * MODSERIAL pc(USBTX, USBRX, 1024, 512); // tx, rx
pspatel321 31:7eaa5e881b56 236 *
pspatel321 31:7eaa5e881b56 237 * int main() {
pspatel321 31:7eaa5e881b56 238 * pc.printf("Hello World!");
pspatel321 31:7eaa5e881b56 239 * while(1) {
pspatel321 31:7eaa5e881b56 240 * pc.putc(pc.getc() + 1);
pspatel321 31:7eaa5e881b56 241 * }
pspatel321 31:7eaa5e881b56 242 * }
pspatel321 31:7eaa5e881b56 243 * @endcode
pspatel321 31:7eaa5e881b56 244 */
pspatel321 31:7eaa5e881b56 245 class MODSERIAL : public Serial
pspatel321 31:7eaa5e881b56 246 {
pspatel321 31:7eaa5e881b56 247 public:
pspatel321 31:7eaa5e881b56 248
pspatel321 31:7eaa5e881b56 249 // Allow instances of MODSERIAL_IRQ_INFO to use protected properties and methods.
pspatel321 31:7eaa5e881b56 250 friend class MODSERIAL_IRQ_INFO;
pspatel321 31:7eaa5e881b56 251
pspatel321 31:7eaa5e881b56 252 //! A copy of the Serial parity enum
pspatel321 31:7eaa5e881b56 253 /** @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format */
pspatel321 31:7eaa5e881b56 254 enum Parity {
pspatel321 31:7eaa5e881b56 255 None = 0
pspatel321 31:7eaa5e881b56 256 , Odd
pspatel321 31:7eaa5e881b56 257 , Even
pspatel321 31:7eaa5e881b56 258 , Forced1
pspatel321 31:7eaa5e881b56 259 , Forced0
pspatel321 31:7eaa5e881b56 260 };
pspatel321 31:7eaa5e881b56 261
pspatel321 31:7eaa5e881b56 262 //! A copy of the Serial IrqType enum
pspatel321 31:7eaa5e881b56 263 enum IrqType {
pspatel321 31:7eaa5e881b56 264 RxIrq = 0
pspatel321 31:7eaa5e881b56 265 , TxIrq
pspatel321 31:7eaa5e881b56 266 , RxOvIrq
pspatel321 31:7eaa5e881b56 267 , TxOvIrq
pspatel321 31:7eaa5e881b56 268 , TxEmpty
pspatel321 31:7eaa5e881b56 269 , RxAutoDetect
pspatel321 31:7eaa5e881b56 270 , NumOfIrqTypes
pspatel321 31:7eaa5e881b56 271 };
pspatel321 31:7eaa5e881b56 272
pspatel321 31:7eaa5e881b56 273 //! Non-blocking functions return code.
pspatel321 31:7eaa5e881b56 274 enum Result {
pspatel321 31:7eaa5e881b56 275 Ok = 0 /*!< Ok. */
pspatel321 31:7eaa5e881b56 276 , NoMemory = -1 /*!< Memory allocation failed. */
pspatel321 31:7eaa5e881b56 277 , NoChar = -1 /*!< No character in buffer. */
pspatel321 31:7eaa5e881b56 278 , BufferOversize = -2 /*!< Oversized buffer. */
pspatel321 31:7eaa5e881b56 279 };
pspatel321 31:7eaa5e881b56 280
pspatel321 31:7eaa5e881b56 281 /**
pspatel321 31:7eaa5e881b56 282 * The MODSERIAL constructor is used to initialise the serial object.
pspatel321 31:7eaa5e881b56 283 *
pspatel321 31:7eaa5e881b56 284 * @param tx PinName of the TX pin.
pspatel321 31:7eaa5e881b56 285 * @param rx PinName of the TX pin.
pspatel321 31:7eaa5e881b56 286 */
pspatel321 31:7eaa5e881b56 287 MODSERIAL(PinName tx, PinName rx, const char* name = NULL);
pspatel321 31:7eaa5e881b56 288
pspatel321 31:7eaa5e881b56 289 /**
pspatel321 31:7eaa5e881b56 290 * The MODSERIAL constructor is used to initialise the serial object.
pspatel321 31:7eaa5e881b56 291 *
pspatel321 31:7eaa5e881b56 292 * @param tx PinName of the TX pin.
pspatel321 31:7eaa5e881b56 293 * @param rx PinName of the TX pin.
pspatel321 31:7eaa5e881b56 294 * @param bufferSize Integer of the TX and RX buffer sizes.
pspatel321 31:7eaa5e881b56 295 */
pspatel321 31:7eaa5e881b56 296 MODSERIAL(PinName tx, PinName rx, int bufferSize, const char* name = NULL);
pspatel321 31:7eaa5e881b56 297
pspatel321 31:7eaa5e881b56 298 /**
pspatel321 31:7eaa5e881b56 299 * The MODSERIAL constructor is used to initialise the serial object.
pspatel321 31:7eaa5e881b56 300 *
pspatel321 31:7eaa5e881b56 301 * @param tx PinName of the TX pin.
pspatel321 31:7eaa5e881b56 302 * @param rx PinName of the TX pin.
pspatel321 31:7eaa5e881b56 303 * @param txBufferSize Integer of the TX buffer sizes.
pspatel321 31:7eaa5e881b56 304 * @param rxBufferSize Integer of the RX buffer sizes.
pspatel321 31:7eaa5e881b56 305 */
pspatel321 31:7eaa5e881b56 306 MODSERIAL(PinName tx, PinName rx, int txBufferSize, int rxBufferSize, const char* name = NULL);
pspatel321 31:7eaa5e881b56 307
pspatel321 31:7eaa5e881b56 308 virtual ~MODSERIAL();
pspatel321 31:7eaa5e881b56 309
pspatel321 31:7eaa5e881b56 310 /**
pspatel321 31:7eaa5e881b56 311 * Function: attach
pspatel321 31:7eaa5e881b56 312 *
pspatel321 31:7eaa5e881b56 313 * The Mbed standard <a href="/handbook/Serial">Serial</a> library object allows an interrupt callback
pspatel321 31:7eaa5e881b56 314 * to be made when a byte is received by the TX or RX UART hardware. MODSERIAL traps these interrupts
pspatel321 31:7eaa5e881b56 315 * to enable it's buffering system. However, after the byte has been received/sent under interrupt control,
pspatel321 31:7eaa5e881b56 316 * MODSERIAL can callback a user function as a notification of the interrupt. Note, user code should not
pspatel321 31:7eaa5e881b56 317 * directly interact with the Uart hardware, MODSERIAL does that, instead, MODSERIAL API functions should
pspatel321 31:7eaa5e881b56 318 * be used.
pspatel321 31:7eaa5e881b56 319 *
pspatel321 31:7eaa5e881b56 320 * <b>Note</b>, a character is written out then, if there is room in the TX FIFO and the TX buffer is empty,
pspatel321 31:7eaa5e881b56 321 * putc() will put the character directly into THR (the output holding register). If the TX FIFO is full and
pspatel321 31:7eaa5e881b56 322 * cannot accept the character, it is placed into the TX output buffer. The TX interrupts are then enabled
pspatel321 31:7eaa5e881b56 323 * so that when the TX FIFO empties, the TX buffer is then transferred to the THR FIFO. The TxIrq will ONLY
pspatel321 31:7eaa5e881b56 324 * be activated when this transfer of a character from BUFFER to THR FIFO takes place. If your character
pspatel321 31:7eaa5e881b56 325 * throughput is not high bandwidth, then the 16 byte TX FIFO may be enough and the TX output buffer may
pspatel321 31:7eaa5e881b56 326 * never come into play.
pspatel321 31:7eaa5e881b56 327 *
pspatel321 31:7eaa5e881b56 328 * @code
pspatel321 31:7eaa5e881b56 329 * #include "mbed.h"
pspatel321 31:7eaa5e881b56 330 * #include "MODSERIAL.h"
pspatel321 31:7eaa5e881b56 331 *
pspatel321 31:7eaa5e881b56 332 * DigitalOut led1(LED1);
pspatel321 31:7eaa5e881b56 333 * DigitalOut led2(LED2);
pspatel321 31:7eaa5e881b56 334 * DigitalOut led3(LED3);
pspatel321 31:7eaa5e881b56 335 *
pspatel321 31:7eaa5e881b56 336 * // To test, connect p9 to p10 as a loopback.
pspatel321 31:7eaa5e881b56 337 * MODSERIAL pc(p9, p10);
pspatel321 31:7eaa5e881b56 338 *
pspatel321 31:7eaa5e881b56 339 * // This function is called when a character goes into the TX buffer.
pspatel321 31:7eaa5e881b56 340 * void txCallback(void) {
pspatel321 31:7eaa5e881b56 341 * led2 = !led2;
pspatel321 31:7eaa5e881b56 342 * }
pspatel321 31:7eaa5e881b56 343 *
pspatel321 31:7eaa5e881b56 344 * // This function is called when a character goes into the RX buffer.
pspatel321 31:7eaa5e881b56 345 * void rxCallback(void) {
pspatel321 31:7eaa5e881b56 346 * led3 = !led3;
pspatel321 31:7eaa5e881b56 347 * }
pspatel321 31:7eaa5e881b56 348 *
pspatel321 31:7eaa5e881b56 349 * int main() {
pspatel321 31:7eaa5e881b56 350 * pc.baud(115200);
pspatel321 31:7eaa5e881b56 351 * pc.attach(&txCallback, MODSERIAL::TxIrq);
pspatel321 31:7eaa5e881b56 352 * pc.attach(&rxCallback, MODSERIAL::RxIrq);
pspatel321 31:7eaa5e881b56 353 *
pspatel321 31:7eaa5e881b56 354 * while(1) {
pspatel321 31:7eaa5e881b56 355 * led1 = !led1;
pspatel321 31:7eaa5e881b56 356 * wait(0.5);
pspatel321 31:7eaa5e881b56 357 * pc.putc('A');
pspatel321 31:7eaa5e881b56 358 * wait(0.5);
pspatel321 31:7eaa5e881b56 359 * }
pspatel321 31:7eaa5e881b56 360 * ]
pspatel321 31:7eaa5e881b56 361 * @endcode
pspatel321 31:7eaa5e881b56 362 *
pspatel321 31:7eaa5e881b56 363 * @ingroup API
pspatel321 31:7eaa5e881b56 364 * @param fptr A pointer to a void function, or 0 to set as none
pspatel321 31:7eaa5e881b56 365 * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
pspatel321 31:7eaa5e881b56 366 */
pspatel321 31:7eaa5e881b56 367 void attach(void (*fptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { _isr[type].attach(fptr); }
pspatel321 31:7eaa5e881b56 368
pspatel321 31:7eaa5e881b56 369 /**
pspatel321 31:7eaa5e881b56 370 * Function: attach
pspatel321 31:7eaa5e881b56 371 *
pspatel321 31:7eaa5e881b56 372 * The Mbed standard <a href="/handbook/Serial">Serial</a> library object allows an interrupt callback
pspatel321 31:7eaa5e881b56 373 * to be made when a byte is received by the TX or RX UART hardware. MODSERIAL traps these interrupts
pspatel321 31:7eaa5e881b56 374 * to enable it's buffering system. However, after the byte has been received/sent under interrupt control,
pspatel321 31:7eaa5e881b56 375 * MODSERIAL can callback a user function as a notification of the interrupt. Note, user code should not
pspatel321 31:7eaa5e881b56 376 * directly interact with the Uart hardware, MODSERIAL does that, instead, MODSERIAL API functions should
pspatel321 31:7eaa5e881b56 377 * be used.
pspatel321 31:7eaa5e881b56 378 *
pspatel321 31:7eaa5e881b56 379 * <b>Note</b>, a character is written out then, if there is room in the TX FIFO and the TX buffer is empty,
pspatel321 31:7eaa5e881b56 380 * putc() will put the character directly into THR (the output holding register). If the TX FIFO is full and
pspatel321 31:7eaa5e881b56 381 * cannot accept the character, it is placed into the TX output buffer. The TX interrupts are then enabled
pspatel321 31:7eaa5e881b56 382 * so that when the TX FIFO empties, the TX buffer is then transferred to the THR FIFO. The TxIrq will ONLY
pspatel321 31:7eaa5e881b56 383 * be activated when this transfer of a character from BUFFER to THR FIFO takes place. If your character
pspatel321 31:7eaa5e881b56 384 * throughput is not high bandwidth, then the 16 byte TX FIFO may be enough and the TX output buffer may
pspatel321 31:7eaa5e881b56 385 * never come into play.
pspatel321 31:7eaa5e881b56 386 *
pspatel321 31:7eaa5e881b56 387 * @code
pspatel321 31:7eaa5e881b56 388 * #include "mbed.h"
pspatel321 31:7eaa5e881b56 389 * #include "MODSERIAL.h"
pspatel321 31:7eaa5e881b56 390 *
pspatel321 31:7eaa5e881b56 391 * DigitalOut led1(LED1);
pspatel321 31:7eaa5e881b56 392 * DigitalOut led2(LED2);
pspatel321 31:7eaa5e881b56 393 * DigitalOut led3(LED3);
pspatel321 31:7eaa5e881b56 394 *
pspatel321 31:7eaa5e881b56 395 * // To test, connect p9 to p10 as a loopback.
pspatel321 31:7eaa5e881b56 396 * MODSERIAL pc(p9, p10);
pspatel321 31:7eaa5e881b56 397 *
pspatel321 31:7eaa5e881b56 398 * class Foo {
pspatel321 31:7eaa5e881b56 399 * public:
pspatel321 31:7eaa5e881b56 400 * // This method is called when a character goes into the TX buffer.
pspatel321 31:7eaa5e881b56 401 * void txCallback(void) { led2 = !led2; }
pspatel321 31:7eaa5e881b56 402 *
pspatel321 31:7eaa5e881b56 403 * // This method is called when a character goes into the RX buffer.
pspatel321 31:7eaa5e881b56 404 * void rxCallback(void) { led3 = !led3; }
pspatel321 31:7eaa5e881b56 405 * };
pspatel321 31:7eaa5e881b56 406 *
pspatel321 31:7eaa5e881b56 407 * Foo foo;
pspatel321 31:7eaa5e881b56 408 *
pspatel321 31:7eaa5e881b56 409 * int main() {
pspatel321 31:7eaa5e881b56 410 * pc.baud(115200);
pspatel321 31:7eaa5e881b56 411 * pc.attach(&foo, &Foo::txCallback, MODSERIAL::TxIrq);
pspatel321 31:7eaa5e881b56 412 * pc.attach(&foo, &Foo::rxCallback, MODSERIAL::RxIrq);
pspatel321 31:7eaa5e881b56 413 *
pspatel321 31:7eaa5e881b56 414 * while(1) {
pspatel321 31:7eaa5e881b56 415 * led1 = !led1;
pspatel321 31:7eaa5e881b56 416 * wait(0.5);
pspatel321 31:7eaa5e881b56 417 * pc.putc('A');
pspatel321 31:7eaa5e881b56 418 * wait(0.5);
pspatel321 31:7eaa5e881b56 419 * }
pspatel321 31:7eaa5e881b56 420 * ]
pspatel321 31:7eaa5e881b56 421 * @endcode
pspatel321 31:7eaa5e881b56 422 *
pspatel321 31:7eaa5e881b56 423 * @ingroup API
pspatel321 31:7eaa5e881b56 424 * @param tptr A pointer to the object to call the member function on
pspatel321 31:7eaa5e881b56 425 * @param mptr A pointer to the member function to be called
pspatel321 31:7eaa5e881b56 426 * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
pspatel321 31:7eaa5e881b56 427 */
pspatel321 31:7eaa5e881b56 428 template<typename T>
pspatel321 31:7eaa5e881b56 429 void attach(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) {
pspatel321 31:7eaa5e881b56 430 if((mptr != 0) && (tptr != 0)) {
pspatel321 31:7eaa5e881b56 431 _isr[type].attach(tptr, mptr);
pspatel321 31:7eaa5e881b56 432 }
pspatel321 31:7eaa5e881b56 433 }
pspatel321 31:7eaa5e881b56 434
pspatel321 31:7eaa5e881b56 435 /**
pspatel321 31:7eaa5e881b56 436 * @see attach
pspatel321 31:7eaa5e881b56 437 * @ingroup API
pspatel321 31:7eaa5e881b56 438 */
pspatel321 31:7eaa5e881b56 439 void connect(void (*fptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { _isr[RxIrq].attach(fptr); }
pspatel321 31:7eaa5e881b56 440
pspatel321 31:7eaa5e881b56 441 /**
pspatel321 31:7eaa5e881b56 442 * @see attach
pspatel321 31:7eaa5e881b56 443 * @ingroup API
pspatel321 31:7eaa5e881b56 444 */
pspatel321 31:7eaa5e881b56 445 template<typename T>
pspatel321 31:7eaa5e881b56 446 void connect(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) {
pspatel321 31:7eaa5e881b56 447 if((mptr != 0) && (tptr != 0)) {
pspatel321 31:7eaa5e881b56 448 _isr[type].attach(tptr, mptr);
pspatel321 31:7eaa5e881b56 449 }
pspatel321 31:7eaa5e881b56 450 }
pspatel321 31:7eaa5e881b56 451
pspatel321 31:7eaa5e881b56 452 /**
pspatel321 31:7eaa5e881b56 453 * Function: writeable
pspatel321 31:7eaa5e881b56 454 *
pspatel321 31:7eaa5e881b56 455 * Determine if there is space available to write a byte
pspatel321 31:7eaa5e881b56 456 *
pspatel321 31:7eaa5e881b56 457 * @ingroup API
pspatel321 31:7eaa5e881b56 458 * @return 1 if there is space to write a character, else 0
pspatel321 31:7eaa5e881b56 459 */
pspatel321 31:7eaa5e881b56 460 int writeable() { return txBufferFull() ? 0 : 1; }
pspatel321 31:7eaa5e881b56 461
pspatel321 31:7eaa5e881b56 462 /**
pspatel321 31:7eaa5e881b56 463 * Function: readable
pspatel321 31:7eaa5e881b56 464 *
pspatel321 31:7eaa5e881b56 465 * Determine if there is a byte available to read
pspatel321 31:7eaa5e881b56 466 *
pspatel321 31:7eaa5e881b56 467 * @ingroup API
pspatel321 31:7eaa5e881b56 468 * @return 1 if there is a character available to read, else 0
pspatel321 31:7eaa5e881b56 469 */
pspatel321 31:7eaa5e881b56 470 int readable() { return rxBufferEmpty() ? 0 : 1; }
pspatel321 31:7eaa5e881b56 471
pspatel321 31:7eaa5e881b56 472 /**
pspatel321 31:7eaa5e881b56 473 * Function: txBufferSane
pspatel321 31:7eaa5e881b56 474 *
pspatel321 31:7eaa5e881b56 475 * Determine if the TX buffer has been initialized.
pspatel321 31:7eaa5e881b56 476 *
pspatel321 31:7eaa5e881b56 477 * @ingroup API
pspatel321 31:7eaa5e881b56 478 * @return true if the buffer is initialized, else false
pspatel321 31:7eaa5e881b56 479 */
pspatel321 31:7eaa5e881b56 480 bool txBufferSane(void) { return buffer[TxIrq] != (char *)NULL ? true : false; }
pspatel321 31:7eaa5e881b56 481
pspatel321 31:7eaa5e881b56 482 /**
pspatel321 31:7eaa5e881b56 483 * Function: rxBufferSane
pspatel321 31:7eaa5e881b56 484 *
pspatel321 31:7eaa5e881b56 485 * Determine if the RX buffer has been initialized.
pspatel321 31:7eaa5e881b56 486 *
pspatel321 31:7eaa5e881b56 487 * @ingroup API
pspatel321 31:7eaa5e881b56 488 * @return true if the buffer is initialized, else false
pspatel321 31:7eaa5e881b56 489 */
pspatel321 31:7eaa5e881b56 490 bool rxBufferSane(void) { return buffer[TxIrq] != (char *)NULL ? true : false; }
pspatel321 31:7eaa5e881b56 491
pspatel321 31:7eaa5e881b56 492 /**
pspatel321 31:7eaa5e881b56 493 * Function: txBufferGetCount
pspatel321 31:7eaa5e881b56 494 *
pspatel321 31:7eaa5e881b56 495 * Returns how many bytes are in the TX buffer
pspatel321 31:7eaa5e881b56 496 *
pspatel321 31:7eaa5e881b56 497 * @ingroup API
pspatel321 31:7eaa5e881b56 498 * @return The number of bytes in the TX buffer
pspatel321 31:7eaa5e881b56 499 */
pspatel321 31:7eaa5e881b56 500 int txBufferGetCount(void) { return buffer_count[TxIrq]; }
pspatel321 31:7eaa5e881b56 501
pspatel321 31:7eaa5e881b56 502 /**
pspatel321 31:7eaa5e881b56 503 * Function: rxBufferGetCount
pspatel321 31:7eaa5e881b56 504 *
pspatel321 31:7eaa5e881b56 505 * Returns how many bytes are in the RX buffer
pspatel321 31:7eaa5e881b56 506 *
pspatel321 31:7eaa5e881b56 507 * @ingroup API
pspatel321 31:7eaa5e881b56 508 * @return The number of bytes in the RX buffer
pspatel321 31:7eaa5e881b56 509 */
pspatel321 31:7eaa5e881b56 510 int rxBufferGetCount(void) { return buffer_count[RxIrq]; }
pspatel321 31:7eaa5e881b56 511
pspatel321 31:7eaa5e881b56 512 /**
pspatel321 31:7eaa5e881b56 513 * Function: txBufferGetSize
pspatel321 31:7eaa5e881b56 514 *
pspatel321 31:7eaa5e881b56 515 * Returns the current size of the TX buffer
pspatel321 31:7eaa5e881b56 516 *
pspatel321 31:7eaa5e881b56 517 * @ingroup API
pspatel321 31:7eaa5e881b56 518 * @return The length iof the TX buffer in bytes
pspatel321 31:7eaa5e881b56 519 */
pspatel321 31:7eaa5e881b56 520 int txBufferGetSize(int size) { return buffer_size[TxIrq]; }
pspatel321 31:7eaa5e881b56 521
pspatel321 31:7eaa5e881b56 522 /**
pspatel321 31:7eaa5e881b56 523 * Function: rxBufferGetSize
pspatel321 31:7eaa5e881b56 524 *
pspatel321 31:7eaa5e881b56 525 * Returns the current size of the RX buffer
pspatel321 31:7eaa5e881b56 526 *
pspatel321 31:7eaa5e881b56 527 * @ingroup API
pspatel321 31:7eaa5e881b56 528 * @return The length iof the RX buffer in bytes
pspatel321 31:7eaa5e881b56 529 */
pspatel321 31:7eaa5e881b56 530 int rxBufferGetSize(int size) { return buffer_size[RxIrq]; }
pspatel321 31:7eaa5e881b56 531
pspatel321 31:7eaa5e881b56 532 /**
pspatel321 31:7eaa5e881b56 533 * Function: txBufferFull
pspatel321 31:7eaa5e881b56 534 *
pspatel321 31:7eaa5e881b56 535 * Is the TX buffer full?
pspatel321 31:7eaa5e881b56 536 *
pspatel321 31:7eaa5e881b56 537 * @ingroup API
pspatel321 31:7eaa5e881b56 538 * @return true if the TX buffer is full, otherwise false
pspatel321 31:7eaa5e881b56 539 */
pspatel321 31:7eaa5e881b56 540 bool txBufferFull(void);
pspatel321 31:7eaa5e881b56 541
pspatel321 31:7eaa5e881b56 542 /**
pspatel321 31:7eaa5e881b56 543 * Function: rxBufferFull
pspatel321 31:7eaa5e881b56 544 *
pspatel321 31:7eaa5e881b56 545 * Is the RX buffer full?
pspatel321 31:7eaa5e881b56 546 *
pspatel321 31:7eaa5e881b56 547 * @ingroup API
pspatel321 31:7eaa5e881b56 548 * @return true if the RX buffer is full, otherwise false
pspatel321 31:7eaa5e881b56 549 */
pspatel321 31:7eaa5e881b56 550 bool rxBufferFull(void);
pspatel321 31:7eaa5e881b56 551
pspatel321 31:7eaa5e881b56 552 /**
pspatel321 31:7eaa5e881b56 553 * Function: txBufferEmpty
pspatel321 31:7eaa5e881b56 554 *
pspatel321 31:7eaa5e881b56 555 * Is the TX buffer empty?
pspatel321 31:7eaa5e881b56 556 *
pspatel321 31:7eaa5e881b56 557 * @ingroup API
pspatel321 31:7eaa5e881b56 558 * @return true if the TX buffer is empty, otherwise false
pspatel321 31:7eaa5e881b56 559 */
pspatel321 31:7eaa5e881b56 560 bool txBufferEmpty(void);
pspatel321 31:7eaa5e881b56 561
pspatel321 31:7eaa5e881b56 562 /**
pspatel321 31:7eaa5e881b56 563 * Function: rxBufferEmpty
pspatel321 31:7eaa5e881b56 564 *
pspatel321 31:7eaa5e881b56 565 * Is the RX buffer empty?
pspatel321 31:7eaa5e881b56 566 *
pspatel321 31:7eaa5e881b56 567 * @ingroup API
pspatel321 31:7eaa5e881b56 568 * @return true if the RX buffer is empty, otherwise false
pspatel321 31:7eaa5e881b56 569 */
pspatel321 31:7eaa5e881b56 570 bool rxBufferEmpty(void);
pspatel321 31:7eaa5e881b56 571
pspatel321 31:7eaa5e881b56 572 /**
pspatel321 31:7eaa5e881b56 573 * Function: txBufferSetSize
pspatel321 31:7eaa5e881b56 574 *
pspatel321 31:7eaa5e881b56 575 * Change the TX buffer size.
pspatel321 31:7eaa5e881b56 576 *
pspatel321 31:7eaa5e881b56 577 * @see Result
pspatel321 31:7eaa5e881b56 578 * @ingroup API
pspatel321 31:7eaa5e881b56 579 * @param size The new TX buffer size in bytes.
pspatel321 31:7eaa5e881b56 580 * @param m Perform a memory sanity check. Errs the Mbed if memory alloc fails.
pspatel321 31:7eaa5e881b56 581 * @return Result Ok on success.
pspatel321 31:7eaa5e881b56 582 */
pspatel321 31:7eaa5e881b56 583 int txBufferSetSize(int size, bool m) { return resizeBuffer(size, TxIrq, m); }
pspatel321 31:7eaa5e881b56 584
pspatel321 31:7eaa5e881b56 585 /**
pspatel321 31:7eaa5e881b56 586 * Function: rxBufferSetSize
pspatel321 31:7eaa5e881b56 587 *
pspatel321 31:7eaa5e881b56 588 * Change the RX buffer size.
pspatel321 31:7eaa5e881b56 589 *
pspatel321 31:7eaa5e881b56 590 * @see Result
pspatel321 31:7eaa5e881b56 591 * @ingroup API
pspatel321 31:7eaa5e881b56 592 * @param size The new RX buffer size in bytes.
pspatel321 31:7eaa5e881b56 593 * @param m Perform a memory sanity check. Errs the Mbed if memory alloc fails.
pspatel321 31:7eaa5e881b56 594 * @return Result Ok on success.
pspatel321 31:7eaa5e881b56 595 */
pspatel321 31:7eaa5e881b56 596 int rxBufferSetSize(int size, bool m) { return resizeBuffer(size, RxIrq, m); }
pspatel321 31:7eaa5e881b56 597
pspatel321 31:7eaa5e881b56 598 /**
pspatel321 31:7eaa5e881b56 599 * Function: txBufferSetSize
pspatel321 31:7eaa5e881b56 600 *
pspatel321 31:7eaa5e881b56 601 * Change the TX buffer size.
pspatel321 31:7eaa5e881b56 602 * Always performs a memory sanity check, halting the Mbed on failure.
pspatel321 31:7eaa5e881b56 603 *
pspatel321 31:7eaa5e881b56 604 * @see Result
pspatel321 31:7eaa5e881b56 605 * @ingroup API
pspatel321 31:7eaa5e881b56 606 * @param size The new TX buffer size in bytes.
pspatel321 31:7eaa5e881b56 607 * @return Result Ok on success.
pspatel321 31:7eaa5e881b56 608 */
pspatel321 31:7eaa5e881b56 609 int txBufferSetSize(int size) { return resizeBuffer(size, TxIrq, true); }
pspatel321 31:7eaa5e881b56 610
pspatel321 31:7eaa5e881b56 611 /**
pspatel321 31:7eaa5e881b56 612 * Function: rxBufferSetSize
pspatel321 31:7eaa5e881b56 613 *
pspatel321 31:7eaa5e881b56 614 * Change the RX buffer size.
pspatel321 31:7eaa5e881b56 615 * Always performs a memory sanity check, halting the Mbed on failure.
pspatel321 31:7eaa5e881b56 616 *
pspatel321 31:7eaa5e881b56 617 * @see Result
pspatel321 31:7eaa5e881b56 618 * @ingroup API
pspatel321 31:7eaa5e881b56 619 * @param size The new RX buffer size in bytes.
pspatel321 31:7eaa5e881b56 620 * @return Result Ok on success.
pspatel321 31:7eaa5e881b56 621 */
pspatel321 31:7eaa5e881b56 622 int rxBufferSetSize(int size) { return resizeBuffer(size, RxIrq, true); }
pspatel321 31:7eaa5e881b56 623
pspatel321 31:7eaa5e881b56 624 /**
pspatel321 31:7eaa5e881b56 625 * Function: txBufferFlush
pspatel321 31:7eaa5e881b56 626 *
pspatel321 31:7eaa5e881b56 627 * Remove all bytes from the TX buffer.
pspatel321 31:7eaa5e881b56 628 * @ingroup API
pspatel321 31:7eaa5e881b56 629 */
pspatel321 31:7eaa5e881b56 630 void txBufferFlush(void) { flushBuffer(TxIrq); }
pspatel321 31:7eaa5e881b56 631
pspatel321 31:7eaa5e881b56 632 /**
pspatel321 31:7eaa5e881b56 633 * Function: rxBufferFlush
pspatel321 31:7eaa5e881b56 634 *
pspatel321 31:7eaa5e881b56 635 * Remove all bytes from the RX buffer.
pspatel321 31:7eaa5e881b56 636 * @ingroup API
pspatel321 31:7eaa5e881b56 637 */
pspatel321 31:7eaa5e881b56 638 void rxBufferFlush(void) { flushBuffer(RxIrq); }
pspatel321 31:7eaa5e881b56 639
pspatel321 31:7eaa5e881b56 640 /**
pspatel321 31:7eaa5e881b56 641 * Function: getcNb
pspatel321 31:7eaa5e881b56 642 *
pspatel321 31:7eaa5e881b56 643 * Like getc() but is non-blocking. If no bytes are in the RX buffer this
pspatel321 31:7eaa5e881b56 644 * function returns Result::NoChar (-1)
pspatel321 31:7eaa5e881b56 645 *
pspatel321 31:7eaa5e881b56 646 * @ingroup API
pspatel321 31:7eaa5e881b56 647 * @return A byte from the RX buffer or Result::NoChar (-1) if bufer empty.
pspatel321 31:7eaa5e881b56 648 */
pspatel321 31:7eaa5e881b56 649 int getcNb() { return __getc(false); }
pspatel321 31:7eaa5e881b56 650
pspatel321 31:7eaa5e881b56 651 /**
pspatel321 31:7eaa5e881b56 652 * Function: getc
pspatel321 31:7eaa5e881b56 653 *
pspatel321 31:7eaa5e881b56 654 * Overloaded version of Serial::getc()
pspatel321 31:7eaa5e881b56 655 *
pspatel321 31:7eaa5e881b56 656 * This function blocks (if the RX buffer is empty the function will wait for a
pspatel321 31:7eaa5e881b56 657 * character to arrive and then return that character).
pspatel321 31:7eaa5e881b56 658 *
pspatel321 31:7eaa5e881b56 659 * @ingroup API
pspatel321 31:7eaa5e881b56 660 * @return A byte from the RX buffer
pspatel321 31:7eaa5e881b56 661 */
pspatel321 31:7eaa5e881b56 662 int getc() { return __getc(true); }
pspatel321 31:7eaa5e881b56 663
pspatel321 31:7eaa5e881b56 664 /**
pspatel321 31:7eaa5e881b56 665 * Function: txGetLastChar
pspatel321 31:7eaa5e881b56 666 *
pspatel321 31:7eaa5e881b56 667 * Rteurn the last byte to pass through the TX interrupt handler.
pspatel321 31:7eaa5e881b56 668 *
pspatel321 31:7eaa5e881b56 669 * @ingroup MISC
pspatel321 31:7eaa5e881b56 670 * @return The byte
pspatel321 31:7eaa5e881b56 671 */
pspatel321 31:7eaa5e881b56 672 char txGetLastChar(void) { return txc; }
pspatel321 31:7eaa5e881b56 673
pspatel321 31:7eaa5e881b56 674 /**
pspatel321 31:7eaa5e881b56 675 * Function: rxGetLastChar
pspatel321 31:7eaa5e881b56 676 *
pspatel321 31:7eaa5e881b56 677 * Return the last byte to pass through the RX interrupt handler.
pspatel321 31:7eaa5e881b56 678 *
pspatel321 31:7eaa5e881b56 679 * @ingroup MISC
pspatel321 31:7eaa5e881b56 680 * @return The byte
pspatel321 31:7eaa5e881b56 681 */
pspatel321 31:7eaa5e881b56 682 char rxGetLastChar(void) { return rxc; }
pspatel321 31:7eaa5e881b56 683
pspatel321 31:7eaa5e881b56 684 /**
pspatel321 31:7eaa5e881b56 685 * Function: txIsBusy
pspatel321 31:7eaa5e881b56 686 *
pspatel321 31:7eaa5e881b56 687 * If the Uart is still actively sending characters this
pspatel321 31:7eaa5e881b56 688 * function will return true.
pspatel321 31:7eaa5e881b56 689 *
pspatel321 31:7eaa5e881b56 690 * @ingroup API
pspatel321 31:7eaa5e881b56 691 * @return bool
pspatel321 31:7eaa5e881b56 692 */
pspatel321 31:7eaa5e881b56 693 bool txIsBusy(void);
pspatel321 31:7eaa5e881b56 694
pspatel321 31:7eaa5e881b56 695 /**
pspatel321 31:7eaa5e881b56 696 * Function: autoDetectChar
pspatel321 31:7eaa5e881b56 697 *
pspatel321 31:7eaa5e881b56 698 * Set the char that, if seen incoming, invokes the AutoDetectChar callback.
pspatel321 31:7eaa5e881b56 699 *
pspatel321 31:7eaa5e881b56 700 * @ingroup API
pspatel321 31:7eaa5e881b56 701 * @param int c The character to detect.
pspatel321 31:7eaa5e881b56 702 */
pspatel321 31:7eaa5e881b56 703 void autoDetectChar(char c) { auto_detect_char = c; }
pspatel321 31:7eaa5e881b56 704
pspatel321 31:7eaa5e881b56 705 /**
pspatel321 31:7eaa5e881b56 706 * Function: move
pspatel321 31:7eaa5e881b56 707 *
pspatel321 31:7eaa5e881b56 708 * Move contents of RX buffer to external buffer. Stops if "end" detected.
pspatel321 31:7eaa5e881b56 709 *
pspatel321 31:7eaa5e881b56 710 * @ingroup API
pspatel321 31:7eaa5e881b56 711 * @param char *s The destination buffer address
pspatel321 31:7eaa5e881b56 712 * @param int max The maximum number of chars to move.
pspatel321 31:7eaa5e881b56 713 * @param char end If this char is detected stop moving.
pspatel321 31:7eaa5e881b56 714 */
pspatel321 31:7eaa5e881b56 715 int move(char *s, int max, char end) {
pspatel321 31:7eaa5e881b56 716 int counter = 0;
pspatel321 31:7eaa5e881b56 717 char c;
pspatel321 31:7eaa5e881b56 718 while(readable()) {
pspatel321 31:7eaa5e881b56 719 c = getc();
pspatel321 31:7eaa5e881b56 720 if (c == end) break;
pspatel321 31:7eaa5e881b56 721 *(s++) = c;
pspatel321 31:7eaa5e881b56 722 counter++;
pspatel321 31:7eaa5e881b56 723 if (counter == max) break;
pspatel321 31:7eaa5e881b56 724 }
pspatel321 31:7eaa5e881b56 725 return counter;
pspatel321 31:7eaa5e881b56 726 }
pspatel321 31:7eaa5e881b56 727
pspatel321 31:7eaa5e881b56 728 /**
pspatel321 31:7eaa5e881b56 729 * Function: move (overloaded)
pspatel321 31:7eaa5e881b56 730 *
pspatel321 31:7eaa5e881b56 731 * Move contents of RX buffer to external buffer. Stops if auto_detect_char detected.
pspatel321 31:7eaa5e881b56 732 *
pspatel321 31:7eaa5e881b56 733 * @ingroup API
pspatel321 31:7eaa5e881b56 734 * @param int max The maximum number of chars to move.
pspatel321 31:7eaa5e881b56 735 * @param char *s The destination buffer address
pspatel321 31:7eaa5e881b56 736 */
pspatel321 31:7eaa5e881b56 737 int move(char *s, int max) {
pspatel321 31:7eaa5e881b56 738 return move(s, max, auto_detect_char);
pspatel321 31:7eaa5e881b56 739 }
pspatel321 31:7eaa5e881b56 740
pspatel321 31:7eaa5e881b56 741 #if 0 // Inhereted from Serial/Stream, for documentation only
pspatel321 31:7eaa5e881b56 742 /**
pspatel321 31:7eaa5e881b56 743 * Function: putc
pspatel321 31:7eaa5e881b56 744 *
pspatel321 31:7eaa5e881b56 745 * Write a character
pspatel321 31:7eaa5e881b56 746 * Inhereted from Serial/Stream
pspatel321 31:7eaa5e881b56 747 *
pspatel321 31:7eaa5e881b56 748 * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.putc
pspatel321 31:7eaa5e881b56 749 * @ingroup API
pspatel321 31:7eaa5e881b56 750 * @param c The character to write to the serial port
pspatel321 31:7eaa5e881b56 751 */
pspatel321 31:7eaa5e881b56 752 int putc(int c);
pspatel321 31:7eaa5e881b56 753 #endif
pspatel321 31:7eaa5e881b56 754
pspatel321 31:7eaa5e881b56 755 #if 0 // Inhereted from Serial/Stream, for documentation only
pspatel321 31:7eaa5e881b56 756 /**
pspatel321 31:7eaa5e881b56 757 * Function: printf
pspatel321 31:7eaa5e881b56 758 *
pspatel321 31:7eaa5e881b56 759 * Write a formated string
pspatel321 31:7eaa5e881b56 760 * Inhereted from Serial/Stream
pspatel321 31:7eaa5e881b56 761 *
pspatel321 31:7eaa5e881b56 762 * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.printf
pspatel321 31:7eaa5e881b56 763 * @ingroup API
pspatel321 31:7eaa5e881b56 764 * @param format A printf-style format string, followed by the variables to use in formating the string.
pspatel321 31:7eaa5e881b56 765 */
pspatel321 31:7eaa5e881b56 766 int printf(const char* format, ...);
pspatel321 31:7eaa5e881b56 767 #endif
pspatel321 31:7eaa5e881b56 768
pspatel321 31:7eaa5e881b56 769 #if 0 // Inhereted from Serial/Stream, for documentation only
pspatel321 31:7eaa5e881b56 770 /**
pspatel321 31:7eaa5e881b56 771 * Function: scanf
pspatel321 31:7eaa5e881b56 772 *
pspatel321 31:7eaa5e881b56 773 * Read a formated string
pspatel321 31:7eaa5e881b56 774 * Inhereted from Serial/Stream
pspatel321 31:7eaa5e881b56 775 *
pspatel321 31:7eaa5e881b56 776 * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.scanf
pspatel321 31:7eaa5e881b56 777 * @ingroup API
pspatel321 31:7eaa5e881b56 778 * @param format - A scanf-style format string, followed by the pointers to variables to store the results.
pspatel321 31:7eaa5e881b56 779 */
pspatel321 31:7eaa5e881b56 780 int scanf(const char* format, ...);
pspatel321 31:7eaa5e881b56 781 #endif
pspatel321 31:7eaa5e881b56 782
pspatel321 31:7eaa5e881b56 783 protected:
pspatel321 31:7eaa5e881b56 784 /**
pspatel321 31:7eaa5e881b56 785 * Used to pass information to callbacks.
pspatel321 31:7eaa5e881b56 786 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 787 */
pspatel321 31:7eaa5e881b56 788 MODSERIAL_IRQ_INFO callbackInfo;
pspatel321 31:7eaa5e881b56 789
pspatel321 31:7eaa5e881b56 790 /**
pspatel321 31:7eaa5e881b56 791 * Remove the last char placed into the rx buffer.
pspatel321 31:7eaa5e881b56 792 * This is an operation that can only be performed
pspatel321 31:7eaa5e881b56 793 * by an rxCallback function. To protect the buffers
pspatel321 31:7eaa5e881b56 794 * this function is defined protected so that a
pspatel321 31:7eaa5e881b56 795 * regular application cannot call it directly. It
pspatel321 31:7eaa5e881b56 796 * can only be called by the public version within a
pspatel321 31:7eaa5e881b56 797 * MODSERIAL_IRQ_INFO class.
pspatel321 31:7eaa5e881b56 798 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 799 * @return The byte removed from the buffer.
pspatel321 31:7eaa5e881b56 800 */
pspatel321 31:7eaa5e881b56 801 int rxDiscardLastChar(void);
pspatel321 31:7eaa5e881b56 802
pspatel321 31:7eaa5e881b56 803 private:
pspatel321 31:7eaa5e881b56 804
pspatel321 31:7eaa5e881b56 805 /**
pspatel321 31:7eaa5e881b56 806 * A pointer to the UART peripheral base address being used.
pspatel321 31:7eaa5e881b56 807 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 808 */
pspatel321 31:7eaa5e881b56 809 void *_base;
pspatel321 31:7eaa5e881b56 810
pspatel321 31:7eaa5e881b56 811 /**
pspatel321 31:7eaa5e881b56 812 * The last byte to pass through the TX IRQ handler.
pspatel321 31:7eaa5e881b56 813 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 814 */
pspatel321 31:7eaa5e881b56 815 volatile char txc;
pspatel321 31:7eaa5e881b56 816
pspatel321 31:7eaa5e881b56 817 /**
pspatel321 31:7eaa5e881b56 818 * The last byte to pass through the RX IRQ handler.
pspatel321 31:7eaa5e881b56 819 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 820 */
pspatel321 31:7eaa5e881b56 821 volatile char rxc;
pspatel321 31:7eaa5e881b56 822
pspatel321 31:7eaa5e881b56 823 /**
pspatel321 31:7eaa5e881b56 824 * Pointers to the TX and RX buffers.
pspatel321 31:7eaa5e881b56 825 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 826 */
pspatel321 31:7eaa5e881b56 827 volatile char *buffer[2];
pspatel321 31:7eaa5e881b56 828
pspatel321 31:7eaa5e881b56 829 /**
pspatel321 31:7eaa5e881b56 830 * Buffer in pointers.
pspatel321 31:7eaa5e881b56 831 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 832 */
pspatel321 31:7eaa5e881b56 833 volatile int buffer_in[2];
pspatel321 31:7eaa5e881b56 834
pspatel321 31:7eaa5e881b56 835 /**
pspatel321 31:7eaa5e881b56 836 * Buffer out pointers.
pspatel321 31:7eaa5e881b56 837 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 838 */
pspatel321 31:7eaa5e881b56 839 volatile int buffer_out[2];
pspatel321 31:7eaa5e881b56 840
pspatel321 31:7eaa5e881b56 841 /**
pspatel321 31:7eaa5e881b56 842 * Buffer lengths.
pspatel321 31:7eaa5e881b56 843 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 844 */
pspatel321 31:7eaa5e881b56 845 volatile int buffer_size[2];
pspatel321 31:7eaa5e881b56 846
pspatel321 31:7eaa5e881b56 847 /**
pspatel321 31:7eaa5e881b56 848 * Buffer content counters.
pspatel321 31:7eaa5e881b56 849 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 850 */
pspatel321 31:7eaa5e881b56 851 volatile int buffer_count[2];
pspatel321 31:7eaa5e881b56 852
pspatel321 31:7eaa5e881b56 853 /**
pspatel321 31:7eaa5e881b56 854 * Buffer overflow.
pspatel321 31:7eaa5e881b56 855 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 856 */
pspatel321 31:7eaa5e881b56 857 volatile int buffer_overflow[2];
pspatel321 31:7eaa5e881b56 858
pspatel321 31:7eaa5e881b56 859 /**
pspatel321 31:7eaa5e881b56 860 * Auto-detect character.
pspatel321 31:7eaa5e881b56 861 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 862 */
pspatel321 31:7eaa5e881b56 863 volatile char auto_detect_char;
pspatel321 31:7eaa5e881b56 864
pspatel321 31:7eaa5e881b56 865 /**
pspatel321 31:7eaa5e881b56 866 * Callback system.
pspatel321 31:7eaa5e881b56 867 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 868 */
pspatel321 31:7eaa5e881b56 869 MODSERIAL_callback _isr[NumOfIrqTypes];
pspatel321 31:7eaa5e881b56 870
pspatel321 31:7eaa5e881b56 871 /**
pspatel321 31:7eaa5e881b56 872 * TX Interrupt Service Routine.
pspatel321 31:7eaa5e881b56 873 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 874 */
pspatel321 31:7eaa5e881b56 875 void isr_tx(bool doCallback);
pspatel321 31:7eaa5e881b56 876
pspatel321 31:7eaa5e881b56 877 /**
pspatel321 31:7eaa5e881b56 878 * TX Interrupt Service Routine stub version.
pspatel321 31:7eaa5e881b56 879 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 880 */
pspatel321 31:7eaa5e881b56 881 void isr_tx(void) { isr_tx(true); }
pspatel321 31:7eaa5e881b56 882
pspatel321 31:7eaa5e881b56 883
pspatel321 31:7eaa5e881b56 884 /**
pspatel321 31:7eaa5e881b56 885 * RX Interrupt Service Routine.
pspatel321 31:7eaa5e881b56 886 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 887 */
pspatel321 31:7eaa5e881b56 888 void isr_rx(void);
pspatel321 31:7eaa5e881b56 889
pspatel321 31:7eaa5e881b56 890 /**
pspatel321 31:7eaa5e881b56 891 * Disable the interrupts for this Uart.
pspatel321 31:7eaa5e881b56 892 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 893 */
pspatel321 31:7eaa5e881b56 894 void disableIrq(void);
pspatel321 31:7eaa5e881b56 895
pspatel321 31:7eaa5e881b56 896 /**
pspatel321 31:7eaa5e881b56 897 * Enable the interrupts for this Uart.
pspatel321 31:7eaa5e881b56 898 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 899 */
pspatel321 31:7eaa5e881b56 900 void enableIrq(void);
pspatel321 31:7eaa5e881b56 901
pspatel321 31:7eaa5e881b56 902 /**
pspatel321 31:7eaa5e881b56 903 * Get a character from the RX buffer
pspatel321 31:7eaa5e881b56 904 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 905 * @param bool True to block (wait for input)
pspatel321 31:7eaa5e881b56 906 * @return A byte from the buffer.
pspatel321 31:7eaa5e881b56 907 */
pspatel321 31:7eaa5e881b56 908 int __getc(bool);
pspatel321 31:7eaa5e881b56 909
pspatel321 31:7eaa5e881b56 910 /**
pspatel321 31:7eaa5e881b56 911 * Put a character from the TX buffer
pspatel321 31:7eaa5e881b56 912 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 913 * @param bool True to block (wait for space in the TX buffer if full)
pspatel321 31:7eaa5e881b56 914 * @return 0 on success
pspatel321 31:7eaa5e881b56 915 */
pspatel321 31:7eaa5e881b56 916 int __putc(int c, bool);
pspatel321 31:7eaa5e881b56 917
pspatel321 31:7eaa5e881b56 918 /**
pspatel321 31:7eaa5e881b56 919 * Function: _putc
pspatel321 31:7eaa5e881b56 920 * Overloaded virtual function.
pspatel321 31:7eaa5e881b56 921 */
pspatel321 31:7eaa5e881b56 922 virtual int _putc(int c) { return __putc(c, true); }
pspatel321 31:7eaa5e881b56 923
pspatel321 31:7eaa5e881b56 924 /**
pspatel321 31:7eaa5e881b56 925 * Function: _getc
pspatel321 31:7eaa5e881b56 926 * Overloaded virtual function.
pspatel321 31:7eaa5e881b56 927 */
pspatel321 31:7eaa5e881b56 928 virtual int _getc() { return __getc(true); }
pspatel321 31:7eaa5e881b56 929
pspatel321 31:7eaa5e881b56 930 /**
pspatel321 31:7eaa5e881b56 931 * Function: init
pspatel321 31:7eaa5e881b56 932 * Initialize the MODSERIAL object
pspatel321 31:7eaa5e881b56 933 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 934 */
pspatel321 31:7eaa5e881b56 935 void init(int txSize, int rxSize, PinName rx);
pspatel321 31:7eaa5e881b56 936
pspatel321 31:7eaa5e881b56 937 /**
pspatel321 31:7eaa5e881b56 938 * Function: flushBuffer
pspatel321 31:7eaa5e881b56 939 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 940 */
pspatel321 31:7eaa5e881b56 941 void flushBuffer(IrqType type);
pspatel321 31:7eaa5e881b56 942
pspatel321 31:7eaa5e881b56 943 /**
pspatel321 31:7eaa5e881b56 944 * Function: resizeBuffer
pspatel321 31:7eaa5e881b56 945 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 946 */
pspatel321 31:7eaa5e881b56 947 int resizeBuffer(int size, IrqType type = RxIrq, bool memory_check = true);
pspatel321 31:7eaa5e881b56 948
pspatel321 31:7eaa5e881b56 949 /**
pspatel321 31:7eaa5e881b56 950 * Function: downSizeBuffer
pspatel321 31:7eaa5e881b56 951 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 952 */
pspatel321 31:7eaa5e881b56 953 int downSizeBuffer(int size, IrqType type, bool memory_check);
pspatel321 31:7eaa5e881b56 954
pspatel321 31:7eaa5e881b56 955 /**
pspatel321 31:7eaa5e881b56 956 * Function: upSizeBuffer
pspatel321 31:7eaa5e881b56 957 * @ingroup INTERNALS
pspatel321 31:7eaa5e881b56 958 */
pspatel321 31:7eaa5e881b56 959 int upSizeBuffer(int size, IrqType type, bool memory_check);
pspatel321 31:7eaa5e881b56 960
pspatel321 31:7eaa5e881b56 961 /*
pspatel321 31:7eaa5e881b56 962 * If MODDMA is available the compile in code to handle sending
pspatel321 31:7eaa5e881b56 963 * an arbitary char buffer. Note, the parts before teh #ifdef
pspatel321 31:7eaa5e881b56 964 * are declared so that MODSERIAL can access then even if MODDMA
pspatel321 31:7eaa5e881b56 965 * isn't avaiable. Since MODDMA.h is only available at this point
pspatel321 31:7eaa5e881b56 966 * all DMA functionality must be declared inline in the class
pspatel321 31:7eaa5e881b56 967 * definition.
pspatel321 31:7eaa5e881b56 968 */
pspatel321 31:7eaa5e881b56 969 public:
pspatel321 31:7eaa5e881b56 970
pspatel321 31:7eaa5e881b56 971 int dmaSendChannel;
pspatel321 31:7eaa5e881b56 972 void *moddma_p;
pspatel321 31:7eaa5e881b56 973
pspatel321 31:7eaa5e881b56 974 #ifdef MODDMA_H
pspatel321 31:7eaa5e881b56 975
pspatel321 31:7eaa5e881b56 976 MODDMA_Config *config;
pspatel321 31:7eaa5e881b56 977
pspatel321 31:7eaa5e881b56 978 /**
pspatel321 31:7eaa5e881b56 979 * Set the "void pointer" moddma_p to be a pointer to a
pspatel321 31:7eaa5e881b56 980 * MODDMA controller class instance. Used to manage the
pspatel321 31:7eaa5e881b56 981 * data transfer of DMA configurations.
pspatel321 31:7eaa5e881b56 982 *
pspatel321 31:7eaa5e881b56 983 * @ingroup API
pspatel321 31:7eaa5e881b56 984 * @param p A pointer to "the" instance of MODDMA.
pspatel321 31:7eaa5e881b56 985 */
pspatel321 31:7eaa5e881b56 986 void MODDMA(MODDMA *p) { moddma_p = p; }
pspatel321 31:7eaa5e881b56 987
pspatel321 31:7eaa5e881b56 988 /**
pspatel321 31:7eaa5e881b56 989 * Send a char buffer to the Uarts TX system
pspatel321 31:7eaa5e881b56 990 * using DMA. This blocks regular library
pspatel321 31:7eaa5e881b56 991 * sending.
pspatel321 31:7eaa5e881b56 992 *
pspatel321 31:7eaa5e881b56 993 * @param buffer A char buffer of bytes to send.
pspatel321 31:7eaa5e881b56 994 * @param len The length of the buffer to send.
pspatel321 31:7eaa5e881b56 995 * @param dmaChannel The DMA channel to use, defaults to 7
pspatel321 31:7eaa5e881b56 996 * @return MODDMA::Status MODDMA::ok if all went ok
pspatel321 31:7eaa5e881b56 997 */
pspatel321 31:7eaa5e881b56 998 int dmaSend(char *buffer, int len, int dmaChannel = 7)
pspatel321 31:7eaa5e881b56 999 {
pspatel321 31:7eaa5e881b56 1000 if (moddma_p == (void *)NULL) return -2;
pspatel321 31:7eaa5e881b56 1001 class MODDMA *dma = (class MODDMA *)moddma_p;
pspatel321 31:7eaa5e881b56 1002
pspatel321 31:7eaa5e881b56 1003 dmaSendChannel = dmaChannel & 0x7;
pspatel321 31:7eaa5e881b56 1004
pspatel321 31:7eaa5e881b56 1005 uint32_t conn = MODDMA::UART0_Tx;
pspatel321 31:7eaa5e881b56 1006 switch(_serial.index) {
pspatel321 31:7eaa5e881b56 1007 case 0: conn = MODDMA::UART0_Tx; break;
pspatel321 31:7eaa5e881b56 1008 case 1: conn = MODDMA::UART1_Tx; break;
pspatel321 31:7eaa5e881b56 1009 case 2: conn = MODDMA::UART2_Tx; break;
pspatel321 31:7eaa5e881b56 1010 case 3: conn = MODDMA::UART3_Tx; break;
pspatel321 31:7eaa5e881b56 1011 }
pspatel321 31:7eaa5e881b56 1012
pspatel321 31:7eaa5e881b56 1013 config = new MODDMA_Config;
pspatel321 31:7eaa5e881b56 1014 config
pspatel321 31:7eaa5e881b56 1015 ->channelNum ( (MODDMA::CHANNELS)(dmaSendChannel & 0x7) )
pspatel321 31:7eaa5e881b56 1016 ->srcMemAddr ( (uint32_t) buffer )
pspatel321 31:7eaa5e881b56 1017 ->transferSize ( len )
pspatel321 31:7eaa5e881b56 1018 ->transferType ( MODDMA::m2p )
pspatel321 31:7eaa5e881b56 1019 ->dstConn ( conn )
pspatel321 31:7eaa5e881b56 1020 ->attach_tc ( this, &MODSERIAL::dmaSendCallback )
pspatel321 31:7eaa5e881b56 1021 ->attach_err ( this, &MODSERIAL::dmaSendCallback )
pspatel321 31:7eaa5e881b56 1022 ; // config end
pspatel321 31:7eaa5e881b56 1023
pspatel321 31:7eaa5e881b56 1024 // Setup the configuration.
pspatel321 31:7eaa5e881b56 1025 if (dma->Setup(config) == 0) {
pspatel321 31:7eaa5e881b56 1026 return -1;
pspatel321 31:7eaa5e881b56 1027 }
pspatel321 31:7eaa5e881b56 1028
pspatel321 31:7eaa5e881b56 1029 //dma.Enable( MODDMA::Channel_0 );
pspatel321 31:7eaa5e881b56 1030 dma->Enable( config->channelNum() );
pspatel321 31:7eaa5e881b56 1031 return MODDMA::Ok;
pspatel321 31:7eaa5e881b56 1032 }
pspatel321 31:7eaa5e881b56 1033
pspatel321 31:7eaa5e881b56 1034 /**
pspatel321 31:7eaa5e881b56 1035 * Attach a callback to the DMA completion.
pspatel321 31:7eaa5e881b56 1036 *
pspatel321 31:7eaa5e881b56 1037 * @ingroup API
pspatel321 31:7eaa5e881b56 1038 * @param fptr A function pointer to call
pspatel321 31:7eaa5e881b56 1039 * @return this
pspatel321 31:7eaa5e881b56 1040 */
pspatel321 31:7eaa5e881b56 1041 void attach_dmaSendComplete(void (*fptr)(MODSERIAL_IRQ_INFO *)) {
pspatel321 31:7eaa5e881b56 1042 _isrDmaSendComplete.attach(fptr);
pspatel321 31:7eaa5e881b56 1043 }
pspatel321 31:7eaa5e881b56 1044
pspatel321 31:7eaa5e881b56 1045 /**
pspatel321 31:7eaa5e881b56 1046 * Attach a callback to the DMA completion.
pspatel321 31:7eaa5e881b56 1047 *
pspatel321 31:7eaa5e881b56 1048 * @ingroup API
pspatel321 31:7eaa5e881b56 1049 * @param tptr A template pointer to the calling object
pspatel321 31:7eaa5e881b56 1050 * @param mptr A method pointer within the object to call.
pspatel321 31:7eaa5e881b56 1051 * @return this
pspatel321 31:7eaa5e881b56 1052 */
pspatel321 31:7eaa5e881b56 1053 template<typename T>
pspatel321 31:7eaa5e881b56 1054 void attach_dmaSendComplete(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *)) {
pspatel321 31:7eaa5e881b56 1055 if((mptr != NULL) && (tptr != NULL)) {
pspatel321 31:7eaa5e881b56 1056 _isrDmaSendComplete.attach(tptr, mptr);
pspatel321 31:7eaa5e881b56 1057 }
pspatel321 31:7eaa5e881b56 1058 }
pspatel321 31:7eaa5e881b56 1059
pspatel321 31:7eaa5e881b56 1060 MODSERIAL_callback _isrDmaSendComplete;
pspatel321 31:7eaa5e881b56 1061
pspatel321 31:7eaa5e881b56 1062 protected:
pspatel321 31:7eaa5e881b56 1063 /**
pspatel321 31:7eaa5e881b56 1064 * Callback for dmaSend().
pspatel321 31:7eaa5e881b56 1065 */
pspatel321 31:7eaa5e881b56 1066 void dmaSendCallback(void)
pspatel321 31:7eaa5e881b56 1067 {
pspatel321 31:7eaa5e881b56 1068 if (moddma_p == (void *)NULL) return;
pspatel321 31:7eaa5e881b56 1069 class MODDMA *dma = (class MODDMA *)moddma_p;
pspatel321 31:7eaa5e881b56 1070
pspatel321 31:7eaa5e881b56 1071 MODDMA_Config *config = dma->getConfig();
pspatel321 31:7eaa5e881b56 1072 dma->haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
pspatel321 31:7eaa5e881b56 1073 dma->Disable( (MODDMA::CHANNELS)config->channelNum() );
pspatel321 31:7eaa5e881b56 1074 if (dma->irqType() == MODDMA::TcIrq) dma->clearTcIrq();
pspatel321 31:7eaa5e881b56 1075 if (dma->irqType() == MODDMA::ErrIrq) dma->clearErrIrq();
pspatel321 31:7eaa5e881b56 1076 dmaSendChannel = -1;
pspatel321 31:7eaa5e881b56 1077 _isrDmaSendComplete.call(&this->callbackInfo);
pspatel321 31:7eaa5e881b56 1078 delete(config);
pspatel321 31:7eaa5e881b56 1079 }
pspatel321 31:7eaa5e881b56 1080
pspatel321 31:7eaa5e881b56 1081 #endif // MODDMA_H
pspatel321 31:7eaa5e881b56 1082
pspatel321 31:7eaa5e881b56 1083 };
pspatel321 31:7eaa5e881b56 1084
pspatel321 31:7eaa5e881b56 1085 }; // namespace AjK ends
pspatel321 31:7eaa5e881b56 1086
pspatel321 31:7eaa5e881b56 1087 using namespace AjK;
pspatel321 31:7eaa5e881b56 1088
pspatel321 31:7eaa5e881b56 1089 #endif