SatCat5
sam_usart.h
Go to the documentation of this file.
1 // Copyright 2024-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
11 
12 #pragma once
13 
14 #include <hal_samv71/interrupt_handler.h>
15 #include <satcat5/io_buffer.h>
16 #include <satcat5/polling.h>
17 #ifdef __FREERTOS__
18 #include <hal_freertos/task.h>
19 #include <satcat5/utils.h>
20 #endif
21 
22 // ASF3 includes
23 extern "C"{
24 #include <usart.h>
25 #include <xdmac.h>
26 }
27 
28 // Default buffer size for UsartSamv71Static
29 #ifndef SATCAT5_SAMV71_UART_BUFFSIZE
30 #define SATCAT5_SAMV71_UART_BUFFSIZE 1600
31 #endif
32 
33 // Enable data cache flushing and invalidation for the DMA controller?
34 // When disabled (default, safe), SCB_DisableDCache() must be called at init.
35 #ifndef SATCAT5_SAMV71_UART_DCACHE
36 #define SATCAT5_SAMV71_UART_DCACHE 0
37 #endif
38 
39 namespace satcat5 {
40  namespace sam {
92  , public satcat5::poll::Timer
93  , public satcat5::poll::Always
95  {
96  public:
115  UsartSamv71(
116  Usart* usart, unsigned baud_hz, unsigned poll_ms,
117  u8* txbuff, unsigned txbytes, u8* rxbuff, unsigned rxbytes,
118  u8* rxdma0, u8* rxdma1, unsigned rxdmabytes,
119  bool fc_on=false);
120 
123  void configure(unsigned baud_hz, bool rts_en, bool cts_en);
124 
126  inline void configure(unsigned baud_hz, bool fc_on=false)
127  { configure(baud_hz, fc_on, fc_on); }
128 
129  protected:
131  void data_rcvd(satcat5::io::Readable* src) override
132  { poll_tx_dma(); }
133 
138  void timer_event() override { poll_rx_dma(); poll_tx_dma(); }
139  void poll_always() override { poll_rx_dma(); poll_tx_dma(); }
141 
143  void irq_event() override;
144 
147  { return m_rxdma_buffidx == 0 ? m_rxdma0 : m_rxdma1; }
148 
150  void poll_tx_dma();
151 
153  void poll_rx_dma();
154 
156  void configure_xdmac(u32 tx_dma_ch, u32 rx_dma_ch);
157 
160  void rts_high();
161  void rts_low();
163 
164  private:
165  // Member variables.
166  Usart* m_usart;
167  unsigned m_txdma_nbytes;
168  u8* const m_rxdma0;
169  u8* const m_rxdma1;
170  const unsigned m_rxdma_nbytes;
171  unsigned m_rxdma_buffidx;
172  bool m_rts_en;
173  bool m_cts_en;
174  u8 m_tx_dma_ch;
175  u8 m_rx_dma_ch;
176  };
177 
186  template <unsigned SIZE = SATCAT5_SAMV71_UART_BUFFSIZE>
188  public:
198  Usart* usart, unsigned baud_hz,
199  unsigned poll_ms, bool fc_on=false)
200  : UsartSamv71(usart, baud_hz, poll_ms,
201  m_txbuff, SIZE, m_rxbuff, SIZE,
202  m_rxdma0, m_rxdma1, SIZE, fc_on) {}
203 
204  private:
205  u8 m_txbuff[SIZE];
206  u8 m_rxbuff[SIZE];
207  u8 m_rxdma0[SIZE];
208  u8 m_rxdma1[SIZE];
209  };
210 
211 #ifdef __FREERTOS__
218  template <
219  unsigned TASK_PRIORITY,
220  unsigned SIZE = SATCAT5_SAMV71_UART_BUFFSIZE,
221  configSTACK_DEPTH_TYPE TASK_SIZE = 1024>
222  class UsartSamv71Preempt
223  : public satcat5::freertos::StaticTask<TASK_SIZE, TASK_PRIORITY>
224  , public UsartSamv71Static<SIZE> {
225  public:
231  UsartSamv71Preempt(
232  Usart* usart, unsigned baud_hz, unsigned poll_ms,
233  bool poll_always=false, bool fc_on=false)
234  : satcat5::freertos::StaticTask<TASK_SIZE, TASK_PRIORITY>(
235  "UsartSamv71Preempt", task, this)
236  , UsartSamv71Static<SIZE>(usart, baud_hz, 0, fc_on) // poll_ms = 0
237  , m_poll_ms(satcat5::util::max_unsigned(1, poll_ms)) // Must be > 0
238  {
239  // Unregister the poll_always() call if requested.
240  if (!poll_always) { this->poll_unregister(); }
241  }
242 
245  static void task(void* pvParams) {
246  UsartSamv71Preempt* arg = (UsartSamv71Preempt*) pvParams;
247  const TickType_t poll_rate = pdMS_TO_TICKS(arg->m_poll_ms);
248  TickType_t last_wake_time = xTaskGetTickCount();
249  for (;;) {
250  vTaskDelayUntil(&last_wake_time, poll_rate);
251  arg->poll_rx_dma();
252  arg->poll_tx_dma();
253  }
254  }
255 
256  protected:
257  // Member variables
258  const unsigned m_poll_ms;
259  };
260 #endif
261 
262  } // namespace sam
263 } // namespace satcat5
Instantiate a FreeRTOS statically-allocated Task.
Definition: task.h:43
Extensible transmit and receive buffer.
Definition: io_buffer.h:42
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
An "Always" object is polled whenever service() is called.
Definition: polling.h:96
Timer objects are polled after a fixed delay or at a regular interval.
Definition: polling.h:213
Interrupt handler interface for the Microchip SAM V71.
io::BufferedIO interface for the SAMV71 USART and UART peripherals.
Definition: sam_usart.h:95
void rts_low()
Drive the RTS signal high/low if flow-control is on.
Definition: sam_usart.cc:328
void rts_high()
Drive the RTS signal high/low if flow-control is on.
Definition: sam_usart.cc:316
void configure(unsigned baud_hz, bool fc_on=false)
Alias for backwards compatibility (deprecated).
Definition: sam_usart.h:126
void configure(unsigned baud_hz, bool rts_en, bool cts_en)
Set baud rate and RTS/CTS enable.
Definition: sam_usart.cc:126
void timer_event() override
The user may configure either continuous polling or timer-based polling; either should perform the sa...
Definition: sam_usart.h:138
void configure_xdmac(u32 tx_dma_ch, u32 rx_dma_ch)
Initial setup of the TX/RX DMA controllers.
Definition: sam_usart.cc:251
void poll_tx_dma()
Poll the RX DMA engine for new data received.
Definition: sam_usart.cc:171
void poll_rx_dma()
Poll the TX DMA engine for unsent data to transmit.
Definition: sam_usart.cc:206
u8 * get_rxdma_buff()
Get the RX buffer the DMA is currently writing to.
Definition: sam_usart.h:146
void irq_event() override
IRQ indicates the RX DMA is full or the TX DMA is empty.
Definition: sam_usart.cc:159
void data_rcvd(satcat5::io::Readable *src) override
Immediately transfer incoming TX data to the DMA engine.
Definition: sam_usart.h:131
void poll_always() override
The user may configure either continuous polling or timer-based polling; either should perform the sa...
Definition: sam_usart.h:139
UsartSamv71(Usart *usart, unsigned baud_hz, unsigned poll_ms, u8 *txbuff, unsigned txbytes, u8 *rxbuff, unsigned rxbytes, u8 *rxdma0, u8 *rxdma1, unsigned rxdmabytes, bool fc_on=false)
Constructor for an ASF3 USART with user-provided buffers.
Definition: sam_usart.cc:81
UsartSamv71 variant with statically-allocated TX and RX buffers; most users should instantiate this i...
Definition: sam_usart.h:187
UsartSamv71Static(Usart *usart, unsigned baud_hz, unsigned poll_ms, bool fc_on=false)
Constructor for an ASF3 USART with built-in buffers.
Definition: sam_usart.h:197
Buffered I/O wrappers for PacketBuffer.
Core event-processing loop for SatCat5 software.
Provides a FreeRTOS task function and hooks for using SatCat5 as a task inside a larger FreeRTOS proj...
Miscellaneous mathematical utility functions.