ESP3D  3.0
Firmware for ESP boards connected to 3D Printer
serial_service.cpp
Go to the documentation of this file.
1 /*
2  serial_service.cpp - serial services functions class
3 
4  Copyright (c) 2014 Luc Lebosse. All rights reserved.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
21 #include "../../include/esp3d_config.h"
22 #include "serial_service.h"
23 #include "../../core/settings_esp3d.h"
24 #include "../../core/esp3doutput.h"
25 #include "../../core/commands.h"
26 
27 //Serial Parameters
28 #define ESP_SERIAL_PARAM SERIAL_8N1
29 
30 #if ESP_SERIAL_OUTPUT == USE_SERIAL_0
31 #define ESP3D_SERIAL Serial
32 #endif //USE_SERIAL_0
33 
34 #if ESP_SERIAL_OUTPUT == USE_SERIAL_1
35 #define ESP3D_SERIAL Serial1
36 #endif //USE_SERIAL_1
37 
38 #if ESP_SERIAL_OUTPUT == USE_SERIAL_2
39 #define ESP3D_SERIAL Serial2
40 #endif //USE_SERIAL_2
41 
43 
44 const long SupportedBaudList[] = {9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 921600};
45 
46 #define TIMEOUT_SERIAL_FLUSH 1500
47 //Constructor
49 {
50  _buffer_size = 0;
51  _started = false;
52 }
53 
54 //Destructor
56 {
57  end();
58 }
59 
60 //Setup Serial
62 {
63  _lastflush = millis();
64  //read from settings
66  _buffer_size = 0;
67  //change only if different from current
68  if (br != baudRate() || (ESP_RX_PIN != -1) || (ESP_TX_PIN != -1)) {
69  if ( !is_valid_baudrate(br)) {
71  }
72 #ifdef ARDUINO_ARCH_ESP8266
73  ESP3D_SERIAL.begin(br, SERIAL_8N1, SERIAL_FULL, (ESP_TX_PIN == -1)?1:ESP_TX_PIN);
74 #if ESP_RX_PIN != -1
75  ESP3D_SERIAL.pins((ESP_TX_PIN == -1)?1:ESP_TX_PIN, ESP_RX_PIN)
76 #endif //ESP_RX_PIN != -1
77 #endif //ARDUINO_ARCH_ESP8266
78 #ifdef ARDUINO_ARCH_ESP32
79  ESP3D_SERIAL.begin (br, ESP_SERIAL_PARAM, ESP_RX_PIN, ESP_TX_PIN);
80 #endif //ARDUINO_ARCH_ESP32
81  }
82  ESP3D_SERIAL.setRxBufferSize (SERIAL_RX_BUFFER_SIZE);
83  _started = true;
84  return true;
85 }
86 //End serial
88 {
89  flush();
90  delay (100);
91  swap();
92  ESP3D_SERIAL.end();
93  _buffer_size = 0;
94  _started = false;
95  return true;
96 }
97 
98 //return the array of long and array size
99 const long * SerialService::get_baudratelist(uint8_t * count)
100 {
101  if (count) {
102  *count = sizeof(SupportedBaudList)/sizeof(long);
103  }
104  return SupportedBaudList;
105 }
106 
107 //check if value is in baudrate list
109 {
110  uint8_t listesize = sizeof(SupportedBaudList)/sizeof(long);
111  for (uint8_t i = 0; i < listesize ; i++) {
112  if (SupportedBaudList[i] == br) {
113  return true;
114  }
115  }
116  return false;
117 }
118 
119 //Function which could be called in other loop
121 {
122  //Do we have some data waiting
123  size_t len = available();
124  if (len > 0) {
125  //if yes read them
126  uint8_t * sbuf = (uint8_t *)malloc(len);
127  if(sbuf) {
128  size_t count = readBytes(sbuf, len);
129  //push to buffer
130  if (count > 0) {
131  push2buffer(sbuf, count);
132  }
133  //freen buffer
134  free(sbuf);
135  }
136  }
137  //we cannot left data in buffer too long
138  //in case some commands "forget" to add \n
139  if (((millis() - _lastflush) > TIMEOUT_SERIAL_FLUSH) && (_buffer_size > 0)) {
140  flushbuffer();
141  }
142 }
143 
144 void SerialService::flushbuffer()
145 {
147  _buffer[_buffer_size] = 0x0;
148  //dispatch command
149  esp3d_commands.process(_buffer, _buffer_size, &output);
150  _lastflush = millis();
151  _buffer_size = 0;
152 }
153 
154 //push collected data to buffer and proceed accordingly
155 void SerialService::push2buffer(uint8_t * sbuf, size_t len)
156 {
157  for (size_t i = 0; i < len; i++) {
158  _lastflush = millis();
159  //command is defined
160  if (char(sbuf[i]) == '\n') {
161  if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) {
162  _buffer[_buffer_size] = sbuf[i];
163  _buffer_size++;
164  }
165  flushbuffer();
166  } else if (isPrintable (char(sbuf[i]) ) || char(sbuf[i]) == '\r') {
167  if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) {
168  _buffer[_buffer_size] = sbuf[i];
169  _buffer_size++;
170  } else {
171  flushbuffer();
172  _buffer[_buffer_size] = sbuf[i];
173  _buffer_size++;
174  }
175  } else { //it is not printable char
176  //clean buffer first
177  if (_buffer_size > 0) {
178  flushbuffer();
179  }
180  //process char
181  _buffer[_buffer_size] = sbuf[i];
182  _buffer_size++;
183  flushbuffer();
184  }
185  }
186 }
187 
188 //Reset Serial Setting (baud rate)
190 {
191  log_esp3d("Reset serial");
193 }
194 
195 //Get current baud rate
197 {
198  long br = 0;
199  br = ESP3D_SERIAL.baudRate();
200 #ifdef ARDUINO_ARCH_ESP32
201  //workaround for ESP32
202  if (br == 115201) {
203  br = 115200;
204  }
205  if (br == 230423) {
206  br = 230400;
207  }
208 #endif //ARDUINO_ARCH_ESP32
209  return br;
210 }
211 
212 size_t SerialService::write(uint8_t c)
213 {
214  return ESP3D_SERIAL.write(c);
215 }
216 
217 size_t SerialService::write(const uint8_t *buffer, size_t size)
218 {
219  if ((uint)ESP3D_SERIAL.availableForWrite() >= size) {
220  return ESP3D_SERIAL.write(buffer, size);
221  } else {
222  size_t sizetosend = size;
223  size_t sizesent = 0;
224  uint8_t *buffertmp=(uint8_t *)buffer;
225  uint32_t starttime = millis();
226  //loop until all is sent or timeout
227  while (sizetosend>0 && ((millis() - starttime) < 100)) {
228  size_t available = ESP3D_SERIAL.availableForWrite();
229  if(available>0) {
230  //in case less is sent
231  available = ESP3D_SERIAL.write(&buffertmp[sizesent], (available >= sizetosend)?sizetosend:available);
232  sizetosend-=available;
233  sizesent+=available;
234  starttime=millis();
235  } else {
236  Hal::wait(5);
237  }
238  }
239  return sizesent;
240  }
241 }
242 
244 {
245  return ESP3D_SERIAL.availableForWrite();
246 }
247 
249 {
250  return ESP3D_SERIAL.available();
251 }
252 
254 {
255  return ESP3D_SERIAL.read();
256 }
257 
258 size_t SerialService::readBytes(uint8_t * sbuf, size_t len)
259 {
260  return ESP3D_SERIAL.readBytes(sbuf, len);
261 }
262 
264 {
265  ESP3D_SERIAL.flush();
266 }
267 
269 {
270 #ifdef ARDUINO_ARCH_ESP8266
271  ESP3D_SERIAL.swap();
272 #endif //ARDUINO_ARCH_ESP8266
273 }
esp3d_commands
Commands esp3d_commands
Definition: commands.cpp:26
SerialService::availableForWrite
uint availableForWrite()
Definition: serial_service.cpp:243
Hal::wait
static void wait(uint32_t milliseconds)
Definition: hal.cpp:226
SerialService::write
size_t write(uint8_t c)
Definition: serial_service.cpp:212
SerialService::~SerialService
~SerialService()
Definition: serial_service.cpp:55
Settings_ESP3D::get_default_int32_value
static uint32_t get_default_int32_value(int pos)
Definition: settings_esp3d.cpp:342
ESP3D_SERIAL_BUFFER_SIZE
#define ESP3D_SERIAL_BUFFER_SIZE
Definition: serial_service.h:26
SerialService
Definition: serial_service.h:28
SerialService::begin
bool begin()
Definition: serial_service.cpp:61
Commands::process
void process(uint8_t *sbuf, size_t len, ESP3DOutput *output, level_authenticate_type auth=LEVEL_GUEST, ESP3DOutput *outputonly=nullptr)
Definition: commands.cpp:36
SerialService::get_baudratelist
const long * get_baudratelist(uint8_t *count)
Definition: serial_service.cpp:99
SerialService::end
bool end()
Definition: serial_service.cpp:87
SerialService::reset
bool reset()
Definition: serial_service.cpp:189
ESP_BAUD_RATE
#define ESP_BAUD_RATE
Definition: settings_esp3d.h:46
SerialService::handle
void handle()
Definition: serial_service.cpp:120
SerialService::SerialService
SerialService()
Definition: serial_service.cpp:48
SerialService::baudRate
long baudRate()
Definition: serial_service.cpp:196
Settings_ESP3D::write_uint32
static bool write_uint32(int pos, const uint32_t value)
Definition: settings_esp3d.cpp:970
SerialService::swap
void swap()
Definition: serial_service.cpp:268
serial_service.h
SerialService::is_valid_baudrate
bool is_valid_baudrate(long br)
Definition: serial_service.cpp:108
serial_service
SerialService serial_service
Definition: serial_service.cpp:42
ESP_SERIAL_CLIENT
#define ESP_SERIAL_CLIENT
Definition: esp3doutput.h:22
SupportedBaudList
const long SupportedBaudList[]
Definition: serial_service.cpp:44
ESP_TX_PIN
#define ESP_TX_PIN
Definition: pins.h:26
log_esp3d
#define log_esp3d(format,...)
Definition: debug_esp3d.h:29
Settings_ESP3D::read_uint32
static uint32_t read_uint32(int pos, bool *haserror=NULL)
Definition: settings_esp3d.cpp:919
SerialService::readBytes
size_t readBytes(uint8_t *sbuf, size_t len)
Definition: serial_service.cpp:258
TIMEOUT_SERIAL_FLUSH
#define TIMEOUT_SERIAL_FLUSH
Definition: serial_service.cpp:46
SerialService::available
int available()
Definition: serial_service.cpp:248
ESP_RX_PIN
#define ESP_RX_PIN
Definition: pins.h:25
ESP_SERIAL_PARAM
#define ESP_SERIAL_PARAM
Definition: serial_service.cpp:28
SERIAL_RX_BUFFER_SIZE
#define SERIAL_RX_BUFFER_SIZE
Definition: configuration.h:233
SerialService::flush
void flush()
Definition: serial_service.cpp:263
ESP3DOutput
Definition: esp3doutput.h:48
SerialService::read
int read()
Definition: serial_service.cpp:253