Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial UART HW flow control support #79

Merged
merged 5 commits into from
Aug 21, 2018
Merged

Conversation

VeijoPesonen
Copy link
Contributor

@VeijoPesonen VeijoPesonen commented Aug 13, 2018

Description

Enables UART HW flow control. Requires RTS/CTS wiring if ESP8266 is on a separate module or the pins are not connected for another reason.

Pull request type

[ ] Fix
[ ] Refactor
[ ] New target
[X] Feature
[ ] Breaking change

Example Mbed OS app config

diff --git i/tools/test_configs/ESP8266Interface.json w/tools/test_configs/ESP8266Interface.json
index 688126511..98abe61fd 100644
--- i/tools/test_configs/ESP8266Interface.json
+++ w/tools/test_configs/ESP8266Interface.json
@@ -5,11 +5,11 @@
             "value" : "\"ESP8266Interface.h\""
         },
         "object-construction" : {
-            "value" : "new ESP8266Interface( D1, D0, false )"
+            "value" : "new ESP8266Interface()"
         },
         "connect-statement" : {
             "help" : "Must use 'net' variable name, replace WIFI_SSID, WIFI_PASSWORD, WIFI_SECURITY with your WiFi settings",
-            "value" : "((ESP8266Interface *)net)->connect(WIFI_SSID, WIFI_PASSWORD, WIFI_SECURITY)"
+            "value" : "net->wifiInterface()->connect(\"SSID\", \"PASSWORD\", NSAPI_SECURITY_WPA_WPA2)"
         },
         "echo-server-addr" : {
             "help" : "IP address of echo server",
@@ -26,12 +26,22 @@
         "tcp-client-echo-buffer-size" : {
             "help" : "Number of bytes to be send to echo server",
             "value" : "200"
+        }
+    },
+    "target_overrides": {
+        "*": {
+            "esp8266.socket-bufsize": 153600,
+            "esp8266.debug": false
         },
-        "ESP8266-TX": {
-            "value":"D1"
+        "NUCLEO_F429ZI": {
+            "esp8266.rts": "PG_12",
+            "esp8266.cts": "PG_15"
         },
-        "ESP8266-RX": {
-            "value":"D0"
+        "K64F": {
+            "esp8266.tx": "PTC4",
+            "esp8266.rx": "PTC3",
+            "esp8266.cts": "PTC2",
+            "esp8266.rts": "PTC1"
         }
     }
 }

@VeijoPesonen
Copy link
Contributor Author

Status

Work in progress - would be good if someone else would also find time to test this

&& _parser.recv("OK\n");

_serial.set_flow_control(SerialBase::CTS, NC, _serial_cts);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the else case?
When no flow control pins are enabled, should it still call something, or is the point entirely skip it?

If device have flow control set as a default, should we still disable it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, on last case _serial.set_flow_contro() is called after _parser.send(), is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understad it so that we are not taking orders from ESP8266 when to send until ESP8266 is configured to do so.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When there are no pins configured for flow control there is no need to make any settings

Copy link

@kjbracey kjbracey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't actually be 100% solid. Eg if 1 app is busy streaming data, another app may be making read calls for its socket, despite the fact that the first app hasn't consumed its data. In that scenario we will be filling up local buffers with socket 1 data to deliver the socket 2 data.

Still, better than nothing.

free(q);
_heap_usage -= sizeof(struct packet) + alloc_len;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting - tabs.

@@ -304,6 +316,8 @@ class ESP8266
int _socket_open[SOCKET_COUNT];
nsapi_connection_status_t _connection_status;
Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
static const int32_t _MAX_HEAP_USAGE = MBED_CONF_ESP8266_SOCKET_BUFSIZE;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sizes should probably be size_t throughout.

_packets(0),
// Big enough, target specific
#ifndef MBED_CONF_ESP8266_SOCKET_BUFSIZE
#define MBED_CONF_ESP8266_SOCKET_BUFSIZE 102400

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have a default in the JSON, don't need a default here. (Gets confusing when people try hacking around)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I'll take this away and leave it to mbed_lib.json

_serial.set_flow_control(SerialBase::RTSCTS, _serial_rts, _serial_cts);

// Start ESP8266's flow control
done = _parser.send("AT+UART_CUR=%u,%u,%u,%u,%u", ESP8266_DEFAULT_BAUD_RATE, DATABITS_8, STOPBITS_1,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're going to the trouble of using all those %u to parametrise, then why not just have a single send call that takes the mode as a parameter, rather than putting it in 3 places?

Personally wouldn't object to just putting 8,1,0 in there literally, rather than spending the code size on the %us.

Copy link
Contributor Author

@VeijoPesonen VeijoPesonen Aug 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally wouldn't object to just putting 8,1,0 in there literally, rather than spending the code size on the %us.

I agree

packet->next = 0;

if (_parser.read((char*)(packet + 1), amount) < amount) {
free(packet);
_heap_usage -= pdu_len;
MBED_ASSERT(_heap_usage >= 0);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... Although if you did change to size_t, this would need to change to an assert that pdu_len >= _heap_usage before subtraction.

@@ -20,6 +20,7 @@
#include "ATCmdParser.h"
#include "nsapi_types.h"
#include "rtos.h"
#include "UARTSerial.h"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't see reason for added include here.


if ((_heap_usage + pdu_len) > _MAX_HEAP_USAGE) {
debug("ESP8266: socket buffer max memory limit exceeded, either increase socket buffer size from mbed_lib.json or enable UART HW flow control\n");
MBED_ASSERT(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use MBED_ERROR instead. (Ask Kari for help)

*
* @return true if started
*/
bool start_uart_hw_flow_ctrl();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be private?
We are calling this, and not expecting users to call it? am I right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Called from ESP8266Interface.cpp so needs to be public

@VeijoPesonen
Copy link
Contributor Author

Required RTS/CTS wiring

nucleo_esp8266_hw_fc1

Bootloader wiring

Be aware that the ESP8266's RTS pin is GPIO15 which is also used for boot mode selection
nucleo_esp8266_hw_fc2

GPIO0 on ESPBee

Pull down for firmware update - pull up for flash boot
espbee gpio0

References

ESPBee Pinout
ESP8266 Bootloader Modes and GPIO state on Startup
ESP8266 AT Instruction Set
Trouble Flashing Your ESP8266? Meet DIO and QIO
NUCLEO-F429ZI board pinout

@SeppoTakalo
Copy link
Contributor

Since you already have pictures, can you add section to README.md of how to enable the flow control? And add those pictures there. (Also, rotate pictures so that text is vertical)

@VeijoPesonen
Copy link
Contributor Author

Squashed and rebased

@VeijoPesonen
Copy link
Contributor Author

@marcuschangarm I fixed a stupid mistake which prevented flow control working at all. I had configured the flow control before running reset for the ESP8266.. Please update

@VeijoPesonen
Copy link
Contributor Author

README.md updated to have an example how to enable UART HW flow control

Copy link
Contributor

@SeppoTakalo SeppoTakalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the previous section The serial port does not have hardware flow control enabled.
change this to does not have hardware flow control enabled by default

Then add a note that not all modules expose RTS/CTS pins.

@VeijoPesonen VeijoPesonen merged commit 7bb1d8e into master Aug 21, 2018
@VeijoPesonen VeijoPesonen deleted the feature-hw_flow_control branch August 22, 2018 04:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants