V.06 11/3

Dependencies:   FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts

Fork of ATT_AWS_IoT_demo by attiot

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MODSERIAL.h Source File

MODSERIAL.h

00001 /*
00002     Copyright (c) 2010 Andy Kirkham
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021     
00022     @file          MODSERIAL.h 
00023     @purpose       Extends Serial to provide fully buffered IO
00024     @version       see ChangeLog.c
00025     @date          Nov 2010
00026     @author        Andy Kirkham
00027 */
00028 
00029 #ifndef MODSERIAL_H
00030 #define MODSERIAL_H
00031 
00032 /** @defgroup API The MODSERIAL API */
00033 /** @defgroup MISC Misc MODSERIAL functions */
00034 /** @defgroup INTERNALS MODSERIAL Internals */
00035 
00036 #ifndef MODSERIAL_DEFAULT_RX_BUFFER_SIZE
00037 #define MODSERIAL_DEFAULT_RX_BUFFER_SIZE    256
00038 #endif
00039 
00040 #ifndef MODSERIAL_DEFAULT_TX_BUFFER_SIZE
00041 #define MODSERIAL_DEFAULT_TX_BUFFER_SIZE    256
00042 #endif
00043 
00044 #include "mbed.h"
00045 #include "serial_api.h"
00046 
00047 namespace AjK {
00048 
00049 // Forward reference.
00050 class MODSERIAL ;
00051 
00052 /**
00053  * @author Andy Kirkham
00054  * @see http://mbed.org/cookbook/MODSERIAL
00055  * @see example3a.cpp
00056  * @see example3b.cpp
00057  * @see API 
00058  *
00059  * <b>MODSERIAL_IRQ_INFO</b> is a class used to pass information (and access to protected
00060  * MODSERIAL functions) to IRQ callbacks. 
00061  */
00062 class MODSERIAL_IRQ_INFO 
00063 {
00064 public:
00065     friend class MODSERIAL ;
00066     
00067     MODSERIAL  *serial;
00068     
00069     MODSERIAL_IRQ_INFO () { serial = 0; }
00070     
00071     /** rxDiscardLastChar()
00072      *
00073      * Remove the last char placed into the rx buffer.
00074      * This is an operation that can only be performed
00075      * by an rxCallback function. 
00076      * @ingroup API
00077      * @return The byte removed from the buffer.
00078      */
00079     int rxDiscardLastChar(void);
00080 
00081 protected:
00082 
00083     /** setSerial()
00084      *
00085      * Used internally by MODSERIAL to set the "this" pointer
00086      * of the MODSERIAL that created this object.
00087      * @ingroup INTERNAL
00088      * @param A pointer to a MODSERIAL object instance.
00089      */
00090     void setSerial(MODSERIAL  *s) { serial = s; }    
00091 };
00092 
00093 // Forward reference dummy class.
00094 class MODSERIAL_callback_dummy;
00095 
00096 /**
00097  * @author Andy Kirkham
00098  * @see http://mbed.org/cookbook/MODSERIAL
00099  * @see example3a.cpp
00100  * @see example3b.cpp
00101  * @see API 
00102  *
00103  * <b>MODSERIAL_callback</b> is a class used to hold application callbacks that
00104  * MODSERIAL can invoke on certain events.
00105  */
00106 class MODSERIAL_callback  
00107 {
00108 protected:
00109 
00110     //! C callback function pointer.
00111     void (*c_callback)(MODSERIAL_IRQ_INFO  *); 
00112     
00113     //! C++ callback object/method pointer (the object part).
00114     MODSERIAL_callback_dummy *obj_callback;
00115     
00116     //! C++ callback object/method pointer (the method part).
00117     void (MODSERIAL_callback_dummy::*method_callback)(MODSERIAL_IRQ_INFO  *);
00118 
00119 public:
00120     
00121     /** Constructor
00122      */
00123     MODSERIAL_callback() {
00124         c_callback      = 0;
00125         obj_callback    = 0;
00126         method_callback = 0;
00127     }
00128     
00129     /** attach - Overloaded attachment function.
00130      *
00131      * Attach a C type function pointer as the callback.
00132      *
00133      * Note, the callback function prototype must be:-
00134      * @code
00135      * void myCallbackFunction(MODSERIAL_IRQ_INFO *);
00136      * @endcode
00137      * @param A C function pointer to call.
00138      */
00139     void attach(void (*function)(MODSERIAL_IRQ_INFO  *) = 0) { c_callback = function; }
00140     
00141     /** attach - Overloaded attachment function.
00142      *
00143      * Attach a C++ type object/method pointer as the callback.
00144      *
00145      * Note, the callback method prototype must be:-
00146      * @code
00147      *     public:
00148      *         void myCallbackFunction(MODSERIAL_IRQ_INFO *);
00149      * @endcode
00150      * @param A C++ object pointer.
00151      * @param A C++ method within the object to call.
00152      */
00153     template<class T> 
00154     void attach(T* item, void (T::*method)(MODSERIAL_IRQ_INFO  *)) { 
00155         obj_callback    = (MODSERIAL_callback_dummy *)item; 
00156         method_callback = (void (MODSERIAL_callback_dummy::*)(MODSERIAL_IRQ_INFO  *))method; 
00157     }
00158 
00159     /** call - Overloaded callback initiator.
00160      *
00161      * call the callback function.
00162      *
00163      * @param A pointer to a MODSERIAL_IRQ_INFO object.
00164      */
00165     void call(MODSERIAL_IRQ_INFO  *arg) {
00166         if (c_callback != 0) {
00167             (*c_callback)(arg);
00168         }
00169         else {
00170             if (obj_callback  != 0 && method_callback != 0) {
00171                 (obj_callback->*method_callback)(arg);
00172             }
00173         }       
00174     }    
00175 };
00176 
00177 /**
00178  * @author Andy Kirkham
00179  * @see http://mbed.org/cookbook/MODSERIAL
00180  * @see http://mbed.org/handbook/Serial
00181  * @see example1.cpp
00182  * @see example2.cpp
00183  * @see example3a.cpp
00184  * @see example3b.cpp
00185  * @see example_dma.cpp
00186  * @see API 
00187  *
00188  * <b>MODSERIAL</b> extends the Mbed library <a href="/handbook/Serial">Serial</a> to provide fully buffered
00189  * TX and RX streams. Buffer length is fully customisable. 
00190  *
00191  * Before using MODSERIAL users should be familar with Mbed's standard <a href="/handbook/Serial">Serial</a>
00192  * library object. MODSERIAL is a direct "drop in" replacement for <a href="/handbook/Serial">Serial</a>. Where
00193  * previously Serial was used, MODSERIAL can be used as adirect replacement instantly offering standard
00194  * TX and RX buffering. By default, both TX and RX buffers are 256 bytes in length.
00195  *
00196  * @image html /media/uploads/mbedofficial/serial_interfaces.png
00197  *
00198  * Standard example:
00199  * @code
00200  * #include "mbed.h"
00201  * #include "MODSERIAL.h"
00202  *
00203  * MODSERIAL pc(USBTX, USBRX); // tx, rx
00204  *
00205  * int main() {
00206  *     pc.printf("Hello World!");
00207  *     while(1) {
00208  *         pc.putc(pc.getc() + 1);
00209  *     }
00210  * }
00211  * @endcode
00212  *
00213  * Example with alternate buffer length:
00214  * @code
00215  * #include "mbed.h"
00216  * #include "MODSERIAL.h"
00217  *
00218  * // Make TX and RX buffers 512byes in length
00219  * MODSERIAL pc(USBTX, USBRX, 512); // tx, rx
00220  *
00221  * int main() {
00222  *     pc.printf("Hello World!");
00223  *     while(1) {
00224  *         pc.putc(pc.getc() + 1);
00225  *     }
00226  * }
00227  * @endcode
00228  *
00229  * Example with alternate buffer length:
00230  * @code
00231  * #include "mbed.h"
00232  * #include "MODSERIAL.h"
00233  *
00234  * // Make TX 1024bytes and RX 512byes in length
00235  * MODSERIAL pc(USBTX, USBRX, 1024, 512); // tx, rx
00236  *
00237  * int main() {
00238  *     pc.printf("Hello World!");
00239  *     while(1) {
00240  *         pc.putc(pc.getc() + 1);
00241  *     }
00242  * }
00243  * @endcode
00244  */
00245 class MODSERIAL  : public Serial 
00246 {
00247 public:
00248 
00249     // Allow instances of MODSERIAL_IRQ_INFO to use protected properties and methods.
00250     friend class MODSERIAL_IRQ_INFO ;
00251 
00252     //! A copy of the Serial parity enum
00253     /** @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format */
00254     enum Parity {
00255           None = 0
00256         , Odd
00257         , Even
00258         , Forced1   
00259         , Forced0
00260     };
00261     
00262     //! A copy of the Serial IrqType enum
00263     enum IrqType {
00264           RxIrq = 0
00265         , TxIrq
00266         , RxOvIrq
00267         , TxOvIrq
00268         , TxEmpty
00269         , RxAutoDetect
00270         , NumOfIrqTypes
00271     };
00272     
00273     //! Non-blocking functions return code.
00274     enum Result {
00275           Ok  = 0                /*!< Ok. */
00276         , NoMemory        = -1   /*!< Memory allocation failed. */
00277         , NoChar          = -1   /*!< No character in buffer. */
00278         , BufferOversize  = -2   /*!< Oversized buffer. */
00279     };
00280     
00281     /**
00282      * The MODSERIAL constructor is used to initialise the serial object.
00283      *
00284      * @param tx PinName of the TX pin.
00285      * @param rx PinName of the TX pin.
00286      */    
00287     MODSERIAL(PinName tx, PinName rx, const char* name = NULL);
00288     
00289     /**
00290      * The MODSERIAL constructor is used to initialise the serial object.
00291      *
00292      * @param tx PinName of the TX pin.
00293      * @param rx PinName of the TX pin.
00294      * @param bufferSize Integer of the TX and RX buffer sizes.
00295      */    
00296     MODSERIAL(PinName tx, PinName rx, int bufferSize, const char* name = NULL);
00297     
00298     /**
00299      * The MODSERIAL constructor is used to initialise the serial object.
00300      *
00301      * @param tx PinName of the TX pin.
00302      * @param rx PinName of the TX pin.
00303      * @param txBufferSize Integer of the TX buffer sizes.
00304      * @param rxBufferSize Integer of the RX buffer sizes.
00305      */    
00306     MODSERIAL(PinName tx, PinName rx, int txBufferSize, int rxBufferSize, const char* name = NULL);
00307     
00308     virtual ~MODSERIAL ();
00309 
00310     /**
00311      * Function: attach
00312      *  
00313      * The Mbed standard <a href="/handbook/Serial">Serial</a> library object allows an interrupt callback
00314      * to be made when a byte is received by the TX or RX UART hardware. MODSERIAL traps these interrupts
00315      * to enable it's buffering system. However, after the byte has been received/sent under interrupt control, 
00316      * MODSERIAL can callback a user function as a notification of the interrupt. Note, user code should not
00317      * directly interact with the Uart hardware, MODSERIAL does that, instead, MODSERIAL API functions should
00318      * be used.
00319      *
00320      * <b>Note</b>, a character is written out then, if there is room in the TX FIFO and the TX buffer is empty,
00321      * putc() will put the character directly into THR (the output holding register). If the TX FIFO is full and 
00322      * cannot accept the character, it is placed into the TX output buffer. The TX interrupts are then enabled
00323      * so that when the TX FIFO empties, the TX buffer is then transferred to the THR FIFO. The TxIrq will ONLY 
00324      * be activated when this transfer of a character from BUFFER to THR FIFO takes place. If your character 
00325      * throughput is not high bandwidth, then the 16 byte TX FIFO may be enough and the TX output buffer may 
00326      * never come into play.
00327      *
00328      * @code
00329      * #include "mbed.h"
00330      * #include "MODSERIAL.h"
00331      *
00332      * DigitalOut led1(LED1);
00333      * DigitalOut led2(LED2);
00334      * DigitalOut led3(LED3);
00335      *
00336      * // To test, connect p9 to p10 as a loopback.
00337      * MODSERIAL pc(p9, p10);
00338      *
00339      * // This function is called when a character goes into the TX buffer.
00340      * void txCallback(void) {
00341      *     led2 = !led2;
00342      * }
00343      *
00344      * // This function is called when a character goes into the RX buffer.
00345      * void rxCallback(void) {
00346      *     led3 = !led3;
00347      * }
00348      *
00349      * int main() {
00350      *     pc.baud(115200);
00351      *     pc.attach(&txCallback, MODSERIAL::TxIrq);
00352      *     pc.attach(&rxCallback, MODSERIAL::RxIrq);
00353      *
00354      *     while(1) {
00355      *         led1 = !led1;
00356      *         wait(0.5);
00357      *         pc.putc('A');
00358      *         wait(0.5);
00359      *     }
00360      * ]
00361      * @endcode
00362      *
00363      * @ingroup API
00364      * @param fptr A pointer to a void function, or 0 to set as none
00365      * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
00366      */  
00367     void attach(void (*fptr)(MODSERIAL_IRQ_INFO  *), IrqType type = RxIrq) { _isr[type].attach(fptr); }
00368     
00369     /**
00370      * Function: attach
00371      *  
00372      * The Mbed standard <a href="/handbook/Serial">Serial</a> library object allows an interrupt callback
00373      * to be made when a byte is received by the TX or RX UART hardware. MODSERIAL traps these interrupts
00374      * to enable it's buffering system. However, after the byte has been received/sent under interrupt control, 
00375      * MODSERIAL can callback a user function as a notification of the interrupt. Note, user code should not
00376      * directly interact with the Uart hardware, MODSERIAL does that, instead, MODSERIAL API functions should
00377      * be used.
00378      *
00379      * <b>Note</b>, a character is written out then, if there is room in the TX FIFO and the TX buffer is empty,
00380      * putc() will put the character directly into THR (the output holding register). If the TX FIFO is full and 
00381      * cannot accept the character, it is placed into the TX output buffer. The TX interrupts are then enabled
00382      * so that when the TX FIFO empties, the TX buffer is then transferred to the THR FIFO. The TxIrq will ONLY 
00383      * be activated when this transfer of a character from BUFFER to THR FIFO takes place. If your character 
00384      * throughput is not high bandwidth, then the 16 byte TX FIFO may be enough and the TX output buffer may 
00385      * never come into play.
00386      *
00387      * @code
00388      * #include "mbed.h"
00389      * #include "MODSERIAL.h"
00390      *
00391      * DigitalOut led1(LED1);
00392      * DigitalOut led2(LED2);
00393      * DigitalOut led3(LED3);
00394      *
00395      * // To test, connect p9 to p10 as a loopback.
00396      * MODSERIAL pc(p9, p10);
00397      *
00398      * class Foo {
00399      * public:
00400      *     // This method is called when a character goes into the TX buffer.
00401      *     void txCallback(void) { led2 = !led2; }
00402      *
00403      *     // This method is called when a character goes into the RX buffer.
00404      *     void rxCallback(void) { led3 = !led3; }
00405      * };
00406      *
00407      * Foo foo;
00408      *
00409      * int main() {
00410      *     pc.baud(115200);
00411      *     pc.attach(&foo, &Foo::txCallback, MODSERIAL::TxIrq);
00412      *     pc.attach(&foo, &Foo::rxCallback, MODSERIAL::RxIrq);
00413      *
00414      *     while(1) {
00415      *         led1 = !led1;
00416      *         wait(0.5);
00417      *         pc.putc('A');
00418      *         wait(0.5);
00419      *     }
00420      * ]
00421      * @endcode
00422      *     
00423      * @ingroup API
00424      * @param  tptr A pointer to the object to call the member function on
00425      * @param  mptr A pointer to the member function to be called
00426      * @param  type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
00427      */
00428     template<typename T>
00429     void attach(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO  *), IrqType type = RxIrq) {
00430         if((mptr != 0) && (tptr != 0)) {
00431             _isr[type].attach(tptr, mptr);            
00432         }
00433     }
00434 
00435     /**
00436      * @see attach
00437      * @ingroup API
00438      */
00439     void connect (void (*fptr)(MODSERIAL_IRQ_INFO  *), IrqType type = RxIrq) { _isr[RxIrq].attach(fptr); }
00440     
00441     /**
00442      * @see attach
00443      * @ingroup API
00444      */
00445     template<typename T>
00446     void connect (T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO  *), IrqType type = RxIrq) {
00447         if((mptr != 0) && (tptr != 0)) {
00448             _isr[type].attach(tptr, mptr);            
00449         }
00450     }
00451     
00452     /**
00453      * Function: writeable
00454      *  
00455      * Determine if there is space available to write a byte
00456      *
00457      * @ingroup API
00458      * @return 1 if there is space to write a character, else 0
00459      */
00460     int writeable() { return txBufferFull() ? 0 : 1; }
00461     
00462     /**
00463      * Function: readable
00464      *  
00465      * Determine if there is a byte available to read
00466      *
00467      * @ingroup API
00468      * @return 1 if there is a character available to read, else 0
00469      */
00470     int readable() { return rxBufferEmpty() ? 0 : 1; } 
00471     
00472     /**
00473      * Function: txBufferSane
00474      *  
00475      * Determine if the TX buffer has been initialized.
00476      *
00477      * @ingroup API
00478      * @return true if the buffer is initialized, else false
00479      */
00480     bool txBufferSane(void) { return buffer[TxIrq] != (char *)NULL ? true : false; }
00481     
00482     /**
00483      * Function: rxBufferSane
00484      *  
00485      * Determine if the RX buffer has been initialized.
00486      *
00487      * @ingroup API
00488      * @return true if the buffer is initialized, else false
00489      */
00490     bool rxBufferSane(void) { return buffer[TxIrq] != (char *)NULL ? true : false; }
00491     
00492     /**
00493      * Function: txBufferGetCount
00494      *  
00495      * Returns how many bytes are in the TX buffer
00496      *
00497      * @ingroup API
00498      * @return The number of bytes in the TX buffer
00499      */
00500     int txBufferGetCount(void)    { return buffer_count[TxIrq]; }
00501     
00502     /**
00503      * Function: rxBufferGetCount
00504      *  
00505      * Returns how many bytes are in the RX buffer
00506      *
00507      * @ingroup API
00508      * @return The number of bytes in the RX buffer
00509      */
00510     int rxBufferGetCount(void)    { return buffer_count[RxIrq]; }
00511     
00512     /**
00513      * Function: txBufferGetSize
00514      *  
00515      * Returns the current size of the TX buffer
00516      *
00517      * @ingroup API
00518      * @return The length iof the TX buffer in bytes
00519      */
00520     int txBufferGetSize(int size) { return buffer_size[TxIrq]; } 
00521     
00522     /**
00523      * Function: rxBufferGetSize
00524      *  
00525      * Returns the current size of the RX buffer
00526      *
00527      * @ingroup API
00528      * @return The length iof the RX buffer in bytes
00529      */
00530     int rxBufferGetSize(int size) { return buffer_size[RxIrq]; } 
00531     
00532     /**
00533      * Function: txBufferFull
00534      *  
00535      * Is the TX buffer full?
00536      *
00537      * @ingroup API
00538      * @return true if the TX buffer is full, otherwise false
00539      */
00540     bool txBufferFull(void);
00541     
00542     /**
00543      * Function: rxBufferFull
00544      *  
00545      * Is the RX buffer full?
00546      *
00547      * @ingroup API
00548      * @return true if the RX buffer is full, otherwise false
00549      */
00550     bool rxBufferFull(void);
00551     
00552     /**
00553      * Function: txBufferEmpty
00554      *  
00555      * Is the TX buffer empty?
00556      *
00557      * @ingroup API
00558      * @return true if the TX buffer is empty, otherwise false
00559      */
00560     bool txBufferEmpty(void);
00561     
00562     /**
00563      * Function: rxBufferEmpty
00564      *  
00565      * Is the RX buffer empty?
00566      *
00567      * @ingroup API
00568      * @return true if the RX buffer is empty, otherwise false
00569      */
00570     bool rxBufferEmpty(void);
00571     
00572     /**
00573      * Function: txBufferSetSize
00574      *  
00575      * Change the TX buffer size.
00576      *
00577      * @see Result
00578      * @ingroup API
00579      * @param size The new TX buffer size in bytes.
00580      * @param m Perform a memory sanity check. Errs the Mbed if memory alloc fails.
00581      * @return Result Ok on success.
00582      */
00583     int txBufferSetSize(int size, bool m) { return resizeBuffer(size, TxIrq, m); } 
00584     
00585     /**
00586      * Function: rxBufferSetSize
00587      *  
00588      * Change the RX buffer size.
00589      *
00590      * @see Result
00591      * @ingroup API
00592      * @param size The new RX buffer size in bytes.
00593      * @param m Perform a memory sanity check. Errs the Mbed if memory alloc fails.
00594      * @return Result Ok on success.
00595      */
00596     int rxBufferSetSize(int size, bool m) { return resizeBuffer(size, RxIrq, m); } 
00597     
00598     /**
00599      * Function: txBufferSetSize
00600      *  
00601      * Change the TX buffer size.
00602      * Always performs a memory sanity check, halting the Mbed on failure.
00603      *
00604      * @see Result
00605      * @ingroup API
00606      * @param size The new TX buffer size in bytes.
00607      * @return Result Ok on success.
00608      */
00609     int txBufferSetSize(int size) { return resizeBuffer(size, TxIrq, true); } 
00610     
00611     /**
00612      * Function: rxBufferSetSize
00613      *  
00614      * Change the RX buffer size.
00615      * Always performs a memory sanity check, halting the Mbed on failure.
00616      *
00617      * @see Result
00618      * @ingroup API
00619      * @param size The new RX buffer size in bytes.
00620      * @return Result Ok on success.
00621      */
00622     int rxBufferSetSize(int size) { return resizeBuffer(size, RxIrq, true); } 
00623     
00624     /**
00625      * Function: txBufferFlush
00626      *  
00627      * Remove all bytes from the TX buffer.
00628      * @ingroup API
00629      */
00630     void txBufferFlush(void) { flushBuffer(TxIrq); }
00631     
00632     /**
00633      * Function: rxBufferFlush
00634      *  
00635      * Remove all bytes from the RX buffer.
00636      * @ingroup API
00637      */
00638     void rxBufferFlush(void) { flushBuffer(RxIrq); }
00639         
00640     /**
00641      * Function: getcNb
00642      *
00643      * Like getc() but is non-blocking. If no bytes are in the RX buffer this
00644      * function returns Result::NoChar (-1)
00645      *
00646      * @ingroup API
00647      * @return A byte from the RX buffer or Result::NoChar (-1) if bufer empty.
00648      */
00649     int getcNb() { return __getc(false); }
00650     
00651     /**
00652      * Function: getc
00653      *
00654      * Overloaded version of Serial::getc()
00655      * 
00656      * This function blocks (if the RX buffer is empty the function will wait for a
00657      * character to arrive and then return that character).
00658      *
00659      * @ingroup API
00660      * @return A byte from the RX buffer
00661      */
00662     int getc()   { return __getc(true);  }
00663     
00664     /**
00665      * Function: txGetLastChar
00666      *
00667      * Rteurn the last byte to pass through the TX interrupt handler.
00668      *
00669      * @ingroup MISC
00670      * @return The byte
00671      */
00672     char txGetLastChar(void) { return txc; }
00673     
00674     /**
00675      * Function: rxGetLastChar
00676      *
00677      * Return the last byte to pass through the RX interrupt handler.
00678      *
00679      * @ingroup MISC
00680      * @return The byte
00681      */
00682     char rxGetLastChar(void) { return rxc; }
00683     
00684 
00685     
00686     /**
00687      * Function: autoDetectChar
00688      *
00689      * Set the char that, if seen incoming, invokes the AutoDetectChar callback.
00690      *
00691      * @ingroup API
00692      * @param int c The character to detect.
00693      */
00694     void autoDetectChar(char c) { auto_detect_char = c; }
00695     
00696     /**
00697      * Function: move
00698      *
00699      * Move contents of RX buffer to external buffer. Stops if "end" detected.
00700      *
00701      * @ingroup API
00702      * @param char *s The destination buffer address
00703      * @param int max The maximum number of chars to move.
00704      * @param char end If this char is detected stop moving.
00705      */
00706     int move(char *s, int max, char end) {
00707         int counter = 0;
00708         char c;
00709         while(readable()) {
00710             c = getc();
00711             if (c == end) break;
00712             *(s++) = c;
00713             counter++;
00714             if (counter == max) break;
00715         }
00716         return counter;
00717     }
00718     
00719     /**
00720      * Function: move (overloaded)
00721      *
00722      * Move contents of RX buffer to external buffer. Stops if auto_detect_char detected.
00723      *
00724      * @ingroup API
00725      * @param int max The maximum number of chars to move.
00726      * @param char *s The destination buffer address
00727      */
00728     int move(char *s, int max) {
00729         return move(s, max, auto_detect_char);
00730     }
00731     
00732     /**
00733     * Function: claim
00734     *
00735     * Redirect a stream to this MODSERIAL object
00736     *
00737     * Important: A name parameter must have been added when creating the MODSERIAL object:
00738     *
00739     * @code
00740     * #include "MODSERIAL.h"
00741     * ...
00742     * MODSERIAL pc(USBTX, USBRX, "modser");
00743     * 
00744     * int main() {
00745     *   pc.claim()            // capture <stdout>
00746     *   pc.printf("Uses the MODSERIAL library\r\n");
00747     *   printf("So does this!\r\n");
00748     * }
00749     * @endcode
00750     *
00751     * @ingroup API
00752     * @param FILE *stream The stream to redirect (default = stdout)
00753     * @return true if succeeded, else false
00754     */    
00755     bool claim(FILE *stream = stdout);
00756     
00757     #if 0 // Inhereted from Serial/Stream, for documentation only
00758     /**
00759      * Function: putc
00760      * 
00761      * Write a character
00762      * Inhereted from Serial/Stream
00763      *
00764      * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.putc
00765      * @ingroup API
00766      * @param c The character to write to the serial port
00767      */
00768     int putc(int c);
00769     #endif
00770     
00771     #if 0 // Inhereted from Serial/Stream, for documentation only
00772     /**
00773      * Function: printf
00774      *  
00775      * Write a formated string
00776      * Inhereted from Serial/Stream
00777      *
00778      * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.printf
00779      * @ingroup API
00780      * @param format A printf-style format string, followed by the variables to use in formating the string.
00781      */
00782     int printf(const char* format, ...);
00783     #endif
00784     
00785     #if 0 // Inhereted from Serial/Stream, for documentation only
00786     /**
00787      * Function: scanf
00788      *  
00789      * Read a formated string
00790      * Inhereted from Serial/Stream
00791      *
00792      * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.scanf
00793      * @ingroup API
00794      * @param format - A scanf-style format string, followed by the pointers to variables to store the results.
00795      */
00796     int scanf(const char* format, ...);
00797     #endif
00798 
00799 protected:    
00800     /**
00801      * Used to pass information to callbacks.
00802      * @ingroup INTERNALS
00803      */
00804     MODSERIAL_IRQ_INFO  callbackInfo;
00805 
00806     /**
00807      * Remove the last char placed into the rx buffer.
00808      * This is an operation that can only be performed
00809      * by an rxCallback function. To protect the buffers
00810      * this function is defined protected so that a 
00811      * regular application cannot call it directly. It 
00812      * can only be called by the public version within a
00813      * MODSERIAL_IRQ_INFO class.
00814      * @ingroup INTERNALS
00815      * @return The byte removed from the buffer.
00816      */
00817     int rxDiscardLastChar(void);    
00818             
00819 private:
00820 
00821     /**
00822      * A pointer to the UART peripheral base address being used.
00823      * @ingroup INTERNALS
00824      */
00825     void *_base;
00826     
00827     /**
00828      * The last byte to pass through the TX IRQ handler.
00829      * @ingroup INTERNALS
00830      */
00831     volatile char txc;
00832     
00833     /**
00834      * The last byte to pass through the RX IRQ handler.
00835      * @ingroup INTERNALS
00836      */
00837     volatile char rxc;
00838     
00839     /**
00840      * Pointers to the TX and RX buffers.
00841      * @ingroup INTERNALS
00842      */
00843     volatile char *buffer[2];
00844     
00845     /**
00846      * Buffer in pointers.
00847      * @ingroup INTERNALS
00848      */
00849     volatile int   buffer_in[2];
00850     
00851     /**
00852      * Buffer out pointers.
00853      * @ingroup INTERNALS
00854      */
00855     volatile int   buffer_out[2];
00856     
00857     /**
00858      * Buffer lengths.
00859      * @ingroup INTERNALS
00860      */
00861     volatile int   buffer_size[2];
00862     
00863     /**
00864      * Buffer content counters.
00865      * @ingroup INTERNALS
00866      */
00867     volatile int   buffer_count[2];
00868     
00869     /**
00870      * Buffer overflow.
00871      * @ingroup INTERNALS
00872      */
00873     volatile int   buffer_overflow[2];
00874     
00875     /**
00876      * Auto-detect character.
00877      * @ingroup INTERNALS
00878      */
00879     volatile char auto_detect_char;
00880     
00881     /**
00882      * Callback system.
00883      * @ingroup INTERNALS
00884      */
00885     MODSERIAL_callback  _isr[NumOfIrqTypes];
00886     
00887     /**
00888      * TX Interrupt Service Routine.
00889      * @ingroup INTERNALS
00890      */
00891     void isr_tx(bool doCallback);
00892     
00893     /**
00894      * TX Interrupt Service Routine stub version.
00895      * @ingroup INTERNALS
00896      */ 
00897     void isr_tx(void) { isr_tx(true); }
00898     
00899     
00900     /**
00901      * RX Interrupt Service Routine.
00902      * @ingroup INTERNALS
00903      */
00904     void isr_rx(void);
00905     
00906         /**
00907      * Get a character from the RX buffer
00908      * @ingroup INTERNALS
00909      * @param bool True to block (wait for input)
00910      * @return A byte from the buffer.
00911      */
00912     int __getc(bool);
00913     
00914     /**
00915      * Put a character from the TX buffer
00916      * @ingroup INTERNALS
00917      * @param bool True to block (wait for space in the TX buffer if full)
00918      * @return 0 on success
00919      */
00920     int __putc(int c, bool);
00921     
00922     /**
00923      * Function: _putc 
00924      * Overloaded virtual function.
00925      */
00926     virtual int _putc(int c) { return __putc(c, true); }
00927     
00928     /**
00929      * Function: _getc 
00930      * Overloaded virtual function.
00931      */
00932     virtual int _getc()      { return __getc(true); }
00933         
00934     /** 
00935      * Function: init
00936      * Initialize the MODSERIAL object
00937      * @ingroup INTERNALS
00938      */
00939     void init(int txSize, int rxSize, PinName rx);
00940     
00941     /** 
00942      * Function: flushBuffer
00943      * @ingroup INTERNALS
00944      */
00945     void flushBuffer(IrqType type);
00946 
00947     /** 
00948      * Function: resizeBuffer
00949      * @ingroup INTERNALS
00950      */
00951     int resizeBuffer(int size, IrqType type = RxIrq, bool memory_check = true);   
00952        
00953     /** 
00954      * Function: moveRingBuffer
00955      * @ingroup INTERNALS
00956      */
00957     void moveRingBuffer(char * newBuffer, IrqType type);
00958     
00959     
00960 
00961 
00962 //DEVICE SPECIFIC FUNCTIONS:
00963     private:
00964     /**
00965     * Set pointers to UART and IRQ
00966     */
00967     void setBase( void );
00968     
00969     /**
00970     * If required, allows for adding specific settings
00971     */
00972     void initDevice( void );
00973     
00974     IRQn_Type _IRQ;
00975     
00976     public:
00977      /**
00978      * Function: txIsBusy
00979      *
00980      * If the Uart is still actively sending characters this
00981      * function will return true.
00982      *
00983      * @ingroup API
00984      * @return bool
00985      */
00986     bool txIsBusy(void);
00987     
00988 
00989 };
00990 
00991 }; // namespace AjK ends
00992 
00993 using namespace AjK;
00994 
00995 #endif
00996 
00997