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 SerialDriver by
SerialDriver.h
00001 /// @file SerialDriver.h 00002 /// @brief RTOS compatible buffered Serial port driver 00003 /// 00004 /// Examples: 00005 /// - @ref Example_printf.cpp 00006 /// - @ref Example_Nullmodem.cpp 00007 /// - @ref Example_Bridge.cpp 00008 /// - @ref Example_Blocking.cpp 00009 /// 00010 /// 00011 /// Dependencies: 00012 /// - cstdarg 00013 /// @see https://developer.mbed.org/users/mbed_official/code/mbed-rtos/ 00014 /// @see https://developer.mbed.org/users/mbed_official/code/mbed/ 00015 00016 #pragma once 00017 00018 #include "mbed.h" 00019 #include "rtos.h" 00020 #include <cstdarg> 00021 00022 00023 /// @class SerialDriver 00024 /// @brief RTOS compatible buffered Serial port driver 00025 /// 00026 /// - Based on SerialBase. 00027 /// - Can use external buffers. 00028 /// - ISR driven, ring buffered IO operation 00029 /// - Can Replace mbed RawSerial 00030 /// - IO operations are idle waiting, don't waste time in RTOS :D 00031 /// - Do not use attach methods for TxIrq or RxIrq! They are already in use. 00032 class SerialDriver : public SerialBase 00033 { 00034 protected: 00035 // ring buffered rx/tx 00036 unsigned char * txBuffer; 00037 unsigned char * rxBuffer; 00038 int txBufferLength, rxBufferLength; 00039 00040 // ring buffer cursors 00041 volatile int txIn, txOut; 00042 volatile int rxIn, rxOut; 00043 volatile int txCount, rxCount; 00044 00045 // semaphores for timeout (used as signals) 00046 Semaphore semTxBufferFull; // used by putc to wait 00047 Semaphore semRxBufferEmpty; // used by getc to wait 00048 00049 // drop counters 00050 volatile int numTxDrops, numRxDrops; 00051 00052 FunctionPointer _callback_rx_overflow; 00053 FunctionPointer _callback_tx_overflow; 00054 FunctionPointer _callback_auto_detect; 00055 00056 public: 00057 enum IrqType { RxOvIrq = 0, TxOvIrq, RxAutoDetect}; 00058 00059 /// @brief Prepares ring buffer and irq 00060 /// 00061 /// If no buffer was set, the buffer gets allocated. 00062 /// @param txPin TX PinName, e.g. USBTX 00063 /// @param rxPin RX PinName, e.g. USBRX 00064 /// @param txBufferLength_ size of TX buffer. Must be > 1! 00065 /// @param rxBufferLength_ size of RX buffer. Must be > 1! 00066 /// @param txBuffer_ TX buffer, if NULL, the buffer will be allocated 00067 /// @param rxBuffer_ RX buffer, if NULL, the buffer will be allocated 00068 SerialDriver(PinName txPin, PinName rxPin, int txBufferLength_= 256, int rxBufferLength_= 256, unsigned char * txBuffer_= NULL, unsigned char * rxBuffer_= NULL); 00069 00070 00071 void attach(IrqType irq, void (*function)(void)) { 00072 if (irq == RxOvIrq) { 00073 _callback_tx_overflow.attach( function ); 00074 } else if (irq == TxOvIrq) { 00075 _callback_tx_overflow.attach( function ); 00076 } else if (irq == RxAutoDetect) { 00077 _callback_auto_detect.attach( function ); 00078 } //else { } 00079 } 00080 00081 //////////////////////////////////////////////////////////////// 00082 // Basic IO Operation 00083 00084 /// @brief Put a byte to the TX buffer 00085 /// 00086 /// If the TX buffer is full, it waits the defined timeout. 00087 /// Drops the byte, if TX buffer is still full after timeout. 00088 /// @param c The byte to write 00089 /// @param timeoutMs give TX buffer time to get writeable. 00090 /// @return 1 - success, 0 - if TX Buffer was full all the time 00091 int putc(int c, unsigned int timeoutMs= osWaitForever); 00092 00093 00094 /// @brief Get a byte from the RX buffer 00095 /// 00096 /// If the RX buffer is empty, it waits the defined timeout. 00097 /// @param timeoutMs give RX buffer time to get readable. 00098 /// @return next byte from RX buffer or -1 after timeout. 00099 int getc(unsigned int timeoutMs= osWaitForever); 00100 00101 00102 protected: 00103 //////////////////////////////////////////////////////////////// 00104 // Interrupts 00105 00106 // TX: Move data from txBuffer to SerialBase::putc 00107 void onTxIrq(); // serial base port now writeable, lets put some bytes 00108 00109 // RX: Move data from SerialBase::getc to rxBuffer 00110 void onRxIrq(); // serial base port now readable, lets get some bytes 00111 00112 // Enable / Disable 00113 inline void disableTxInterrupt() { serial_irq_set(&_serial, (SerialIrq)TxIrq, 0); } 00114 inline void enableTxInterrupt() { serial_irq_set(&_serial, (SerialIrq)TxIrq, 1); } 00115 00116 inline void disableRxInterrupt() { serial_irq_set(&_serial, (SerialIrq)RxIrq, 0); } 00117 inline void enableRxInterrupt() { serial_irq_set(&_serial, (SerialIrq)RxIrq, 1); } 00118 00119 00120 public: 00121 //////////////////////////////////////////////////////////////// 00122 // Extended IO Operation 00123 00124 /// @brief write a buck of bytes 00125 /// 00126 /// No timeout! To block, or not to block. That is the question. 00127 /// @param buffer buck of bytes 00128 /// @param length write how much bytes? 00129 /// @param block idle wait for every @ref putc to complete 00130 /// @return written bytes. For non block write it could be < length! 00131 int write(const unsigned char * buffer, const unsigned int length, bool block= true); 00132 00133 /// @brief read a buck of bytes 00134 /// 00135 /// No timeout! To block, or not to block. That is the question. 00136 /// @param buffer buck of bytes 00137 /// @param length read how much bytes? 00138 /// @param block idle wait for every @ref getc to complete 00139 /// @return read bytes. For non block read it could be < length! 00140 int read(unsigned char * buffer, const unsigned int length, bool block= true); 00141 00142 00143 /// @brief Write a string (without terminating null) 00144 /// 00145 /// For compatibility with mbed RawSerial 00146 /// @param str null terminated string 00147 /// @param block idle wait for every @ref putc to complete 00148 /// @return written chars (without terminating null) 00149 int puts(const char * str, bool block= true); 00150 00151 /// @brief Print a formatted string. 00152 /// 00153 /// Idle blocking! 00154 /// Dynamically allocates needed buffer. 00155 /// @param format null terminated format string 00156 /// @return written chars (without terminating null) 00157 int printf(const char * format, ...); 00158 00159 00160 //////////////////////////////////////////////////////////////// 00161 // Buffer Infos 00162 00163 /// @brief Checks if TX buffer is full 00164 /// @return true - TX buffer is full, false - else 00165 inline bool isTxBufferFull() { return txCount == txBufferLength; } 00166 00167 /// @brief Checks if RX buffer is full 00168 /// @return true - RX buffer is full, false - else 00169 inline bool isRxBufferFull() { return rxCount == rxBufferLength; } 00170 00171 /// @brief Checks if TX buffer is empty 00172 /// @return true - TX buffer is empty, false - else 00173 inline bool isTxBufferEmtpy() { return txCount == 0; } 00174 00175 /// @brief Checks if RX buffer is empty 00176 /// @return true - RX buffer is empty, false - else 00177 inline bool isRxBufferEmpty() { return rxCount == 0; } 00178 00179 00180 /// @brief Checks if TX buffer is writeable (= not full). 00181 /// 00182 /// For compatibility with mbed Serial. 00183 /// @return true - TX buffer is writeable, false - else 00184 inline bool writeable() { return !isTxBufferFull(); } 00185 00186 /// @brief Checks if RX buffer is readable (= not empty). 00187 /// 00188 /// For compatibility with mbed Serial. 00189 /// @return true - RX buffer is readable, false - else 00190 inline bool readable() { return !isRxBufferEmpty(); } 00191 00192 00193 /// @brief Returns number of dropped bytes that did not fit into TX buffer 00194 /// @return number of dropped tx bytes 00195 inline int getNumTxDrops() { return numTxDrops; } 00196 00197 /// @brief Returns number of dropped bytes that did not fit into RX buffer 00198 /// @return number of dropped rx bytes 00199 inline int getNumRxDrops() { return numRxDrops; } 00200 };
Generated on Sat Jul 16 2022 05:44:44 by
1.7.2
