HardwareSerial.h 8.5 KB
Newer Older
M
me-no-dev 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 HardwareSerial.h - Hardware serial library for Wiring
 Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 Modified 28 September 2010 by Mark Sproul
 Modified 14 August 2012 by Alarus
 Modified 3 December 2013 by Matthijs Kooijman
 Modified 18 December 2014 by Ivan Grokhotkov (esp8266 platform support)
 Modified 31 March 2015 by Markus Sattler (rewrite the code for UART0 + UART1 support in ESP8266)
 Modified 25 April 2015 by Thomas Flayols (add configuration different from 8N1 in ESP8266)
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
 Modified 13 October 2018 by Jeroen Döll (add baudrate detection)
 Baudrate detection example usage (detection on Serial1):
   void setup() {
     Serial.begin(115200);
     delay(100);
     Serial.println();

     Serial1.begin(0, SERIAL_8N1, -1, -1, true, 11000UL);  // Passing 0 for baudrate to detect it, the last parameter is a timeout in ms

     unsigned long detectedBaudRate = Serial1.baudRate();
     if(detectedBaudRate) {
       Serial.printf("Detected baudrate is %lu\n", detectedBaudRate);
     } else {
       Serial.println("No baudrate detected, Serial1 will not work!");
     }
   }

 Pay attention: the baudrate returned by baudRate() may be rounded, eg 115200 returns 115201
M
me-no-dev 已提交
43 44 45 46 47 48
 */

#ifndef HardwareSerial_h
#define HardwareSerial_h

#include <inttypes.h>
49
#include <functional>
M
me-no-dev 已提交
50 51
#include "Stream.h"
#include "esp32-hal.h"
52
#include "soc/soc_caps.h"
53
#include "HWCDC.h"
M
me-no-dev 已提交
54

55 56 57 58 59
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"

typedef enum {
60
    UART_NO_ERROR,
61 62 63 64 65 66 67 68 69 70
    UART_BREAK_ERROR,
    UART_BUFFER_FULL_ERROR,
    UART_FIFO_OVF_ERROR,
    UART_FRAME_ERROR,
    UART_PARITY_ERROR
} hardwareSerial_error_t;

typedef std::function<void(void)> OnReceiveCb;
typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb;

M
me-no-dev 已提交
71 72 73 74
class HardwareSerial: public Stream
{
public:
    HardwareSerial(int uart_nr);
75
    ~HardwareSerial();
M
me-no-dev 已提交
76

77 78 79 80 81 82 83 84
    // setRxTimeout sets the timeout after which onReceive callback will be called (after receiving data, it waits for this time of UART rx inactivity to call the callback fnc)
    // param symbols_timeout defines a timeout threshold in uart symbol periods. Setting 0 symbol timeout disables the callback call by timeout.
    //                       Maximum timeout setting is calculacted automatically by IDF. If set above the maximum, it is ignored and an error is printed on Serial0 (check console).
    //                       Examples: Maximum for 11 bits symbol is 92 (SERIAL_8N2, SERIAL_8E1, SERIAL_8O1, etc), Maximum for 10 bits symbol is 101 (SERIAL_8N1).
    //                       For example symbols_timeout=1 defines a timeout equal to transmission time of one symbol (~11 bit) on current baudrate. 
    //                       For a baudrate of 9600, SERIAL_8N1 (10 bit symbol) and symbols_timeout = 3, the timeout would be 3 / (9600 / 10) = 3.125 ms
    void setRxTimeout(uint8_t symbols_timeout);

85 86 87 88 89 90
    // setRxFIFOFull(uint8_t fifoBytes) will set the number of bytes that will trigger UART_INTR_RXFIFO_FULL interrupt and fill up RxRingBuffer
    // This affects some functions such as Serial::available() and Serial.read() because, in a UART flow of receiving data, Serial internal 
    // RxRingBuffer will be filled only after these number of bytes arrive or a RX Timeout happens.
    // This parameter can be set to 1 in order to receive byte by byte, but it will also consume more CPU time as the ISR will be activates often.
    void setRxFIFOFull(uint8_t fifoBytes);

91 92 93 94 95 96 97 98 99 100
    // onReceive will setup a callback that will be called whenever an UART interruption occurs (UART_INTR_RXFIFO_FULL or UART_INTR_RXFIFO_TOUT)
    // UART_INTR_RXFIFO_FULL interrupt triggers at UART_FULL_THRESH_DEFAULT bytes received (defined as 120 bytes by default in IDF)
    // UART_INTR_RXFIFO_TOUT interrupt triggers at UART_TOUT_THRESH_DEFAULT symbols passed without any reception (defined as 10 symbos by default in IDF)
    // onlyOnTimeout parameter will define how onReceive will behave:
    // Default: true -- The callback will only be called when RX Timeout happens. 
    //                  Whole stream of bytes will be ready for being read on the callback function at once.
    //                  This option may lead to Rx Overflow depending on the Rx Buffer Size and number of bytes received in the streaming
    //         false -- The callback will be called when FIFO reaches 120 bytes and also on RX Timeout.
    //                  The stream of incommig bytes will be "split" into blocks of 120 bytes on each callback.
    //                  This option avoid any sort of Rx Overflow, but leaves the UART packet reassembling work to the Application.
101
    void onReceive(OnReceiveCb function, bool onlyOnTimeout = false);
102 103

    // onReceive will be called on error events (see hardwareSerial_error_t)
104
    void onReceiveError(OnReceiveErrorCb function);
105 106 107

    // eventQueueReset clears all events in the queue (the events that trigger onReceive and onReceiveError) - maybe usefull in some use cases
    void eventQueueReset();
108
 
109
    void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);
110
    void end(bool fullyTerminate = true);
111
    void updateBaudRate(unsigned long baud);
M
me-no-dev 已提交
112
    int available(void);
113
    int availableForWrite(void);
M
me-no-dev 已提交
114 115
    int peek(void);
    int read(void);
116 117 118 119 120
    size_t read(uint8_t *buffer, size_t size);
    inline size_t read(char * buffer, size_t size)
    {
        return read((uint8_t*) buffer, size);
    }
M
me-no-dev 已提交
121
    void flush(void);
C
chuck todd 已提交
122
    void flush( bool txOnly);
M
me-no-dev 已提交
123 124
    size_t write(uint8_t);
    size_t write(const uint8_t *buffer, size_t size);
125 126 127 128
    inline size_t write(const char * buffer, size_t size)
    {
        return write((uint8_t*) buffer, size);
    }
129 130 131 132
    inline size_t write(const char * s)
    {
        return write((uint8_t*) s, strlen(s));
    }
M
me-no-dev 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
    inline size_t write(unsigned long n)
    {
        return write((uint8_t) n);
    }
    inline size_t write(long n)
    {
        return write((uint8_t) n);
    }
    inline size_t write(unsigned int n)
    {
        return write((uint8_t) n);
    }
    inline size_t write(int n)
    {
        return write((uint8_t) n);
    }
L
Luc 已提交
149
    uint32_t baudRate();
M
me-no-dev 已提交
150 151 152
    operator bool() const;

    void setDebugOutput(bool);
153 154
    
    void setRxInvert(bool);
155 156 157 158 159 160 161

    // Negative Pin Number will keep it unmodified, thus this function can set individual pins
    // SetPins shall be called after Serial begin()
    void setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin = -1, int8_t rtsPin = -1);
    // Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
    void setHwFlowCtrlMode(uint8_t mode = HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64);   // 64 is half FIFO Length

162
    size_t setRxBufferSize(size_t new_size);
163
    size_t setTxBufferSize(size_t new_size);
M
me-no-dev 已提交
164 165 166 167

protected:
    int _uart_nr;
    uart_t* _uart;
168
    size_t _rxBufferSize;
169
    size_t _txBufferSize;
170
    OnReceiveCb _onReceiveCB;
171
    OnReceiveErrorCb _onReceiveErrorCB;
172 173 174
    // _onReceive and _rxTimeout have be consistent when timeout is disabled
    bool _onReceiveTimeout;
    uint8_t _rxTimeout;
175
    TaskHandle_t _eventTask;
176 177 178
#if !CONFIG_DISABLE_HAL_LOCKS
    SemaphoreHandle_t _lock;
#endif
179 180 181 182

    void _createEventTask(void *args);
    void _destroyEventTask(void);
    static void _uartEventTask(void *args);
M
me-no-dev 已提交
183 184
};

D
Dirk O. Kaar 已提交
185 186
extern void serialEventRun(void) __attribute__((weak));

187
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
188 189
#ifndef ARDUINO_USB_CDC_ON_BOOT
#define ARDUINO_USB_CDC_ON_BOOT 0
190
#endif
191
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
M
Me No Dev 已提交
192
#if !ARDUINO_USB_MODE
193 194
#include "USB.h"
#include "USBCDC.h"
M
Me No Dev 已提交
195
#endif
196
extern HardwareSerial Serial0;
197
#else
M
me-no-dev 已提交
198
extern HardwareSerial Serial;
199
#endif
200
#if SOC_UART_NUM > 1
201
extern HardwareSerial Serial1;
202 203
#endif
#if SOC_UART_NUM > 2
204
extern HardwareSerial Serial2;
205
#endif
206
#endif
M
me-no-dev 已提交
207

D
Dirk O. Kaar 已提交
208
#endif // HardwareSerial_h