MODSERIAL with support for more devices
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); }