Skip to content

Commit 509e1a5

Browse files
authored
Improve ESP32 connect (#64)
1 parent 6d611c2 commit 509e1a5

File tree

3 files changed

+142
-35
lines changed

3 files changed

+142
-35
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ nanoff --help
6060

6161
## ESP32 usage examples
6262

63+
>Note: some ESP32 boards have issues entering bootloader mode. This can be usually overcome by holding down the BOOT/FLASH button in the board.
64+
In case nanoff detects this situation the following warning is shown:
65+
```console
66+
*** Hold down the BOOT/FLASH button in ESP32 board ***
67+
```
68+
6369
### Update the firmware of an ESP32_WROOM_32 target
6470

6571
To update the firmware of an ESP32_WROOM_32 target connected to COM31, to the latest available development version.

nanoFirmwareFlasher/Esp32Operations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ internal static async System.Threading.Tasks.Task<ExitCodes> UpdateFirmwareAsync
190190
if (verbosity >= VerbosityLevel.Normal)
191191
{
192192
Console.ForegroundColor = ConsoleColor.White;
193-
Console.Write($"Erasing flash...");
193+
Console.WriteLine($"Erasing flash...");
194194
}
195195

196196
if (updateFw)

nanoFirmwareFlasher/EspTool.cs

Lines changed: 135 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ internal class EspTool
6161
/// true if the stub program is already active and we can use the --before no_reset_no_sync parameter
6262
/// </summary>
6363
private bool _isStubActive = false;
64+
private bool connectPatternFound;
65+
private DateTime connectTimeStamp;
66+
private bool connectPromptShown;
6467

6568
/// <summary>
6669
/// This property is <see langword="true"/> if the specified COM port is valid.
@@ -197,27 +200,41 @@ internal EspTool(
197200
/// <returns>The filled info structure with all the information about the connected ESP32 chip or null if an error occured</returns>
198201
internal DeviceInfo TestChip()
199202
{
203+
if (Verbosity >= VerbosityLevel.Normal)
204+
{
205+
Console.ForegroundColor = ConsoleColor.White;
206+
Console.WriteLine($"Reading MAC from chip...");
207+
}
208+
200209
// execute read_mac command and parse the result
201210
if (!RunEspTool("read_mac", true, false, null, out string messages))
202211
{
203212
throw new EspToolExecutionException(messages);
204213
}
205214

215+
if (Verbosity >= VerbosityLevel.Normal)
216+
{
217+
Console.ForegroundColor = ConsoleColor.Green;
218+
Console.WriteLine("OK");
219+
Console.ForegroundColor = ConsoleColor.White;
220+
}
221+
206222
var match = Regex.Match(messages, "(esptool.py v)(?<version>[0-9.]+)(.*?[\r\n]*)*(Chip is )(?<name>.*)(.*?[\r\n]*)*(Features: )(?<features>.*)(.*?[\r\n]*)*(MAC: )(?<mac>.*)");
207223
if (!match.Success)
208224
{
209225
throw new EspToolExecutionException(messages);
210226
}
211227

212-
// that gives us the version of the esptool.py, the chip name and the MAC address
228+
// that gives us the chip version, name, features and the MAC address
213229
string version = match.Groups["version"].ToString().Trim();
214230
string name = match.Groups["name"].ToString().Trim();
215231
string features = match.Groups["features"].ToString().Trim();
216232
string mac = match.Groups["mac"].ToString().Trim();
217233

218-
if (Verbosity >= VerbosityLevel.Diagnostic)
234+
if (Verbosity >= VerbosityLevel.Normal)
219235
{
220-
Console.WriteLine($"Executed esptool.py version {version}");
236+
Console.ForegroundColor = ConsoleColor.White;
237+
Console.WriteLine($"Reading flash ID from chip...");
221238
}
222239

223240
// execute flash_id command and parse the result
@@ -226,6 +243,13 @@ internal DeviceInfo TestChip()
226243
throw new EspToolExecutionException(messages);
227244
}
228245

246+
if (Verbosity >= VerbosityLevel.Normal)
247+
{
248+
Console.ForegroundColor = ConsoleColor.Green;
249+
Console.WriteLine("OK");
250+
Console.ForegroundColor = ConsoleColor.White;
251+
}
252+
229253
match = Regex.Match(messages, $"(Manufacturer: )(?<manufacturer>.*)(.*?[\r\n]*)*(Device: )(?<device>.*)(.*?[\r\n]*)*(Detected flash size: )(?<size>.*)");
230254
if (!match.Success)
231255
{
@@ -435,55 +459,88 @@ private bool RunEspTool(
435459
};
436460

437461
// start esptool and wait for exit
438-
if (espTool.Start())
439-
{
440-
// if no progress output needed wait unlimited time until esptool exit
441-
if (Verbosity < VerbosityLevel.Detailed &&
442-
!progressTestChar.HasValue)
443-
{
444-
espTool.WaitForExit();
445-
}
446-
}
447-
else
462+
if (!espTool.Start())
448463
{
449464
throw new EspToolExecutionException("Error starting esptool!");
450465
}
451466

452467
var messageBuilder = new StringBuilder();
453468

469+
// reset these
470+
connectPromptShown = false;
471+
connectPatternFound = false;
472+
connectTimeStamp = DateTime.UtcNow;
473+
454474
// showing progress is a little bit tricky
455-
if (progressTestChar.HasValue && Verbosity >= VerbosityLevel.Detailed)
475+
if (Verbosity > VerbosityLevel.Quiet)
456476
{
457-
// loop until esptool exit
458-
while (!espTool.HasExited)
477+
if (progressTestChar.HasValue)
459478
{
460-
// loop until there is no next char to read from standard output
461-
while (true)
479+
// need to look for progress test char
480+
481+
// loop until esptool exit
482+
while (!espTool.HasExited)
462483
{
463-
int next = espTool.StandardOutput.Read();
464-
if (next != -1)
484+
// loop until there is no next char to read from standard output
485+
while (true)
465486
{
466-
// append the char to the message buffer
467-
messageBuilder.Append((char)next);
468-
// try to find a progress message
469-
string progress = FindProgress(messageBuilder, progressTestChar.Value);
470-
if (progress != null)
487+
int next = espTool.StandardOutput.Read();
488+
if (next != -1)
471489
{
472-
// print progress and set the cursor to the beginning of the line (\r)
473-
Console.Write(progress);
474-
Console.Write("\r");
490+
// append the char to the message buffer
491+
messageBuilder.Append((char)next);
492+
493+
// try to find a progress message
494+
string progress = FindProgress(messageBuilder, progressTestChar.Value);
495+
if (progress != null && Verbosity > VerbosityLevel.Quiet)
496+
{
497+
// print progress and set the cursor to the beginning of the line (\r)
498+
Console.Write(progress);
499+
Console.Write("\r");
500+
}
501+
502+
ProcessConnectPattern(messageBuilder);
503+
}
504+
else
505+
{
506+
break;
475507
}
476508
}
477-
else
509+
}
510+
511+
// collect the last messages
512+
messageBuilder.AppendLine(espTool.StandardOutput.ReadToEnd());
513+
messageBuilder.Append(espTool.StandardError.ReadToEnd());
514+
}
515+
else
516+
{
517+
// when not looking for progress char, look for connect pattern
518+
519+
// loop until esptool exit
520+
while (!espTool.HasExited)
521+
{
522+
// loop until there is no next char to read from standard output
523+
while (true)
478524
{
479-
break;
525+
int next = espTool.StandardOutput.Read();
526+
if (next != -1)
527+
{
528+
// append the char to the message buffer
529+
messageBuilder.Append((char)next);
530+
531+
ProcessConnectPattern(messageBuilder);
532+
}
533+
else
534+
{
535+
break;
536+
}
480537
}
481538
}
482-
}
483539

484-
// collect the last messages
485-
messageBuilder.AppendLine(espTool.StandardOutput.ReadToEnd());
486-
messageBuilder.Append(espTool.StandardError.ReadToEnd());
540+
// collect the last messages
541+
messageBuilder.AppendLine(espTool.StandardOutput.ReadToEnd());
542+
messageBuilder.Append(espTool.StandardError.ReadToEnd());
543+
}
487544
}
488545
else
489546
{
@@ -501,6 +558,50 @@ private bool RunEspTool(
501558
return espTool.ExitCode == 0;
502559
}
503560

561+
private void ProcessConnectPattern(StringBuilder messageBuilder)
562+
{
563+
// try to find a connect pattern
564+
connectPatternFound = FindConnectPattern(messageBuilder);
565+
566+
var timeToConnect = DateTime.UtcNow.Subtract(connectTimeStamp).TotalSeconds;
567+
568+
// if esptool is struggling to connect for more than 5 seconds
569+
570+
// prompt user
571+
if (!connectPromptShown &&
572+
connectPatternFound &&
573+
timeToConnect > 5)
574+
{
575+
Console.ForegroundColor = ConsoleColor.Magenta;
576+
577+
Console.WriteLine("*** Hold down the BOOT/FLASH button in ESP32 board ***");
578+
579+
Console.ForegroundColor = ConsoleColor.White;
580+
581+
// set flag
582+
connectPromptShown = true;
583+
}
584+
}
585+
586+
private bool FindConnectPattern(StringBuilder messageBuilder)
587+
{
588+
if (messageBuilder.Length > 2)
589+
{
590+
var previousChar = messageBuilder[messageBuilder.Length - 2];
591+
var newChar = messageBuilder[messageBuilder.Length - 1];
592+
593+
// don't look for double dot (..) sequence so it doesn't mistake it with an ellipsis (...)
594+
return ((previousChar == '.'
595+
&& newChar == '_') ||
596+
(previousChar == '_'
597+
&& newChar == '_') ||
598+
(previousChar == '_'
599+
&& newChar == '.'));
600+
}
601+
602+
return false;
603+
}
604+
504605
/// <summary>
505606
/// Try to find a progress message in the esptool output
506607
/// </summary>

0 commit comments

Comments
 (0)