MODSERIAL with support for more devices

Fork of MODSERIAL by Erik -

Committer:
AjK
Date:
Tue Nov 23 21:34:54 2010 +0000
Revision:
9:b3cdae80e7a9
Parent:
8:775f860e94d3
Child:
10:725fe81aa9ff
1.9

Who changed what in which revision?

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