Pico-Arduino
PicoHardwareSerial.h
1 #pragma once
2 
3 #include "Stream.h"
4 #include "HardwareSerial.h"
5 #include "RingBuffer.h"
6 #include "pico/stdlib.h"
7 
8 #ifndef BUFFER_SIZE
9 #define BUFFER_SIZE 512
10 #endif
11 
12 
19  public:
21  }
22 
23  virtual void begin(unsigned long baudrate=PICO_DEFAULT_UART_BAUD_RATE) {
24  stdio_init_all();
25  open = true;
26  };
27  virtual void begin(unsigned long baudrate, uint16_t config){
28  stdio_init_all();
29  open = true;
30 
31  }
32  virtual void end() {
33  open = false;
34  }
35  virtual int available(void){
36  readBuffer();
37  return buffer.available();
38  }
39  virtual int peek(void) {
40  readBuffer();
41  return buffer.peek();
42  }
43  virtual int read(void){
44  // we might need to flush the current ouptut...
45  flush();
46  // try to refill the buffer
47  readBuffer();
48  return buffer.read_char();
49  }
50 
51  virtual void flush(void) {
52  stdio_flush();
53  }
54 
55  virtual size_t write(uint8_t c) {
56  size_t len = putchar(c);
57  stdio_flush();
58  return len;
59  }
60 
61  virtual int println(){
62  return println("");
63  }
64 
65  virtual int println(char const* str){
66  int len = printf("%s\n",str);
67  flush();
68  return len;
69  }
70 
71  using Print::write; // pull in write(str) and write(buf, size) from Print
72  using Print::print; // pull in write(str) and write(buf, size) from Print
73  using Print::println; // pull in write(str) and write(buf, size) from Print
74 
75  virtual operator bool(){
76  return open;
77  };
78 
79  protected:
80  bool open;
81  RingBufferN<BUFFER_SIZE> buffer;
82 
83  void readBuffer() {
84  // refill buffer only if it is empty
85  if (buffer.available()==0){
86  // fill buffer as long as we have space
87  int c = getchar_timeout_us(1000);
88  while(c!=PICO_ERROR_TIMEOUT && buffer.availableForStore()>0){
89  buffer.store_char(c);
90  c = getchar_timeout_us(1000);
91  }
92  }
93  }
94 
95 
96 };
97 
103  public:
105  }
106 
107  PicoHardwareSerial(int uart_no) {
108  this->uart_no = uart_no;
109  this->uart = uart_no == 0 ? uart0 : uart1;
110  }
111 
112  virtual void begin(unsigned long baudrate=PICO_DEFAULT_UART_BAUD_RATE) {
113  begin(baudrate, SERIAL_8N1);
114  }
115 
116  virtual void begin(unsigned long baudrate, uint16_t config) {
117  begin(baudrate, config);
118  }
119 
132  virtual void begin(unsigned long baudrate, uint32_t config, int rxPin=-1, int txPin=-1, bool invert=false, bool cts=false, bool rts=false) {
133  Logger.info("begin", toStr(baudrate));
134  rx_pin = rxPin;
135  tx_pin = txPin;
136  setupDefaultRxTxPins();
137  stdio_uart_init_full(uart, baudrate, tx_pin, rx_pin);
138  uart_set_hw_flow(uart, cts, rts);
139  set_config(config);
140  open = true;
141  }
142 
143  virtual void end(){
144  uart_deinit(uart);
145  open = false;
146  }
147 
148  virtual int available(void){
149  if (buffer.available()>0){
150  return buffer.available();
151  }
152  return uart_is_readable(uart);
153  }
154 
155  virtual int availableForWrite(void){
156  return uart_is_writable(uart);
157  }
158 
159  virtual int peek(void){
160  readBuffer();
161  return buffer.peek();
162  }
163 
164  virtual int read(void){
165  readBuffer();
166  return buffer.read_char();
167  }
168 
169  virtual size_t write(uint8_t c) {
170  uart_putc(uart, c);
171  return 1;
172  }
173 
174  inline size_t write(const uint8_t *buffer, size_t size) {
175  uart_write_blocking(uart, buffer, size);
176  flush();
177  return size;
178  }
179 
180  inline size_t write(const char * buffer, size_t size) {
181  return write((uint8_t*) buffer, size);
182  }
183 
184  inline size_t write(const char * s){
185  return write((uint8_t*) s, strlen(s));
186  }
187 
188  inline size_t write(unsigned long n){
189  return write((uint8_t) n);
190  }
191 
192  inline size_t write(long n){
193  return write((uint8_t) n);
194  }
195 
196  inline size_t write(unsigned int n) {
197  return write((uint8_t) n);
198  }
199 
200  inline size_t write(int n){
201  return write((uint8_t) n);
202  }
203 
204  uint32_t baudRate(){
205  return baud_rate;
206  }
207 
208  using Print::write; // pull in write(str) and write(buf, size) from Print
209  using Print::print; // pull in write(str) and write(buf, size) from Print
210  using Print::println; // pull in write(str) and write(buf, size) from Print
211 
212 
213  virtual void flush(void) {
214  };
215 
216  virtual operator bool(){
217  return open;
218  };
219 
220 
221  protected:
222  RingBufferN<BUFFER_SIZE> buffer;
223  uart_inst_t *uart;
224  uint baud_rate;
225  int tx_pin;
226  int rx_pin;
227  int uart_no;
228  bool open = false;
229 
230  void readBuffer() {
231  // refill buffer only if it is empty
232  if (buffer.available()==0){
233  while(uart_is_readable(uart) && buffer.availableForStore()>0) {
234  char c = uart_getc(uart);
235  buffer.store_char(c);
236  }
237  }
238  }
239 
240  void set_config(uint32_t config){
241  //data, parity, and stop bits
242  switch(config){
243  case SERIAL_5N1:
244  uart_set_format(uart, 5, 1,UART_PARITY_NONE);
245  break;
246  case SERIAL_6N1:
247  uart_set_format(uart, 6, 1,UART_PARITY_NONE);
248  break;
249  case SERIAL_7N1:
250  uart_set_format(uart, 7, 1,UART_PARITY_NONE);
251  break;
252  case SERIAL_8N1:
253  uart_set_format(uart, 8, 1,UART_PARITY_NONE);
254  break;
255  case SERIAL_5N2:
256  uart_set_format(uart, 5, 2,UART_PARITY_NONE);
257  break;
258  case SERIAL_6N2:
259  uart_set_format(uart, 6, 2,UART_PARITY_NONE);
260  break;
261  case SERIAL_7N2:
262  uart_set_format(uart, 7, 2,UART_PARITY_NONE);
263  break;
264  case SERIAL_8N2:
265  uart_set_format(uart, 8, 2,UART_PARITY_NONE);
266  break;
267  case SERIAL_5E1:
268  uart_set_format(uart, 5, 1,UART_PARITY_EVEN);
269  break;
270  case SERIAL_6E1:
271  uart_set_format(uart, 6, 1,UART_PARITY_EVEN);
272  break;
273  case SERIAL_7E1:
274  uart_set_format(uart, 7, 1,UART_PARITY_EVEN);
275  break;
276  case SERIAL_8E1:
277  uart_set_format(uart, 8, 1,UART_PARITY_EVEN);
278  break;
279  case SERIAL_5E2:
280  uart_set_format(uart, 5, 2,UART_PARITY_EVEN);
281  break;
282  case SERIAL_6E2:
283  uart_set_format(uart, 6, 2,UART_PARITY_EVEN);
284  break;
285  case SERIAL_7E2:
286  uart_set_format(uart, 7, 2,UART_PARITY_EVEN);
287  break;
288  case SERIAL_8E2:
289  uart_set_format(uart, 8, 2,UART_PARITY_EVEN);
290  break;
291  case SERIAL_5O1:
292  uart_set_format(uart, 5, 1,UART_PARITY_ODD);
293  break;
294  case SERIAL_6O1:
295  uart_set_format(uart, 6, 1,UART_PARITY_ODD);
296  break;
297  case SERIAL_7O1:
298  uart_set_format(uart, 7, 1,UART_PARITY_ODD);
299  break;
300  case SERIAL_8O1:
301  uart_set_format(uart, 8, 1,UART_PARITY_ODD);
302  break;
303  case SERIAL_5O2:
304  uart_set_format(uart, 5, 2,UART_PARITY_ODD);
305  break;
306  case SERIAL_6O2:
307  uart_set_format(uart, 6, 2,UART_PARITY_ODD);
308  break;
309  case SERIAL_7O2:
310  uart_set_format(uart, 7, 2,UART_PARITY_ODD);
311  break;
312  case SERIAL_8O2:
313  uart_set_format(uart, 8, 2,UART_PARITY_ODD);
314  break;
315  };
316  }
317 
318  void setupDefaultRxTxPins(){
319  // we use different pins for uart0 and uar1. We assign values only if it has not been defined in setup
320  if (uart_no==0){
321  if (rx_pin==-1) {
322  rx_pin = 1;
323  }
324  if (tx_pin==-1){
325  tx_pin = 0;
326  }
327  } else {
328  if (rx_pin==-1){
329  rx_pin = 5;
330  }
331  if (tx_pin==-1){
332  tx_pin = 4;
333  }
334  }
335  // display pin assignments
336  if (Logger.isLogging()) {
337  Logger.info("Using UART: ", toStr(uart_no));
338  Logger.info("rxPin is ", toStr(rx_pin));
339  Logger.info("txPin is ", toStr(tx_pin));
340  }
341  if (tx_pin!=-1)
342  gpio_set_function(tx_pin, GPIO_FUNC_UART);
343  if (rx_pin!=-1)
344  gpio_set_function(rx_pin, GPIO_FUNC_UART);
345 
346  }
347 
348  const char* toStr(int value){
349  static char buffer[10];
350  itoa(value,buffer,10);
351  return (const char*)buffer;
352  }
353 };
354 
355 // #if !defined(TINYUSB_HOST_LINKED) && !defined(TINYUSB_DEVICE_LINKED)
356 // /**
357 // * @brief Output class which uses USB
358 // *
359 // */
360 // class PicoUSBSerial : public PicoDefaultSerial {
361 // PicoUSBSerial(){
362 // stdio_usb_init();
363 // }
364 
365 // // this does not do anything
366 // irtual void begin() {
367 // }
368 // };
369 // #endif
PicoDefaultSerial is using the pico default output. It is mapped to the Arduino Serial variable.
Definition: PicoHardwareSerial.h:18
Serial Stream for a defined UART. By default we use the following pins: UART0 tx/rx = gp0/gp1; UART1 ...
Definition: PicoHardwareSerial.h:102
virtual void begin(unsigned long baudrate, uint32_t config, int rxPin=-1, int txPin=-1, bool invert=false, bool cts=false, bool rts=false)
Initialization to output to UART.
Definition: PicoHardwareSerial.h:132
Definition: HardwareSerial.h:88