Skip to main content

How a Single `while(1)` Bricked My ESP32-S3 — and What I Learned Fixing It

    This is a custom ESP32S3 prototyping board i built to troubleshoot the issues.  It Started With a Simple Problem I was testing the EvilCrow Cable Wind — a USB HID device built around the ESP32-S3 that executes keystroke injection payloads over WiFi. Everything seemed fine: the keyboard HID was typing correctly, the web interface loaded, basic commands like RunWin worked. But ServerConnect and ShellWin did absolutely nothing. No error. No feedback. Just silence. Digging Into the Code The first thing I found was this pattern — repeated across four commands: ORIGINAL — DANGEROUS if (!clientServer.connect(serverIP, serverPort)) { while(1); // hangs forever if TCP fails } ⚠ Critical Bug If TCP connection failed for any reason, the device entered an infinite loop with no timeout, no error output, and no recovery path. Ever. But there was more. The bugs were stacking: critical   TCP failures were environmental: listener ...

What is Charlieplexing?

When you use microcontrollers and you are out of PIN's to connect some LED's for status or when you want to drive a binary clock with few pins left in microcontroller, there is a way that can solve this issue.
Its called charlieplexing and if you know multiplexing you will have some idea of how it works. I will do an example using Arduino for demonstration.
Charlieplexing is a method to drive multiple LED's with few pins available in your microcontroller.
Here is the formula to calculate how many LEDs can be drive from N number of pins.

Number of LED's = No. of PINS available ( No. of PINS available - 1)

For example you have only 3 pins left in Arduino and you want to know how many LED's can be drive.

Number of LED's = 3(3-1)
Number of LED's = 3(2)
Number of LED's = 6

So from 3 PINS you can drive 6 LED's.

Since arduino have tri-state output (INPUT, HIGH and LOW) its easy to drive the LED's using this method.
how leds are connected to 3 pins of an arduino


Truth table of how its drive

L = LOW (make out pin as LOW)
H = HIGH (make out pin as HIGH)
I = INPUT (make pin as INPUT) so this pin will be an open circuit

To drive LED 1
You have to make pin 2 and 3 as output pins. Pin 4 as an input.
So when you sent pin 2 = LOW and pin 3 = HIGH and leave pin 4 as an INPUT, the LED 1 will light up.
To drive LED 3
You have to make pin 3 and 4 as output pins. Pin 2 as an input.
So when you sent pin 3 = LOW and pin 4 = HIGH and leave pin 2 as an INPUT, the LED 3 will light up.

Here is an arduino test code that i have written for test charlieplexing.


#define L1 2
#define L2 3
#define L3 4

int delays = 400;      


void setup() {

}

void loop() {
 
  pinMode(L1,OUTPUT);
  pinMode(L2,OUTPUT);
  pinMode(L3,INPUT);
 
  digitalWrite(L1,LOW);
  digitalWrite(L2,HIGH);
  delay(delays);
  digitalWrite(L1,HIGH);
  digitalWrite(L2,LOW);
  delay(delays);
 
  pinMode(L1,INPUT);
  pinMode(L2,OUTPUT);
  pinMode(L3,OUTPUT);
 
  digitalWrite(L2,HIGH);
  digitalWrite(L3,LOW);
  delay(delays);
  digitalWrite(L2,LOW);
  digitalWrite(L3,HIGH);
  delay(delays);
 
  pinMode(L1,OUTPUT);
  pinMode(L2,INPUT);
  pinMode(L3,OUTPUT);
 
  digitalWrite(L1,LOW);
  digitalWrite(L3,HIGH);
  delay(delays);
  digitalWrite(L1,HIGH);
  digitalWrite(L3,LOW);
  delay(delays);

}



hope this will help you.

Comments