Created
January 27, 2022 17:08
-
-
Save MMI/978fbc41de95c0c7106449ad457696cd to your computer and use it in GitHub Desktop.
Mac only C code to reboot an ESP32 device into bootloader mode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This code works on my Mac, developed in conjuntion with a logic analyzer. | |
*/ | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <termios.h> | |
#include <stdio.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <time.h> | |
static char *prog; | |
void usage(void) | |
{ | |
fprintf(stderr, "Usage: %s <device>\n", prog); | |
exit(1); | |
} | |
int main(int ac, char **av) | |
{ | |
prog = av[0]; | |
if (ac < 2) { | |
fprintf(stderr, "%s: requires device path argument\n", prog); | |
usage(); | |
} | |
int fd = open(av[1], O_RDWR | O_NOCTTY | O_NDELAY); | |
if (fd < 0) { | |
fprintf(stderr, "%s: failed to open %s because: %s\n", prog, av[1], strerror(errno)); | |
usage(); | |
} | |
struct termios options; | |
fcntl(fd, F_SETFL, 0); | |
tcgetattr(fd, &options); | |
cfsetispeed(&options, B115200); | |
cfsetospeed(&options, B115200); | |
printf("Configuring port now\n"); | |
options.c_cflag |= (CLOCAL | CREAD | CRTSCTS); | |
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); | |
options.c_oflag &= ~OPOST; | |
options.c_cc[VMIN] = 0; | |
options.c_cc[VTIME] = 10; | |
tcsetattr(fd, TCSANOW, &options); | |
int status; | |
if (ioctl(fd, TIOCMGET, &status)) { | |
fprintf(stderr, "%s: TIOCMGET failed because %s\n", prog, strerror(errno)); | |
usage(); | |
} | |
printf("got status: %x\n", status); | |
printf("status & TIOCM_DTR: %d\n", status & TIOCM_DTR); | |
printf("status & TIOCM_DSR: %d\n", status & TIOCM_DSR); | |
printf("status & TIOCM_RTS: %d\n", status & TIOCM_RTS); | |
printf("status & TIOCM_CTS: %d\n", status & TIOCM_CTS); | |
sleep(1); | |
// Step | DTR | RTS | |
// 1 | 1 | 1 | |
// 2 | 0 | 0 | |
// 3 | 1 | 0 | |
// 4 | 0 | 1 | |
// Logic analyzer shows that set bits in the ioctl | |
// are actually digital low -- thus the XORing | |
// These same steps without the XORing will do a regular | |
// reboot | |
status = 6; // step 1: DTR & RTS high | |
status ^= 6; | |
ioctl(fd, TIOCMSET, &status); | |
status = 0; // step 2: DTR & RTS low | |
status ^= 6; | |
ioctl(fd, TIOCMSET, &status); | |
status = 2; // step 3: DTR high, RTS low | |
status ^= 6; | |
ioctl(fd, TIOCMSET, &status); | |
status = 4; // step 4: DTR low, RTS high | |
status ^= 6; | |
ioctl(fd, TIOCMSET, &status); | |
usleep(50000); | |
status = 6; // normal state: DTR & RTS high | |
status ^= 6; | |
ioctl(fd, TIOCMSET, &status); | |
printf("The device should be in bootloader mode\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment