FastArduino  v1.7
C++ library to build fast but small Arduino/AVR projects
soft_uart.h
Go to the documentation of this file.
1 // Copyright 2016-2021 Jean-Francois Poilpret
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
21 #ifndef SOFTUART_HH
22 #define SOFTUART_HH
23 
24 #include "boards/board.h"
25 #include "interrupts.h"
26 #include "utilities.h"
27 #include "uart_commons.h"
28 #include "streams.h"
29 #include "gpio.h"
30 #include "pci.h"
31 #include "int.h"
32 
39 #define REGISTER_UARX_PCI_ISR(RX, PCI_NUM) \
40  ISR(CAT3(PCINT, PCI_NUM, _vect)) \
41  { \
42  serial::soft::isr_handler::check_uarx_pci<PCI_NUM, RX>(); \
43  }
44 
51 #define REGISTER_UARX_INT_ISR(RX, INT_NUM) \
52  ISR(CAT3(INT, INT_NUM, _vect)) \
53  { \
54  serial::soft::isr_handler::check_uarx_int<INT_NUM, RX>(); \
55  }
56 
64 #define REGISTER_UART_PCI_ISR(RX, TX, PCI_NUM) \
65  ISR(CAT3(PCINT, PCI_NUM, _vect)) \
66  { \
67  serial::soft::isr_handler::check_uart_pci<PCI_NUM, RX, TX>(); \
68  }
69 
77 #define REGISTER_UART_INT_ISR(RX, TX, INT_NUM) \
78  ISR(CAT3(INT, INT_NUM, _vect)) \
79  { \
80  serial::soft::isr_handler::check_uart_int<INT_NUM, RX, TX>(); \
81  }
82 
83 namespace serial
84 {
95  namespace soft
96  {
97  }
98 }
99 
100 namespace serial::soft
101 {
103  class AbstractUATX
104  {
105  public:
110  streams::ostream out()
111  {
112  return streams::ostream(out_());
113  }
114 
115  protected:
116  AbstractUATX(const AbstractUATX&) = delete;
117  AbstractUATX& operator=(const AbstractUATX&) = delete;
118 
119  using CALLBACK = streams::ostreambuf::CALLBACK;
120 
121  template<uint8_t SIZE_TX>
122  explicit AbstractUATX(char (&output)[SIZE_TX], CALLBACK callback, void* arg)
123  : obuf_{output, callback, arg} {}
124 
125  void compute_times(uint32_t rate, StopBits stop_bits)
126  {
127  // Calculate timing for TX in number of cycles
128  uint16_t bit_time = uint16_t(F_CPU / rate);
129  // 11 or 12 cycles + delay counted from start bit (cbi) to first bit (sbi or cbi)
130  start_bit_tx_time_ = (bit_time - 12) / 4;
131  // 11 or 12 cycles + delay counted from first bit (sbi or cbi) to second bit (sbi or cbi)
132  interbit_tx_time_ = (bit_time - 12) / 4;
133  // For stop bit we lengthten the bit duration of 25% to guarantee alignment of RX side on stop duration
134  stop_bit_tx_time_ = (bit_time / 4) * 5 / 4;
135  if (stop_bits == StopBits::TWO) stop_bit_tx_time_ *= 2;
136  }
137 
138  static Parity calculate_parity(Parity parity, uint8_t value)
139  {
140  if (parity == Parity::NONE) return Parity::NONE;
141  bool odd = false;
142  while (value)
143  {
144  if (value & 0x01) odd = !odd;
145  value >>= 1;
146  }
147  return (odd ? Parity::ODD : Parity::EVEN);
148  }
149 
150  streams::ostreambuf& out_()
151  {
152  return obuf_;
153  }
154 
155  void check_overflow(Errors& errors)
156  {
157  errors.queue_overflow = obuf_.overflow();
158  }
159 
160  template<board::DigitalPin DPIN> void write(Parity parity, uint8_t value)
161  {
162  synchronized write_<DPIN>(parity, value);
163  }
164  template<board::DigitalPin DPIN> void write_(Parity parity, uint8_t value);
165 
166  private:
167  // NOTE declaring obuf_ first instead of last optimizes code size (4 bytes)
168  streams::ostreambuf obuf_;
169 
170  // Various timing constants based on rate
171  uint16_t interbit_tx_time_;
172  uint16_t start_bit_tx_time_;
173  uint16_t stop_bit_tx_time_;
174  };
175 
176  template<board::DigitalPin DPIN> void AbstractUATX::write_(Parity parity, uint8_t value)
177  {
178  using TX = gpio::FastPinType<DPIN>;
179  // Pre-calculate all what we need: parity bit
180  Parity parity_bit = calculate_parity(parity, value);
181 
182  // Write start bit
183  TX::clear();
184  // Wait before starting actual value transmission
185  _delay_loop_2(start_bit_tx_time_);
186  for (uint8_t bit = 0; bit < 8; ++bit)
187  {
188  if (value & 0x01)
189  TX::set();
190  else
191  TX::clear();
192  value >>= 1;
193  _delay_loop_2(interbit_tx_time_);
194  }
195  // Add parity if needed
196  if (parity_bit != Parity::NONE)
197  {
198  if (parity_bit == parity)
199  TX::clear();
200  else
201  TX::set();
202  _delay_loop_2(interbit_tx_time_);
203  }
204  // Add stop bit
205  TX::set();
206  _delay_loop_2(stop_bit_tx_time_);
207  }
209 
218  template<board::DigitalPin TX_> class UATX : public AbstractUATX, public UARTErrors
219  {
220  private:
221  using THIS = UATX<TX_>;
222 
223  public:
225  static constexpr const board::DigitalPin TX = TX_;
226 
233  template<uint8_t SIZE_TX> explicit UATX(char (&output)[SIZE_TX])
234  : AbstractUATX{output, THIS::on_put, this} {}
235 
246  void begin(uint32_t rate, Parity parity = Parity::NONE, StopBits stop_bits = StopBits::ONE)
247  {
248  parity_ = parity;
249  compute_times(rate, stop_bits);
250  out_().queue().unlock();
251  }
252 
261  void end(UNUSED BufferHandling buffer_handling = BufferHandling::KEEP)
262  {
263  out_().queue().lock();
264  }
265 
266  private:
267  static void on_put(void* arg)
268  {
269  THIS& target = *((THIS*) arg);
270  target.check_overflow(target.errors());
271  char value;
272  while (target.out_().queue().pull(value)) target.write<TX>(target.parity_, uint8_t(value));
273  }
274 
275  Parity parity_;
277  };
278 
280  class AbstractUARX
281  {
282  public:
287  streams::istream in()
288  {
289  return streams::istream(in_());
290  }
291 
292  protected:
293  AbstractUARX(const AbstractUARX&) = delete;
294  AbstractUARX& operator=(const AbstractUARX&) = delete;
295 
296  template<uint8_t SIZE_RX> explicit AbstractUARX(char (&input)[SIZE_RX]) : ibuf_{input} {}
297 
298  streams::istreambuf& in_()
299  {
300  return ibuf_;
301  }
302 
303  void compute_times(uint32_t rate, UNUSED bool has_parity, UNUSED StopBits stop_bits)
304  {
305  // Calculate timing for RX in number of cycles
306  uint16_t bit_time = uint16_t(F_CPU / rate);
307 
308  // Actual timing is based on number of times to count 4 cycles, because we use _delay_loop_2()
309 
310  // Time to wait (_delay_loop_2) between detection of start bit and sampling of first bit
311  // For sampling of first bit we wait until middle of first bit
312  // We remove processing time due to ISR call and ISR code:
313  // - 3 cycles to generate the PCI interrupt
314  // - 1-4 (take 2) cycles to complete current instruction
315  // - 4 cycles to process the interrupt + 2 cycles rjmp in vector table
316  // - 32 cycles spent in PCINT vector to save context and check stop bit (sbic)
317  // - 8 cycles to setup stack variables
318  // - (4N) + 4 in delay
319  // - 8 cycles until first bit sample read (sbis)
320  start_bit_rx_time_ = compute_delay(3 * bit_time / 2, 3 + 2 + 4 + 2 + 32 + 8 + 4 + 8);
321 
322  // Time to wait (_delay_loop_2) between sampling of 2 consecutive data bits
323  // This is also use between last bit and parity bit (if checked) or stop bit
324  // We have to wait exactly for `bit_time` cycles
325  // We remove processing time due to each bit sampling and data value update
326  // - 10+4N cycles elapse between processing of each bit
327  interbit_rx_time_ = compute_delay(bit_time, 10);
328 
329  // No extra delay is used after sampling of first stop bit (as there are already
330  // enough code cycles used for pushing data and restoring context on ISR leave)
331  // Actually, >80 cycles elapse until next PCI can be handled
332  }
333 
334  template<board::DigitalPin DPIN> void pin_change(Parity parity, Errors& errors);
335 
336  private:
337  static constexpr uint16_t compute_delay(uint16_t total_cycles, uint16_t less_cycles)
338  {
339  // We add 3 cycles to allow rounding
340  return (total_cycles > less_cycles) ? ((total_cycles - less_cycles + 3) / 4) : 1;
341  }
342 
343  // NOTE declaring ibuf_ first instead of last optimizes code size (2 bytes)
344  streams::istreambuf ibuf_;
345 
346  // Various timing constants based on rate
347  uint16_t interbit_rx_time_;
348  uint16_t start_bit_rx_time_;
349  };
350 
351  template<board::DigitalPin DPIN> void AbstractUARX::pin_change(Parity parity, Errors& errors)
352  {
353  using RX = gpio::FastPinType<DPIN>;
354  // Check RX is low (start bit)
355  if (RX::value()) return;
356  uint8_t value = 0;
357  bool odd = false;
358  errors.has_errors = 0;
359  // Wait for start bit to finish
360  _delay_loop_2(start_bit_rx_time_);
361  // Read first 7 bits
362  for (uint8_t i = 0; i < 8; ++i)
363  {
364  if (RX::value())
365  {
366  value |= 0x80;
367  odd = !odd;
368  }
369  if (i < 7)
370  value >>= 1;
371  _delay_loop_2(interbit_rx_time_);
372  }
373 
374  if (parity != Parity::NONE)
375  {
376  // Check parity bit
377  bool parity_bit = (parity == Parity::ODD ? !odd : odd);
378  // Check parity bit
379  errors.parity_error = (RX::value() != parity_bit);
380  _delay_loop_2(interbit_rx_time_);
381  }
382 
383  // Check we receive a stop bit
384  if (!RX::value())
385  errors.frame_error = true;
386  // Push value if no error
387  if (errors.has_errors == 0)
388  errors.queue_overflow = !in_().queue().push_(char(value));
389  }
391 
393  template<typename T, T IRQ> class UARX {};
395 
397  template<board::ExternalInterruptPin RX_>
398  class UARX<board::ExternalInterruptPin, RX_> : public AbstractUARX, public UARTErrors
399  {
400  public:
406  static constexpr const board::DigitalPin RX = board::EXT_PIN<RX_>();
407 
414 
426  template<uint8_t SIZE_RX>
427  explicit UARX(char (&input)[SIZE_RX], INT_TYPE& enabler)
428  : AbstractUARX{input}, int_{enabler}
429  {
431  }
432 
443  void begin(uint32_t rate, Parity parity = Parity::NONE, StopBits stop_bits = StopBits::ONE)
444  {
445  parity_ = parity;
446  AbstractUARX::compute_times(rate, parity != Parity::NONE, stop_bits);
447  int_.enable();
448  }
449 
457  void end(BufferHandling buffer_handling = BufferHandling::KEEP)
458  {
459  int_.disable();
460  if (buffer_handling == BufferHandling::CLEAR)
461  in_().queue().clear();
462  }
463 
464  private:
465  void on_pin_change()
466  {
467  this->pin_change<RX>(parity_, errors());
468  // Clear PCI interrupt to remove pending PCI occurred during this method and to detect next start bit
469  int_.clear_();
470  }
471 
472  Parity parity_;
473  gpio::FAST_PIN<RX> rx_ = gpio::PinMode::INPUT;
474  INT_TYPE& int_;
475  friend struct isr_handler;
476  };
477 
479  template<typename T, T IRQ, board::DigitalPin TX> class UART {};
481 
483  template<board::ExternalInterruptPin RX_, board::DigitalPin TX_>
484  class UART<board::ExternalInterruptPin, RX_, TX_> : public AbstractUARX, public AbstractUATX, public UARTErrors
485  {
486  private:
488 
489  public:
491  static constexpr const board::DigitalPin TX = TX_;
495  static constexpr const board::DigitalPin RX = board::EXT_PIN<RX_>();
496 
503 
516  template<uint8_t SIZE_RX, uint8_t SIZE_TX>
517  explicit UART(char (&input)[SIZE_RX], char (&output)[SIZE_TX], INT_TYPE& enabler)
518  : AbstractUARX{input}, AbstractUATX{output, THIS::on_put, this}, int_{enabler}
519  {
521  }
522 
533  void begin(uint32_t rate, Parity parity = Parity::NONE, StopBits stop_bits = StopBits::ONE)
534  {
535  out_().queue().unlock();
536  parity_ = parity;
537  AbstractUARX::compute_times(rate, parity != Parity::NONE, stop_bits);
538  AbstractUATX::compute_times(rate, stop_bits);
539  int_.enable();
540  }
541 
549  void end(BufferHandling buffer_handling = BufferHandling::KEEP)
550  {
551  int_.disable();
552  if (buffer_handling == BufferHandling::CLEAR)
553  in_().queue().clear();
554  out_().queue().lock();
555  }
556 
557  private:
558  static void on_put(void* arg)
559  {
560  THIS& target = *((THIS*) arg);
561  target.check_overflow(target.errors());
562  char value;
563  while (target.out_().queue().pull(value)) target.write<TX>(target.parity_, uint8_t(value));
564  }
565 
566  void on_pin_change()
567  {
568  this->pin_change<RX>(parity_, errors());
569  // Clear PCI interrupt to remove pending PCI occurred during this method and to detect next start bit
570  int_.clear_();
571  }
572 
573  Parity parity_;
575  gpio::FAST_PIN<RX> rx_ = gpio::PinMode::INPUT;
576  INT_TYPE& int_;
577  friend struct isr_handler;
578  };
579 
581  template<board::InterruptPin RX_> class UARX<board::InterruptPin, RX_> : public AbstractUARX, public UARTErrors
582  {
583  public:
589  static constexpr const board::DigitalPin RX = board::PCI_PIN<RX_>();
590 
597 
609  template<uint8_t SIZE_RX>
610  explicit UARX(char (&input)[SIZE_RX], PCI_TYPE& enabler)
611  : AbstractUARX{input}, pci_{enabler}
612  {
614  }
615 
626  void begin(uint32_t rate, Parity parity = Parity::NONE, StopBits stop_bits = StopBits::ONE)
627  {
628  parity_ = parity;
629  AbstractUARX::compute_times(rate, parity != Parity::NONE, stop_bits);
630  pci_.template enable_pin<RX_>();
631  }
632 
640  void end(BufferHandling buffer_handling = BufferHandling::KEEP)
641  {
642  pci_.template disable_pin<RX_>();
643  if (buffer_handling == BufferHandling::CLEAR)
644  in_().queue().clear();
645  }
646 
647  private:
648  void on_pin_change()
649  {
650  this->pin_change<RX>(parity_, errors());
651  // Clear PCI interrupt to remove pending PCI occurred during this method and to detect next start bit
652  pci_.clear_();
653  }
654 
655  Parity parity_;
656  gpio::FAST_PIN<RX> rx_ = gpio::PinMode::INPUT;
657  PCI_TYPE& pci_;
658  friend struct isr_handler;
659  };
660 
662  template<board::InterruptPin RX_, board::DigitalPin TX_>
663  class UART<board::InterruptPin, RX_, TX_> : public AbstractUARX, public AbstractUATX, public UARTErrors
664  {
665  private:
667 
668  public:
670  static constexpr const board::DigitalPin TX = TX_;
674  static constexpr const board::DigitalPin RX = board::PCI_PIN<RX_>();
675 
682 
695  template<uint8_t SIZE_RX, uint8_t SIZE_TX>
696  explicit UART(char (&input)[SIZE_RX], char (&output)[SIZE_TX], PCI_TYPE& enabler)
697  : AbstractUARX{input}, AbstractUATX{output, THIS::on_put, this}, pci_{enabler}
698  {
700  }
701 
712  void begin(uint32_t rate, Parity parity = Parity::NONE, StopBits stop_bits = StopBits::ONE)
713  {
714  out_().queue().unlock();
715  parity_ = parity;
716  AbstractUARX::compute_times(rate, parity != Parity::NONE, stop_bits);
717  AbstractUATX::compute_times(rate, stop_bits);
718  pci_.template enable_pin<RX_>();
719  }
720 
729  void end(BufferHandling buffer_handling = BufferHandling::KEEP)
730  {
731  pci_.template disable_pin<RX_>();
732  if (buffer_handling == BufferHandling::CLEAR)
733  in_().queue().clear();
734  out_().queue().lock();
735  }
736 
737  private:
738  static void on_put(void* arg)
739  {
740  THIS& target = *((THIS*) arg);
741  target.check_overflow(target.errors());
742  char value;
743  while (target.out_().queue().pull(value)) target.write<TX>(target.parity_, uint8_t(value));
744  }
745 
746  void on_pin_change()
747  {
748  this->pin_change<RX>(parity_, errors());
749  // Clear PCI interrupt to remove pending PCI occurred during this method and to detect next start bit
750  pci_.clear_();
751  }
752 
753  Parity parity_;
755  gpio::FAST_PIN<RX> rx_ = gpio::PinMode::INPUT;
756  PCI_TYPE& pci_;
757  friend struct isr_handler;
758  };
759 
760  // Useful type aliases
761  //=====================
762 
775  template<board::ExternalInterruptPin RX_> using UARX_EXT = UARX<board::ExternalInterruptPin, RX_>;
776 
789  template<board::InterruptPin RX_> using UARX_PCI = UARX<board::InterruptPin, RX_>;
790 
804  template<board::ExternalInterruptPin RX_, board::DigitalPin TX_>
806 
820  template<board::InterruptPin RX_, board::DigitalPin TX_>
822 
824  struct isr_handler
825  {
826  template<uint8_t PCI_NUM_, board::InterruptPin RX_> static void check_uarx_pci()
827  {
828  interrupt::isr_handler_pci::check_pci_pins<PCI_NUM_, RX_>();
829  using UARX = serial::soft::UARX_PCI<RX_>;
830  interrupt::HandlerHolder<UARX>::handler()->on_pin_change();
831  }
832 
833  template<uint8_t INT_NUM_, board::ExternalInterruptPin RX_> static void check_uarx_int()
834  {
835  interrupt::isr_handler_int::check_int_pin<INT_NUM_, RX_>();
836  using UARX = serial::soft::UARX_EXT<RX_>;
837  interrupt::HandlerHolder<UARX>::handler()->on_pin_change();
838  }
839 
840  template<uint8_t PCI_NUM_, board::InterruptPin RX_, board::DigitalPin TX_> static void check_uart_pci()
841  {
842  interrupt::isr_handler_pci::check_pci_pins<PCI_NUM_, RX_>();
844  interrupt::HandlerHolder<UART>::handler()->on_pin_change();
845  }
846 
847  template<uint8_t INT_NUM_, board::ExternalInterruptPin RX_, board::DigitalPin TX_> static void check_uart_int()
848  {
849  interrupt::isr_handler_int::check_int_pin<INT_NUM_, RX_>();
851  interrupt::HandlerHolder<UART>::handler()->on_pin_change();
852  }
853  };
855 }
856 
857 #endif /* SOFTUART_HH */
858 
serial::soft::UART< board::ExternalInterruptPin, RX_, TX_ >
Definition: soft_uart.h:485
serial::soft::UART< board::InterruptPin, RX_, TX_ >
Definition: soft_uart.h:664
serial::Parity
Parity
Parity used for serial transmission.
Definition: uart_commons.h:38
board::ExternalInterruptPin
ExternalInterruptPin
Defines all digital output pins of target MCU, usable as direct external interrupt pins.
Definition: empty.h:91
gpio::FastPinType
API that manipulates a given digital IO pin of a the target MCU.
Definition: gpio.h:545
serial
Defines all API for UART features.
Definition: soft_uart.h:84
streams::ostream
Output stream wrapper to provide formatted output API, a la C++.
Definition: streams.h:61
serial::soft::UARX< board::InterruptPin, RX_ >::begin
void begin(uint32_t rate, Parity parity=Parity::NONE, StopBits stop_bits=StopBits::ONE)
Enable the receiver.
Definition: soft_uart.h:626
serial::UARTErrors
Holder of latest UART errors.
Definition: uart_commons.h:96
streams::istreambuf
Input API based on a ring buffer.
Definition: streambuf.h:209
serial::soft::UATX::begin
void begin(uint32_t rate, Parity parity=Parity::NONE, StopBits stop_bits=StopBits::ONE)
Enable the transmitter.
Definition: soft_uart.h:246
streams.h
C++-like std::iostream facilities.
serial::soft::UARX< board::InterruptPin, RX_ >::UARX
UARX(char(&input)[SIZE_RX], PCI_TYPE &enabler)
Construct a new software serial receiver and provide it with a buffer for interrupt-based reception.
Definition: soft_uart.h:610
serial::soft::UART< board::InterruptPin, RX_, TX_ >::PCI_TYPE
interrupt::PCI_SIGNAL< RX_ > PCI_TYPE
The interrupt::PCISignal type for RX_ pin, if it is a PinChangeInterrupt pin.
Definition: soft_uart.h:681
serial::soft::UARX< board::ExternalInterruptPin, RX_ >
Definition: soft_uart.h:399
uart_commons.h
Common definitions for serial API.
serial::soft::UARX< board::ExternalInterruptPin, RX_ >::end
void end(BufferHandling buffer_handling=BufferHandling::KEEP)
Stop reception.
Definition: soft_uart.h:457
serial::Parity::NONE
@ NONE
No parity bit.
interrupt::PCI_SIGNAL
typename PCIType< PIN >::TYPE PCI_SIGNAL
Useful alias type to the PCISignal type matching a given board::InterruptPin.
Definition: pci.h:567
streams::ostreambuf
Output API based on a ring buffer.
Definition: streambuf.h:46
serial::StopBits::ONE
@ ONE
One stop bit.
serial::soft::UART< board::ExternalInterruptPin, RX_, TX_ >::UART
UART(char(&input)[SIZE_RX], char(&output)[SIZE_TX], INT_TYPE &enabler)
Construct a new software serial receiver/transceiver and provide it with 2 buffers,...
Definition: soft_uart.h:517
serial::StopBits
StopBits
Number of stop bits used for serial transmission.
Definition: uart_commons.h:51
serial::soft::UARX< board::InterruptPin, RX_ >::end
void end(BufferHandling buffer_handling=BufferHandling::KEEP)
Stop reception.
Definition: soft_uart.h:640
gpio::FAST_PIN
typename FastPinType< DPIN_ >::TYPE FAST_PIN
Useful alias type to the FastPin type matching a given board::DigitalPin.
Definition: gpio.h:688
pci.h
General API for handling Pin Change Interrupts.
serial::soft::UART< board::InterruptPin, RX_, TX_ >::begin
void begin(uint32_t rate, Parity parity=Parity::NONE, StopBits stop_bits=StopBits::ONE)
Enable the receiver/transceiver.
Definition: soft_uart.h:712
serial::BufferHandling
BufferHandling
How the TX/RX buffer should be handled when ending transmission (see end() methods) on UATX/UARX.
Definition: uart_commons.h:63
errors
This namespace defines common errors that can be returned by some FastArduino API methods,...
Definition: errors.h:38
board
Defines all types and constants specific to support Arduino MEGA board (ATmega644 MCU target).
Definition: atmega_xx4.h:39
serial::soft::UARX< board::ExternalInterruptPin, RX_ >::INT_TYPE
typename interrupt::INTSignal< RX_ > INT_TYPE
The interrupt::INTSignal type for RX_ pin, if it is a External Interrupt pin.
Definition: soft_uart.h:413
serial::soft
Defines API types used by software UART features.
Definition: soft_uart.h:96
interrupt::INTSignal
Handler of an External Interrupt.
Definition: int.h:132
board::InterruptPin
InterruptPin
Defines all digital output pins of target MCU, usable as pin change interrupt (PCI) pins.
Definition: empty.h:98
serial::soft::UART< board::ExternalInterruptPin, RX_, TX_ >::INT_TYPE
typename interrupt::INTSignal< RX_ > INT_TYPE
The interrupt::INTSignal type for RX_ pin, if it is a External Interrupt pin.
Definition: soft_uart.h:502
streams::istream
Input stream wrapper to provide formatted input API, a la C++.
Definition: streams.h:357
serial::soft::UATX::end
void end(UNUSED BufferHandling buffer_handling=BufferHandling::KEEP)
Stop all transmissions.
Definition: soft_uart.h:261
UNUSED
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
Definition: defines.h:45
serial::soft::UART< board::ExternalInterruptPin, RX_, TX_ >::begin
void begin(uint32_t rate, Parity parity=Parity::NONE, StopBits stop_bits=StopBits::ONE)
Enable the receiver/transceiver.
Definition: soft_uart.h:533
utilities.h
General utilities API that have broad application in programs.
serial::soft::UARX< board::InterruptPin, RX_ >
Definition: soft_uart.h:582
serial::soft::UART< board::ExternalInterruptPin, RX_, TX_ >::end
void end(BufferHandling buffer_handling=BufferHandling::KEEP)
Stop all transmissions and receptions.
Definition: soft_uart.h:549
gpio.h
General Purpose (digital) Input Output API.
serial::soft::UARX< board::InterruptPin, RX_ >::PCI_TYPE
interrupt::PCI_SIGNAL< RX_ > PCI_TYPE
The interrupt::PCISignal type for RX_ pin, if it is a PinChangeInterrupt pin.
Definition: soft_uart.h:596
serial::soft::UARX< board::ExternalInterruptPin, RX_ >::UARX
UARX(char(&input)[SIZE_RX], INT_TYPE &enabler)
Construct a new software serial receiver and provide it with a buffer for interrupt-based reception.
Definition: soft_uart.h:427
interrupts.h
General API for handling AVR interrupt vectors.
serial::soft::UART< board::InterruptPin, RX_, TX_ >::UART
UART(char(&input)[SIZE_RX], char(&output)[SIZE_TX], PCI_TYPE &enabler)
Construct a new software serial receiver/transceiver and provide it with 2 buffers,...
Definition: soft_uart.h:696
serial::soft::UARX< board::ExternalInterruptPin, RX_ >::begin
void begin(uint32_t rate, Parity parity=Parity::NONE, StopBits stop_bits=StopBits::ONE)
Enable the receiver.
Definition: soft_uart.h:443
interrupt::register_handler
void register_handler(Handler &handler)
Register a class instance containing methods that shall be called back by an ISR.
Definition: interrupts.h:157
serial::soft::UATX::UATX
UATX(char(&output)[SIZE_TX])
Construct a new software serial transmitter and provide it with a buffer for payload transmission.
Definition: soft_uart.h:233
gpio::PinMode::OUTPUT
@ OUTPUT
Digital pin is configured as output.
serial::soft::UATX
Software-emulated serial transmitter API.
Definition: soft_uart.h:219
serial::soft::UART< board::InterruptPin, RX_, TX_ >::end
void end(BufferHandling buffer_handling=BufferHandling::KEEP)
Stop all transmissions and receptions.
Definition: soft_uart.h:729
int.h
General API for handling External Interrupt pins.
board::DigitalPin
DigitalPin
Defines all available digital input/output pins of ATmega644, with reference to Arduino MEGA pins.
Definition: atmega_xx4.h:76
serial::soft::UATX::TX
static constexpr const board::DigitalPin TX
The board::DigitalPin to which transmitted signal is sent.
Definition: soft_uart.h:225