15
15
*/
16
16
17
17
#include " ESP8266.h"
18
- #include " mbed_debug.h"
18
+ #include " Callback.h"
19
+ #include " mbed_error.h"
19
20
#include " nsapi_types.h"
21
+ #include " PinNames.h"
20
22
21
23
#include < cstring>
22
24
23
25
#define ESP8266_DEFAULT_BAUD_RATE 115200
24
26
#define ESP8266_ALL_SOCKET_IDS -1
25
27
26
- ESP8266::ESP8266 (PinName tx, PinName rx, bool debug)
27
- : _serial(tx, rx, ESP8266_DEFAULT_BAUD_RATE),
28
- _parser(&_serial),
29
- _packets(0 ),
28
+ ESP8266::ESP8266 (PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
29
+ : _serial(tx, rx, ESP8266_DEFAULT_BAUD_RATE),
30
+ _serial_rts(rts),
31
+ _serial_cts(cts),
32
+ _parser(&_serial),
33
+ _packets(0 ),
30
34
_packets_end(&_packets),
31
35
_connect_error(0 ),
32
36
_fail(false ),
33
37
_closed(false ),
34
38
_socket_open(),
35
- _connection_status(NSAPI_STATUS_DISCONNECTED)
39
+ _connection_status(NSAPI_STATUS_DISCONNECTED),
40
+ _heap_usage(0 )
36
41
{
37
42
_serial.set_baud ( ESP8266_DEFAULT_BAUD_RATE );
38
43
_parser.debug_on (debug);
@@ -70,6 +75,34 @@ int ESP8266::get_firmware_version()
70
75
}
71
76
}
72
77
78
+ bool ESP8266::start_uart_hw_flow_ctrl (void )
79
+ {
80
+ bool done = true ;
81
+
82
+ if (_serial_rts != NC && _serial_cts != NC) {
83
+ // Start board's flow control
84
+ _serial.set_flow_control (SerialBase::RTSCTS, _serial_rts, _serial_cts);
85
+
86
+ // Start ESP8266's flow control
87
+ done = _parser.send (" AT+UART_CUR=%u,8,1,0,3" , ESP8266_DEFAULT_BAUD_RATE)
88
+ && _parser.recv (" OK\n " );
89
+
90
+ } else if (_serial_rts != NC) {
91
+ _serial.set_flow_control (SerialBase::RTS, _serial_rts, NC);
92
+
93
+ done = _parser.send (" AT+UART_CUR=%u,8,1,0,2" , ESP8266_DEFAULT_BAUD_RATE)
94
+ && _parser.recv (" OK\n " );
95
+
96
+ } else if (_serial_cts != NC) {
97
+ done = _parser.send (" AT+UART_CUR=%u,8,1,0,1" , ESP8266_DEFAULT_BAUD_RATE)
98
+ && _parser.recv (" OK\n " );
99
+
100
+ _serial.set_flow_control (SerialBase::CTS, NC, _serial_cts);
101
+ }
102
+
103
+ return done;
104
+ }
105
+
73
106
bool ESP8266::startup (int mode)
74
107
{
75
108
if (!(mode == WIFIMODE_STATION || mode == WIFIMODE_SOFTAP
@@ -361,7 +394,10 @@ nsapi_error_t ESP8266::send(int id, const void *data, uint32_t amount)
361
394
if (_parser.send (" AT+CIPSEND=%d,%lu" , id, amount)
362
395
&& _parser.recv (" >" )
363
396
&& _parser.write ((char *)data, (int )amount) >= 0 ) {
364
- while (_parser.process_oob ()); // multiple sends in a row require this
397
+ // No flow control, data overrun is possible
398
+ if (_serial_rts == NC) {
399
+ while (_parser.process_oob ()); // Drain USART receive register
400
+ }
365
401
_smutex.unlock ();
366
402
return NSAPI_ERROR_OK;
367
403
}
@@ -376,25 +412,37 @@ void ESP8266::_packet_handler()
376
412
{
377
413
int id;
378
414
int amount;
415
+ int pdu_len;
379
416
380
417
// parse out the packet
381
418
if (!_parser.recv (" ,%d,%d:" , &id, &amount)) {
382
419
return ;
383
420
}
384
421
385
- struct packet *packet = (struct packet *)malloc (
386
- sizeof (struct packet ) + amount);
422
+ pdu_len = sizeof (struct packet ) + amount;
423
+
424
+ if ((_heap_usage + pdu_len) > MBED_CONF_ESP8266_SOCKET_BUFSIZE) {
425
+ MBED_WARNING (MBED_MAKE_ERROR (MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOBUFS), \
426
+ " ESP8266::_packet_handler(): \" esp8266.socket-bufsize\" -limit exceeded, packet dropped" );
427
+ return ;
428
+ }
429
+
430
+ struct packet *packet = (struct packet *)malloc (pdu_len);
387
431
if (!packet) {
388
- debug (" ESP8266: could not allocate memory for RX data\n " );
432
+ MBED_WARNING (MBED_MAKE_ERROR (MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
433
+ " ESP8266::_packet_handler(): Could not allocate memory for RX data" );
389
434
return ;
390
435
}
436
+ _heap_usage += pdu_len;
391
437
392
438
packet->id = id;
393
439
packet->len = amount;
440
+ packet->alloc_len = amount;
394
441
packet->next = 0 ;
395
442
396
443
if (_parser.read ((char *)(packet + 1 ), amount) < amount) {
397
444
free (packet);
445
+ _heap_usage -= pdu_len;
398
446
return ;
399
447
}
400
448
@@ -403,17 +451,23 @@ void ESP8266::_packet_handler()
403
451
_packets_end = &packet->next ;
404
452
}
405
453
454
+ void ESP8266::process_oob (uint32_t timeout, bool all) {
455
+ setTimeout (timeout);
456
+ // Poll for inbound packets
457
+ while (_parser.process_oob () && all) {
458
+ }
459
+ setTimeout ();
460
+ }
461
+
406
462
int32_t ESP8266::recv_tcp (int id, void *data, uint32_t amount, uint32_t timeout)
407
463
{
408
464
_smutex.lock ();
409
- setTimeout (timeout);
410
465
411
- // Poll for inbound packets
412
- while (_parser.process_oob ()) {
466
+ // No flow control, drain the USART receive register ASAP to avoid data overrun
467
+ if (_serial_rts == NC) {
468
+ process_oob (timeout, true );
413
469
}
414
470
415
- setTimeout ();
416
-
417
471
// check if any packets are ready for us
418
472
for (struct packet **p = &_packets; *p; p = &(*p)->next ) {
419
473
if ((*p)->id == id) {
@@ -426,10 +480,13 @@ int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
426
480
_packets_end = p;
427
481
}
428
482
*p = (*p)->next ;
483
+
429
484
_smutex.unlock ();
430
485
486
+ uint32_t pdu_len = sizeof (struct packet ) + q->alloc_len ;
431
487
uint32_t len = q->len ;
432
488
free (q);
489
+ _heap_usage -= pdu_len;
433
490
return len;
434
491
} else { // return only partial packet
435
492
memcpy (data, q+1 , amount);
@@ -446,6 +503,11 @@ int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
446
503
_smutex.unlock ();
447
504
return 0 ;
448
505
}
506
+
507
+ // Flow control, read from USART receive register only when no more data is buffered, and as little as possible
508
+ if (_serial_rts != NC) {
509
+ process_oob (timeout, false );
510
+ }
449
511
_smutex.unlock ();
450
512
451
513
return NSAPI_ERROR_WOULD_BLOCK;
@@ -477,7 +539,9 @@ int32_t ESP8266::recv_udp(int id, void *data, uint32_t amount, uint32_t timeout)
477
539
*p = (*p)->next ;
478
540
_smutex.unlock ();
479
541
542
+ uint32_t pdu_len = sizeof (struct packet ) + q->alloc_len ;
480
543
free (q);
544
+ _heap_usage -= pdu_len;
481
545
return len;
482
546
}
483
547
}
@@ -493,13 +557,14 @@ void ESP8266::_clear_socket_packets(int id)
493
557
while (*p) {
494
558
if ((*p)->id == id || id == ESP8266_ALL_SOCKET_IDS) {
495
559
struct packet *q = *p;
560
+ int pdu_len = sizeof (struct packet ) + q->alloc_len ;
496
561
497
562
if (_packets_end == &(*p)->next ) {
498
563
_packets_end = p; // Set last packet next field/_packets
499
564
}
500
565
*p = (*p)->next ;
501
-
502
566
free (q);
567
+ _heap_usage -= pdu_len;
503
568
} else {
504
569
// Point to last packet next field
505
570
p = &(*p)->next ;
0 commit comments