Demo application for using the AT&T IoT Starter Kit Powered by AWS.
Dependencies: SDFileSystem
Fork of ATT_AWS_IoT_demo by
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
Generated on Tue Jul 12 2022 22:13:21 by 1.7.2