@@ -18,6 +18,65 @@ uint8_t next_uart_num = 1;
18
18
#endif
19
19
20
20
#ifdef ARDUINO_ARCH_ESP32
21
+
22
+ #define UART_PARITY_EVEN 0 << 0
23
+ #define UART_PARITY_ODD 1 << 0
24
+ #define UART_PARITY_EN 1 << 1
25
+ #define UART_NB_BIT_5 0 << 2
26
+ #define UART_NB_BIT_6 1 << 2
27
+ #define UART_NB_BIT_7 2 << 2
28
+ #define UART_NB_BIT_8 3 << 2
29
+ #define UART_NB_STOP_BIT_1 1 << 4
30
+ #define UART_NB_STOP_BIT_2 3 << 4
31
+ #define UART_TICK_APB_CLOCK 1 << 27
32
+
33
+ uint32_t UARTComponent::get_config () {
34
+ uint32_t config = 0 ;
35
+
36
+ /*
37
+ * All bits numbers below come from
38
+ * framework-arduinoespressif32/cores/esp32/esp32-hal-uart.h
39
+ * And more specifically conf0 union in uart_dev_t.
40
+ *
41
+ * Below is bit used from conf0 union.
42
+ * <name>:<bits position> <values>
43
+ * parity:0 0:even 1:odd
44
+ * parity_en:1 Set this bit to enable uart parity check.
45
+ * bit_num:2-4 0:5bits 1:6bits 2:7bits 3:8bits
46
+ * stop_bit_num:4-6 stop bit. 1:1bit 2:1.5bits 3:2bits
47
+ * tick_ref_always_on:27 select the clock.1:apb clock:ref_tick
48
+ */
49
+
50
+ if (this ->parity_ == " even" )
51
+ config |= UART_PARITY_EVEN | UART_PARITY_EN;
52
+ else if (this ->parity_ == " odd" )
53
+ config |= UART_PARITY_ODD | UART_PARITY_EN;
54
+
55
+ switch (this ->nr_bits_ ) {
56
+ case 5 :
57
+ config |= UART_NB_BIT_5;
58
+ break ;
59
+ case 6 :
60
+ config |= UART_NB_BIT_6;
61
+ break ;
62
+ case 7 :
63
+ config |= UART_NB_BIT_7;
64
+ break ;
65
+ case 8 :
66
+ config |= UART_NB_BIT_8;
67
+ break ;
68
+ }
69
+
70
+ if (this ->stop_bits_ == 1 )
71
+ config |= UART_NB_STOP_BIT_1;
72
+ else
73
+ config |= UART_NB_STOP_BIT_2;
74
+
75
+ config |= UART_TICK_APB_CLOCK;
76
+
77
+ return config;
78
+ }
79
+
21
80
void UARTComponent::setup () {
22
81
ESP_LOGCONFIG (TAG, " Setting up UART..." );
23
82
// Use Arduino HardwareSerial UARTs if all used pins match the ones
@@ -30,10 +89,7 @@ void UARTComponent::setup() {
30
89
}
31
90
int8_t tx = this ->tx_pin_ .has_value () ? *this ->tx_pin_ : -1 ;
32
91
int8_t rx = this ->rx_pin_ .has_value () ? *this ->rx_pin_ : -1 ;
33
- uint32_t config = SERIAL_8N1;
34
- if (this ->stop_bits_ == 2 )
35
- config = SERIAL_8N2;
36
- this ->hw_serial_ ->begin (this ->baud_rate_ , config, rx, tx);
92
+ this ->hw_serial_ ->begin (this ->baud_rate_ , get_config (), rx, tx);
37
93
}
38
94
39
95
void UARTComponent::dump_config () {
@@ -45,6 +101,8 @@ void UARTComponent::dump_config() {
45
101
ESP_LOGCONFIG (TAG, " RX Pin: GPIO%d" , *this ->rx_pin_ );
46
102
}
47
103
ESP_LOGCONFIG (TAG, " Baud Rate: %u baud" , this ->baud_rate_ );
104
+ ESP_LOGCONFIG (TAG, " Bits: %u" , this ->nr_bits_ );
105
+ ESP_LOGCONFIG (TAG, " Parity: %s" , this ->parity_ .c_str ());
48
106
ESP_LOGCONFIG (TAG, " Stop bits: %u" , this ->stop_bits_ );
49
107
this ->check_logger_conflict_ ();
50
108
}
@@ -108,17 +166,46 @@ void UARTComponent::flush() {
108
166
#endif // ESP32
109
167
110
168
#ifdef ARDUINO_ARCH_ESP8266
169
+ uint32_t UARTComponent::get_config () {
170
+ uint32_t config = 0 ;
171
+
172
+ if (this ->parity_ == " none" )
173
+ config |= UART_PARITY_NONE;
174
+ else if (this ->parity_ == " even" )
175
+ config |= UART_PARITY_EVEN;
176
+ else if (this ->parity_ == " odd" )
177
+ config |= UART_PARITY_ODD;
178
+
179
+ switch (this ->nr_bits_ ) {
180
+ case 5 :
181
+ config |= UART_NB_BIT_5;
182
+ break ;
183
+ case 6 :
184
+ config |= UART_NB_BIT_6;
185
+ break ;
186
+ case 7 :
187
+ config |= UART_NB_BIT_7;
188
+ break ;
189
+ case 8 :
190
+ config |= UART_NB_BIT_8;
191
+ break ;
192
+ }
193
+
194
+ if (this ->stop_bits_ == 1 )
195
+ config |= UART_NB_STOP_BIT_1;
196
+ else
197
+ config |= UART_NB_STOP_BIT_2;
198
+
199
+ return config;
200
+ }
201
+
111
202
void UARTComponent::setup () {
112
203
ESP_LOGCONFIG (TAG, " Setting up UART bus..." );
113
204
// Use Arduino HardwareSerial UARTs if all used pins match the ones
114
205
// preconfigured by the platform. For example if RX disabled but TX pin
115
206
// is 1 we still want to use Serial.
116
- uint32_t mode = UART_NB_BIT_8 | UART_PARITY_NONE;
117
- if (this ->stop_bits_ == 1 )
118
- mode |= UART_NB_STOP_BIT_1;
119
- else
120
- mode |= UART_NB_STOP_BIT_2;
121
- SerialConfig config = static_cast <SerialConfig>(mode);
207
+ SerialConfig config = static_cast <SerialConfig>(get_config ());
208
+
122
209
if (this ->tx_pin_ .value_or (1 ) == 1 && this ->rx_pin_ .value_or (3 ) == 3 ) {
123
210
this ->hw_serial_ = &Serial;
124
211
this ->hw_serial_ ->begin (this ->baud_rate_ , config);
@@ -133,7 +220,7 @@ void UARTComponent::setup() {
133
220
this ->sw_serial_ = new ESP8266SoftwareSerial ();
134
221
int8_t tx = this ->tx_pin_ .has_value () ? *this ->tx_pin_ : -1 ;
135
222
int8_t rx = this ->rx_pin_ .has_value () ? *this ->rx_pin_ : -1 ;
136
- this ->sw_serial_ ->setup (tx, rx, this ->baud_rate_ , this ->stop_bits_ );
223
+ this ->sw_serial_ ->setup (tx, rx, this ->baud_rate_ , this ->stop_bits_ , this -> nr_bits_ , this -> parity_ );
137
224
}
138
225
}
139
226
@@ -146,6 +233,8 @@ void UARTComponent::dump_config() {
146
233
ESP_LOGCONFIG (TAG, " RX Pin: GPIO%d" , *this ->rx_pin_ );
147
234
}
148
235
ESP_LOGCONFIG (TAG, " Baud Rate: %u baud" , this ->baud_rate_ );
236
+ ESP_LOGCONFIG (TAG, " Bits: %u" , this ->nr_bits_ );
237
+ ESP_LOGCONFIG (TAG, " Parity: %s" , this ->parity_ .c_str ());
149
238
ESP_LOGCONFIG (TAG, " Stop bits: %u" , this ->stop_bits_ );
150
239
if (this ->hw_serial_ != nullptr ) {
151
240
ESP_LOGCONFIG (TAG, " Using hardware serial interface." );
@@ -250,8 +339,12 @@ void UARTComponent::flush() {
250
339
}
251
340
}
252
341
253
- void ESP8266SoftwareSerial::setup (int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate, uint8_t stop_bits) {
342
+ void ESP8266SoftwareSerial::setup (int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate, uint8_t stop_bits, uint32_t nr_bits,
343
+ std::string &parity) {
254
344
this ->bit_time_ = F_CPU / baud_rate;
345
+ this ->stop_bits_ = stop_bits;
346
+ this ->nr_bits_ = nr_bits;
347
+ this ->parity_ = parity;
255
348
if (tx_pin != -1 ) {
256
349
auto pin = GPIOPin (tx_pin, OUTPUT);
257
350
pin.setup ();
@@ -265,21 +358,22 @@ void ESP8266SoftwareSerial::setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_ra
265
358
this ->rx_buffer_ = new uint8_t [this ->rx_buffer_size_ ];
266
359
pin.attach_interrupt (ESP8266SoftwareSerial::gpio_intr, this , FALLING);
267
360
}
268
- this ->stop_bits_ = stop_bits;
269
361
}
270
362
void ICACHE_RAM_ATTR ESP8266SoftwareSerial::gpio_intr (ESP8266SoftwareSerial *arg) {
271
363
uint32_t wait = arg->bit_time_ + arg->bit_time_ / 3 - 500 ;
272
364
const uint32_t start = ESP.getCycleCount ();
273
365
uint8_t rec = 0 ;
274
366
// Manually unroll the loop
275
- rec |= arg->read_bit_ (&wait , start) << 0 ;
276
- rec |= arg->read_bit_ (&wait , start) << 1 ;
277
- rec |= arg->read_bit_ (&wait , start) << 2 ;
278
- rec |= arg->read_bit_ (&wait , start) << 3 ;
279
- rec |= arg->read_bit_ (&wait , start) << 4 ;
280
- rec |= arg->read_bit_ (&wait , start) << 5 ;
281
- rec |= arg->read_bit_ (&wait , start) << 6 ;
282
- rec |= arg->read_bit_ (&wait , start) << 7 ;
367
+ for (int i = 0 ; i < arg->nr_bits_ ; i++)
368
+ rec |= arg->read_bit_ (&wait , start) << i;
369
+
370
+ /* If parity is enabled, just read it and ignore it. */
371
+ /* TODO: Should we check parity? Or is it too slow for nothing added..*/
372
+ if (arg->parity_ == " even" )
373
+ arg->read_bit_ (&wait , start);
374
+ else if (arg->parity_ == " odd" )
375
+ arg->read_bit_ (&wait , start);
376
+
283
377
// Stop bit
284
378
arg->wait_ (&wait , start);
285
379
if (arg->stop_bits_ == 2 )
@@ -295,21 +389,29 @@ void ICACHE_RAM_ATTR HOT ESP8266SoftwareSerial::write_byte(uint8_t data) {
295
389
ESP_LOGE (TAG, " UART doesn't have TX pins set!" );
296
390
return ;
297
391
}
392
+ bool parity_bit = false ;
393
+ bool need_parity_bit = true ;
394
+ if (this ->parity_ == " even" )
395
+ parity_bit = true ;
396
+ else if (this ->parity_ == " odd" )
397
+ parity_bit = false ;
398
+ else
399
+ need_parity_bit = false ;
298
400
299
401
{
300
402
InterruptLock lock;
301
403
uint32_t wait = this ->bit_time_ ;
302
404
const uint32_t start = ESP.getCycleCount ();
303
405
// Start bit
304
406
this ->write_bit_ (false , &wait , start);
305
- this -> write_bit_ (data & ( 1 << 0 ), & wait , start);
306
- this -> write_bit_ ( data & (1 << 1 ), & wait , start );
307
- this ->write_bit_ (data & ( 1 << 2 ) , &wait , start);
308
- this -> write_bit_ (data & ( 1 << 3 ), & wait , start);
309
- this -> write_bit_ (data & ( 1 << 4 ), & wait , start) ;
310
- this -> write_bit_ (data & ( 1 << 5 ), & wait , start);
311
- this -> write_bit_ (data & ( 1 << 6 ), & wait , start);
312
- this ->write_bit_ (data & ( 1 << 7 ) , &wait , start);
407
+ for ( int i = 0 ; i < this -> nr_bits_ ; i++) {
408
+ bool bit = data & (1 << i );
409
+ this ->write_bit_ (bit , &wait , start);
410
+ if (need_parity_bit)
411
+ parity_bit ^= bit ;
412
+ }
413
+ if (need_parity_bit)
414
+ this ->write_bit_ (parity_bit , &wait , start);
313
415
// Stop bit
314
416
this ->write_bit_ (true , &wait , start);
315
417
if (this ->stop_bits_ == 2 )
0 commit comments