Mistake on this page?
Report an issue in GitHub or email us
BufferedSerial.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2019 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef MBED_BUFFEREDSERIAL_H
19 #define MBED_BUFFEREDSERIAL_H
20 
21 #include "platform/platform.h"
22 
23 #if (DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
24 
25 #include "platform/FileHandle.h"
26 #include "drivers/SerialBase.h"
27 #include "drivers/InterruptIn.h"
28 #include "platform/PlatformMutex.h"
29 #include "platform/CircularBuffer.h"
30 #include "platform/NonCopyable.h"
31 
32 #ifndef MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE
33 #define MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE 256
34 #endif
35 
36 #ifndef MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE
37 #define MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE 256
38 #endif
39 
40 namespace mbed {
41 /**
42  * \defgroup drivers_BufferedSerial BufferedSerial class
43  * \ingroup drivers-public-api-uart
44  * @{
45  */
46 
47 /** Class providing buffered UART communication functionality using separate
48  * circular buffer for send and receive channels
49  *
50  */
51 
53  private SerialBase,
54  public FileHandle,
55  private NonCopyable<BufferedSerial> {
56 
57 public:
58 
59  /** Create a BufferedSerial port, connected to the specified transmit and
60  * receive pins, with a particular baud rate.
61  * @param tx Transmit pin
62  * @param rx Receive pin
63  * @param baud The baud rate of the serial port (optional, defaults to
64  * MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
65  */
67  PinName tx,
68  PinName rx,
69  int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE
70  );
71 
72  /** Create a BufferedSerial port, connected to the specified transmit and
73  * receive pins, with a particular baud rate.
74  * @param static_pinmap reference to structure which holds static pinmap
75  * @param baud The baud rate of the serial port (optional, defaults to
76  * MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
77  */
79  const serial_pinmap_t &static_pinmap,
80  int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE
81  );
82 
83  ~BufferedSerial() override;
84 
85  /** Equivalent to POSIX poll(). Derived from FileHandle.
86  * Provides a mechanism to multiplex input/output over a set of file
87  * handles.
88  * The events that can be reported are POLLIN, POLLOUT, POLLHUP.
89  */
90  short poll(short events) const final;
91 
92  /* Resolve ambiguities versus our private SerialBase
93  * (for writable, spelling differs, but just in case)
94  */
97 
98  /** Write the contents of a buffer to a file
99  *
100  * Follows POSIX semantics:
101  *
102  * * if blocking, block until all data is written
103  * * if no data can be written, and non-blocking set, return -EAGAIN
104  * * if some data can be written, and non-blocking set, write partial
105  *
106  * @param buffer The buffer to write from
107  * @param length The number of bytes to write
108  * @return The number of bytes written, negative error on failure
109  */
110  ssize_t write(const void *buffer, size_t length) override;
111 
112  /** Read the contents of a file into a buffer
113  *
114  * Follows POSIX semantics:
115  *
116  * * if no data is available, and non-blocking set return -EAGAIN
117  * * if no data is available, and blocking set, wait until data is
118  * available
119  * * If any data is available, call returns immediately
120  *
121  * @param buffer The buffer to read in to
122  * @param length The number of bytes to read
123  * @return The number of bytes read, 0 at end of file, negative
124  * error on failure
125  */
126  ssize_t read(void *buffer, size_t length) override;
127 
128  /** Close a file
129  *
130  * @return 0 on success, negative error code on failure
131  */
132  int close() override;
133 
134  /** Check if the file in an interactive terminal device
135  *
136  * @return True if the file is a terminal
137  * @return False if the file is not a terminal
138  * @return Negative error code on failure
139  */
140  int isatty() override;
141 
142  /** Move the file position to a given offset from from a given location
143  *
144  * Not valid for a device type FileHandle like BufferedSerial.
145  * In case of BufferedSerial, returns ESPIPE
146  *
147  * @param offset The offset from whence to move to
148  * @param whence The start of where to seek
149  * SEEK_SET to start from beginning of file,
150  * SEEK_CUR to start from current position in file,
151  * SEEK_END to start from end of file
152  * @return The new offset of the file, negative error code on
153  * failure
154  */
155  off_t seek(off_t offset, int whence) override;
156 
157  /** Flush any buffers associated with the file
158  *
159  * @return 0 on success, negative error code on failure
160  */
161  int sync() override;
162 
163  /** Set blocking or non-blocking mode
164  * The default is blocking.
165  *
166  * @param blocking true for blocking mode, false for non-blocking mode.
167  */
168  int set_blocking(bool blocking) override
169  {
170  _blocking = blocking;
171  return 0;
172  }
173 
174  /** Check current blocking or non-blocking mode for file operations.
175  *
176  * @return true for blocking mode, false for non-blocking mode.
177  */
178  bool is_blocking() const override
179  {
180  return _blocking;
181  }
182 
183  /** Enable or disable input
184  *
185  * Control enabling of device for input. This is primarily intended
186  * for temporary power-saving; the overall ability of the device to operate
187  * for input and/or output may be fixed at creation time, but this call can
188  * allow input to be temporarily disabled to permit power saving without
189  * losing device state.
190  *
191  * @param enabled true to enable input, false to disable.
192  *
193  * @return 0 on success
194  * @return Negative error code on failure
195  */
196  int enable_input(bool enabled) override;
197 
198  /** Enable or disable output
199  *
200  * Control enabling of device for output. This is primarily intended
201  * for temporary power-saving; the overall ability of the device to operate
202  * for input and/or output may be fixed at creation time, but this call can
203  * allow output to be temporarily disabled to permit power saving without
204  * losing device state.
205  *
206  * @param enabled true to enable output, false to disable.
207  *
208  * @return 0 on success
209  * @return Negative error code on failure
210  */
211  int enable_output(bool enabled) override;
212 
213  /** Register a callback on state change of the file.
214  *
215  * The specified callback will be called on state changes such as when
216  * the file can be written to or read from.
217  *
218  * The callback may be called in an interrupt context and should not
219  * perform expensive operations.
220  *
221  * Note! This is not intended as an attach-like asynchronous api, but
222  * rather as a building block for constructing such functionality.
223  *
224  * The exact timing of when the registered function
225  * is called is not guaranteed and susceptible to change. It should be
226  * used as a cue to make read/write/poll calls to find the current state.
227  *
228  * @param func Function to call on state change
229  */
230  void sigio(Callback<void()> func) override;
231 
232  /** Setup interrupt handler for DCD line
233  *
234  * If DCD line is connected, an IRQ handler will be setup.
235  * Does nothing if DCD is NC, i.e., not connected.
236  *
237  * @param dcd_pin Pin-name for DCD
238  * @param active_high a boolean set to true if DCD polarity is active
239  * low
240  */
241  void set_data_carrier_detect(PinName dcd_pin, bool active_high = false);
242 
243  /** Set the baud rate
244  *
245  * @param baud The baud rate
246  */
247  void set_baud(int baud);
248 
249  // Expose private SerialBase::Parity as BufferedSerial::Parity
250  using SerialBase::Parity;
251  using SerialBase::None;
252  using SerialBase::Odd;
253  using SerialBase::Even;
254  using SerialBase::Forced1;
255  using SerialBase::Forced0;
256 
257  /** Set the transmission format used by the serial port
258  *
259  * @param bits The number of bits in a word (5-8; default = 8)
260  * @param parity The parity used (None, Odd, Even, Forced1, Forced0;
261  * default = None)
262  * @param stop_bits The number of stop bits (1 or 2; default = 1)
263  */
264  void set_format(
265  int bits = 8, Parity parity = BufferedSerial::None, int stop_bits = 1
266  );
267 
268 #if DEVICE_SERIAL_FC
269  // For now use the base enum - but in future we may have extra options
270  // such as XON/XOFF or manual GPIO RTSCTS.
271  using SerialBase::Flow;
272  using SerialBase::Disabled;
273  using SerialBase::RTS;
274  using SerialBase::CTS;
275  using SerialBase::RTSCTS;
276 
277  /** Set the flow control type on the serial port
278  *
279  * @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
280  * @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for
281  * CTS)
282  * @param flow2 the second flow control pin (CTS for RTSCTS)
283  */
284  void set_flow_control(Flow type, PinName flow1 = NC, PinName flow2 = NC);
285 #endif
286 
287 private:
288 
289  /** Acquire mutex
290  */
291  void api_lock(void);
292 
293  /** Release mutex
294  */
295  void api_unlock(void);
296 
297  /** Unbuffered write - invoked when write called from critical section
298  * @param buf_ptr The buffer to write from
299  * @param length The number of bytes to write
300  * @return The number of bytes written, negative error on failure
301  */
302  ssize_t write_unbuffered(const char *buf_ptr, size_t length);
303 
304  /** Enable processing of byte reception IRQs and register a callback to
305  * process them.
306  */
307  void enable_rx_irq();
308 
309  /** Disable processing of byte reception IRQs and de-register callback to
310  * process them.
311  */
312  void disable_rx_irq();
313 
314  /** Enable processing of byte transmission IRQs and register a callback to
315  * process them.
316  */
317  void enable_tx_irq();
318 
319  /** Disable processing of byte transmission IRQs and de-register callback to
320  * process them.
321  */
322  void disable_tx_irq();
323 
324  /** Software serial buffers
325  * By default buffer size is 256 for TX and 256 for RX. Configurable
326  * through mbed_app.json
327  */
330 
331  PlatformMutex _mutex;
332 
333  Callback<void()> _sigio_cb;
334 
335  bool _blocking = true;
336  bool _tx_irq_enabled = false;
337  bool _rx_irq_enabled = false;
338  bool _tx_enabled = true;
339  bool _rx_enabled = true;
340  InterruptIn *_dcd_irq = nullptr;
341 
342  /** Device Hanged up
343  * Determines if the device hanged up on us.
344  *
345  * @return True, if hanged up
346  */
347  bool hup() const;
348 
349  /** ISRs for serial
350  * Routines to handle interrupts on serial pins.
351  * Copies data into Circular Buffer.
352  * Reports the state change to File handle.
353  */
354  void tx_irq(void);
355  void rx_irq(void);
356 
357  /** Execute a callback previously registered for state change of the file.
358  */
359  void wake(void);
360 
361  /** Wake on data carrier detected.
362  */
363  void dcd_irq(void);
364 };
365 
366 /** @}*/
367 
368 } //namespace mbed
369 
370 #endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
371 #endif //MBED_BUFFEREDSERIAL_H
void set_format(int bits=8, Parity parity=BufferedSerial::None, int stop_bits=1)
Set the transmission format used by the serial port.
ssize_t write(const void *buffer, size_t length) override
Write the contents of a buffer to a file.
void baud(int baudrate)
Set the baud rate of the serial port.
bool readable() const
Definition depends on the subclass implementing FileHandle.
Definition: FileHandle.h:248
Templated Circular buffer class.
int sync() override
Flush any buffers associated with the file.
Class FileHandle.
Definition: FileHandle.h:46
int isatty() override
Check if the file in an interactive terminal device.
short poll(short events) const final
Equivalent to POSIX poll().
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162
off_t seek(off_t offset, int whence) override
Move the file position to a given offset from from a given location.
The PlatformMutex class is used to synchronize the execution of threads.
Definition: PlatformMutex.h:47
void sigio(Callback< void()> func) override
Register a callback on state change of the file.
void set_baud(int baud)
Set the baud rate.
A base class for serial port implementations Can&#39;t be instantiated directly (use UnbufferedSerial or ...
Definition: SerialBase.h:46
int set_blocking(bool blocking) override
Set blocking or non-blocking mode The default is blocking.
void set_data_carrier_detect(PinName dcd_pin, bool active_high=false)
Setup interrupt handler for DCD line.
int close() override
Close a file.
int enable_input(bool enabled) override
Enable or disable input.
A digital interrupt input, used to call a function on a rising or falling edge.
Definition: InterruptIn.h:65
Class providing buffered UART communication functionality using separate circular buffer for send and...
bool is_blocking() const override
Check current blocking or non-blocking mode for file operations.
int enable_output(bool enabled) override
Enable or disable output.
bool writable() const
Definition depends on the subclass implementing FileHandle.
Definition: FileHandle.h:237
ssize_t read(void *buffer, size_t length) override
Read the contents of a file into a buffer.
Callback class based on template specialization.
Definition: Callback.h:46
BufferedSerial(PinName tx, PinName rx, int baud=MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
Create a BufferedSerial port, connected to the specified transmit and receive pins, with a particular baud rate.
void set_flow_control(Flow type, PinName flow1=NC, PinName flow2=NC)
Set the flow control type on the serial port.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.