Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MODSERIAL by
Diff: MODSERIAL.h
- Revision:
- 18:21ef26402365
- Parent:
- 17:6c9b57c14868
- Child:
- 19:a158936322cc
--- a/MODSERIAL.h Tue Mar 08 01:42:25 2011 +0000 +++ b/MODSERIAL.h Thu Apr 21 09:20:41 2011 +0000 @@ -45,6 +45,135 @@ namespace AjK { +// Forward reference. +class MODSERIAL; + +/** + * @author Andy Kirkham + * @see http://mbed.org/cookbook/MODSERIAL + * @see example3a.cpp + * @see example3b.cpp + * @see API + * + * <b>MODSERIAL_IRQ_INFO</b> is a class used to pass information (and access to protected + * MODSERIAL functions) to IRQ callbacks. + */ +class MODSERIAL_IRQ_INFO +{ +public: + friend class MODSERIAL; + + MODSERIAL *serial; + + MODSERIAL_IRQ_INFO() { serial = 0; } + + /** rxDiscardLastChar() + * + * Remove the last char placed into the rx buffer. + * This is an operation that can only be performed + * by an rxCallback function. + * @ingroup API + * @return The byte removed from the buffer. + */ + int rxDiscardLastChar(void); + +protected: + + /** setSerial() + * + * Used internally by MODSERIAL to set the "this" pointer + * of the MODSERIAL that created this object. + * @ingroup INTERNAL + * @param A pointer to a MODSERIAL object instance. + */ + void setSerial(MODSERIAL *s) { serial = s; } +}; + +// Forward reference dummy class. +class MODSERIAL_callback_dummy; + +/** + * @author Andy Kirkham + * @see http://mbed.org/cookbook/MODSERIAL + * @see example3a.cpp + * @see example3b.cpp + * @see API + * + * <b>MODSERIAL_callback</b> is a class used to hold application callbacks that + * MODSERIAL can invoke on certain events. + */ +class MODSERIAL_callback +{ +protected: + + //! C callback function pointer. + void (*c_callback)(MODSERIAL_IRQ_INFO *); + + //! C++ callback object/method pointer (the object part). + MODSERIAL_callback_dummy *obj_callback; + + //! C++ callback object/method pointer (the method part). + void (MODSERIAL_callback_dummy::*method_callback)(MODSERIAL_IRQ_INFO *); + +public: + + /** Constructor + */ + MODSERIAL_callback() { + c_callback = 0; + obj_callback = 0; + method_callback = 0; + } + + /** attach - Overloaded attachment function. + * + * Attach a C type function pointer as the callback. + * + * Note, the callback function prototype must be:- + * @code + * void myCallbackFunction(MODSERIAL_IRQ_INFO *); + * @endcode + * @param A C function pointer to call. + */ + void attach(void (*function)(MODSERIAL_IRQ_INFO *) = 0) { c_callback = function; } + + /** attach - Overloaded attachment function. + * + * Attach a C++ type object/method pointer as the callback. + * + * Note, the callback method prototype must be:- + * @code + * public: + * void myCallbackFunction(MODSERIAL_IRQ_INFO *); + * @endcode + * @param A C++ object pointer. + * @param A C++ method within the object to call. + */ + template<class T> + void attach(T* item, void (T::*method)(MODSERIAL_IRQ_INFO *)) { + obj_callback = (MODSERIAL_callback_dummy *)item; + method_callback = (void (MODSERIAL_callback_dummy::*)(MODSERIAL_IRQ_INFO *))method; + } + + /** call - Overloaded callback initiator. + * + * call the callback function. + * + * @param uint32_t The value to pass to the callback. + * @return uint32_t The value the callback returns. + */ + void call(MODSERIAL_IRQ_INFO *arg) { + if (c_callback != 0) { + (*c_callback)(arg); + } + else { + if (obj_callback != 0 && method_callback != 0) { + (obj_callback->*method_callback)(arg); + } + } + } +}; + /** * @author Andy Kirkham * @see http://mbed.org/cookbook/MODSERIAL @@ -113,6 +242,9 @@ { public: + // Allow instances of MODSERIAL_IRQ_INFO to use protected properties and methods. + friend class MODSERIAL_IRQ_INFO; + //! A copy of the Serial parity enum /** @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format */ enum Parity { @@ -231,7 +363,7 @@ * @param fptr A pointer to a void function, or 0 to set as none * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty) */ - void attach(void (*fptr)(void), IrqType type = RxIrq) { _isr[type].attach(fptr); } + void attach(void (*fptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { _isr[type].attach(fptr); } /** * Function: attach @@ -293,8 +425,8 @@ * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty) */ template<typename T> - void attach(T* tptr, void (T::*mptr)(void), IrqType type = RxIrq) { - if((mptr != NULL) && (tptr != NULL)) { + void attach(T* tptr, uint32_t (T::*mptr)(uint32_t), IrqType type = RxIrq) { + if((mptr != 0) && (tptr != 0)) { _isr[type].attach(tptr, mptr); } } @@ -303,15 +435,15 @@ * @see attach * @ingroup API */ - void connect(void (*fptr)(void), IrqType type = RxIrq) { _isr[RxIrq].attach(fptr); } + void connect(void (*fptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { _isr[RxIrq].attach(fptr); } /** * @see attach * @ingroup API */ template<typename T> - void connect(T* tptr, void (T::*mptr)(void), IrqType type = RxIrq) { - if((mptr != NULL) && (tptr != NULL)) { + void connect(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { + if((mptr != 0) && (tptr != 0)) { _isr[type].attach(tptr, mptr); } } @@ -646,8 +778,28 @@ */ int scanf(const char* format, ...); #endif + +protected: + /** + * Used to pass information to callbacks. + * @ingroup INTERNALS + */ + MODSERIAL_IRQ_INFO callbackInfo; + + /** + * Remove the last char placed into the rx buffer. + * This is an operation that can only be performed + * by an rxCallback function. To protect the buffers + * this function is defined protected so that a + * regular application cannot call it directly. It + * can only be called by the public version within a + * MODSERIAL_IRQ_INFO class. + * @ingroup INTERNALS + * @return The byte removed from the buffer. + */ + int rxDiscardLastChar(void); -protected: +private: /** * A pointer to the UART peripheral base address being used. @@ -713,7 +865,7 @@ * Callback system. * @ingroup INTERNALS */ - FunctionPointer _isr[NumOfIrqTypes]; + MODSERIAL_callback _isr[NumOfIrqTypes]; /** * TX Interrupt Service Routine. @@ -745,7 +897,7 @@ * @ingroup INTERNALS */ void enableIrq(void); - + /** * Get a character from the RX buffer * @ingroup INTERNALS @@ -885,7 +1037,7 @@ * @param fptr A function pointer to call * @return this */ - void attach_dmaSendComplete(void (*fptr)(void)) { + void attach_dmaSendComplete(void (*fptr)(MODSERIAL_IRQ_INFO *)) { _isrDmaSendComplete.attach(fptr); } @@ -898,13 +1050,13 @@ * @return this */ template<typename T> - void attach_dmaSendComplete(T* tptr, void (T::*mptr)(void)) { + void attach_dmaSendComplete(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *)) { if((mptr != NULL) && (tptr != NULL)) { _isrDmaSendComplete.attach(tptr, mptr); } } - FunctionPointer _isrDmaSendComplete; + MODSERIAL_callback _isrDmaSendComplete; protected: /** @@ -921,7 +1073,7 @@ if (dma->irqType() == MODDMA::TcIrq) dma->clearTcIrq(); if (dma->irqType() == MODDMA::ErrIrq) dma->clearErrIrq(); dmaSendChannel = -1; - _isrDmaSendComplete.call(); + _isrDmaSendComplete.call(&this->callbackInfo); delete(config); }