diff --git a/README.md b/README.md index b99950c..44e97f3 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,26 @@ additional contributions! For quick support and questions: [![Chat at https://gitter.im/jeelabs/esp-link](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jeelabs/esp-link?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +Esp-link goals +-------------- + +The goal of the esp-link project is to create an advanced Wifi co-processor. Esp-link assumes that +there is a "main processor" (also referred to as "attached uController") and that esp-link's role +is to facilitate communication over Wifi. Where esp-link is a bit unusual is that it's not really +just a Wifi interface or a slave co-processor. In some sense it's the master, because the main +processor can be reset, controlled and reprogrammed through esp-link. The three main areas of +functionality in esp-link are: +- reprogramming and debugging the attached uC +- letting the attached uC make outbound communication and offloading the protocol processing +- forwarding inbound communication and offloading the protocol processing (this part is the +least developed) + +The goal of the project is also to remain focused on the above mission. In particular, esp-link +is not a platform for stand-alone applications and it does not support connecting sensors or +actuators directly to it. A few users have taken esp-link as a starting point for doing these +things and that's great, but there's also value in keeping the mainline esp-link project +focused on a clear mission. + Esp-link uses ------------- The simplest use of esp-link is as a transparent serial to wifi bridge. You can flash an attached @@ -347,6 +367,35 @@ The efficiency is not 100% because there is protocol overhead (such as sync, rec length characters) and there is dead time waiting for an ack or preparing the next record to be sent. +#### Details of built-in AVR flash algorithm + +The built-in flashing algorithm differs a bit from what avrdude does. The programming protocol +states that STK_GET_SYNC+CRC_EOP (0x30 0x20) should be sent to synchronize, but that works poorly +because the AVR's UART only buffers one character. This means that if STK_GET_SYNC+CRC_EOP is +sent twice there is a high chance that only the last character (CRC_EOP) is actually +received. If that is followed by another STK_GET_SYNC+CRC_EOP sequence then optiboot receives +CRC_EOP+STK_GET_SYNC+CRC_EOP which causes it to abort and run the old sketch. Ending up in that +situation is quite likely because optiboot initializes the UART as one of the first things, but +then goes off an flashes an LED for ~300ms during which it doesn't empty the UART. + +Looking at the optiboot code, the good news is that CRC_EOP+CRC_EOP can be used to get an initial +response without the overrun danger of the normal sync sequence and this is what esp-link does. +The programming sequence runs as follows: + +- esp-link sends a brief reset pulse (1ms) +- esp-link sends CRC_EOP+CRC_EOP ~50ms later +- esp-link sends CRC_EOP+CRC_EOP every ~70-80ms +- eventually optiboot responds with STK_INSYNC+STK_OK (0x14;0x10) +- esp-link sends one CRC_EOP to sort out the even/odd issue +- either optiboot responds with STK_INSYNC+STK_OK or nothing happens for 70-80ms, in which case + esp-link sends another CRC_EOP +- esp-link sends STK_GET_SYNC+CRC_EOP and optiboot responds with STK_INSYNC+STK_OK and we're in + sync now +- esp-link sends the next command (starts with 'u') and programming starts... + +If no sync is achieved, esp-link changes baud rate and the whole thing starts over with a reset +pulse about 600ms, esp-link gives up after about 5 seconds and reports an error. + ### Flashing an attached ARM processor You can reprogram NXP's LPC800-series and many other ARM processors as well by pointing your diff --git a/cmd/cmd.c b/cmd/cmd.c index 8f04faf..0d625cd 100644 --- a/cmd/cmd.c +++ b/cmd/cmd.c @@ -27,11 +27,13 @@ extern const CmdList commands[]; static void ICACHE_FLASH_ATTR CMD_ProtoWrite(uint8_t data) { switch(data){ - case SLIP_START: case SLIP_END: - case SLIP_REPL: - uart0_write_char(SLIP_REPL); - uart0_write_char(SLIP_ESC(data)); + uart0_write_char(SLIP_ESC); + uart0_write_char(SLIP_ESC_END); + break; + case SLIP_ESC: + uart0_write_char(SLIP_ESC); + uart0_write_char(SLIP_ESC_ESC); break; default: uart0_write_char(data); @@ -48,7 +50,7 @@ uint16_t ICACHE_FLASH_ATTR CMD_ResponseStart(uint16_t cmd, uint32_t callback, uint32_t _return, uint16_t argc) { uint16_t crc = 0; - uart0_write_char(SLIP_START); + uart0_write_char(SLIP_END); CMD_ProtoWriteBuf((uint8_t*)&cmd, 2); crc = crc16_data((uint8_t*)&cmd, 2, crc); CMD_ProtoWriteBuf((uint8_t*)&callback, 4); @@ -124,17 +126,17 @@ CMD_parse_packet(uint8_t *buf, short len) { CmdPacket *packet = (CmdPacket*)buf; uint8_t *data_ptr = (uint8_t*)&packet->args; uint8_t *data_limit = data_ptr+len; - + DBG("CMD_parse_packet: cmd=%d(%s) argc=%d cb=%p ret=%lu\n", - packet->cmd, - cmd_names[packet->cmd], - packet->argc, - (void *)packet->callback, + packet->cmd, + cmd_names[packet->cmd], + packet->argc, + (void *)packet->callback, packet->_return ); #if 0 - // print out arguments + // print out arguments uint16_t argn = 0; uint16_t argc = packet->argc; while (data_ptr+2 < data_limit && argc--) { diff --git a/cmd/cmd.h b/cmd/cmd.h index ecd8140..06486b5 100644 --- a/cmd/cmd.h +++ b/cmd/cmd.h @@ -6,19 +6,11 @@ #define CMD_H #include -// Escape chars used by tuanpmt, dunno why he didn't use std ones... -#define SLIP_START 0x7E -#define SLIP_END 0x7F -#define SLIP_REPL 0x7D -#define SLIP_ESC(x) (x ^ 0x20) - -#if 0 -// Proper SLIP escape chars from RFC +// Standard SLIP escape chars from RFC #define SLIP_END 0300 // indicates end of packet #define SLIP_ESC 0333 // indicates byte stuffing #define SLIP_ESC_END 0334 // ESC ESC_END means END data byte #define SLIP_ESC_ESC 0335 // ESC ESC_ESC means ESC data byte -#endif typedef struct __attribute__((__packed__)) { uint16_t len; // length of data diff --git a/cmd/handlers.c b/cmd/handlers.c index 4d20e4d..50af21d 100644 --- a/cmd/handlers.c +++ b/cmd/handlers.c @@ -68,7 +68,7 @@ CMD_Null(CmdPacket *cmd) { } // Command handler for Reset command, this was originally to reset the ESP but we don't want to -// do that is esp-link. It is still good to clear any information the ESP has about the attached +// do that in esp-link. It is still good to clear any information the ESP has about the attached // uC. static uint32_t ICACHE_FLASH_ATTR CMD_Reset(CmdPacket *cmd) { diff --git a/esp-link/cgi.c b/esp-link/cgi.c index 6879cd6..713ba31 100644 --- a/esp-link/cgi.c +++ b/esp-link/cgi.c @@ -202,7 +202,7 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) { os_strncpy(name, flashConfig.hostname, 12); name[12] = 0; // construct json response - os_sprintf(buff, + os_sprintf(buff, "{ " "\"menu\": [ " "\"Home\", \"/home.html\", " @@ -217,7 +217,7 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) { " ], " "\"version\": \"%s\", " "\"name\": \"%s\"" - " }", + " }", esp_link_version, name); httpdSend(connData, buff, -1); diff --git a/html/home.html b/html/home.html index 2413566..e225fab 100644 --- a/html/home.html +++ b/html/home.html @@ -22,8 +22,8 @@ Network SSID - WiFI status - WiFI address + WiFi status + WiFi address SLIP status MQTT status Serial baud @@ -32,7 +32,7 @@

Info

The JeeLabs esp-link firmware bridges the ESP8266 - serial port to WiFI and can + serial port to WiFi and can program microcontrollers over the serial port, in particular Arduinos, AVRs, and NXP's LPC800 and other ARM processors. Typical avrdude command line to program an Arduino:

@@ -79,7 +79,7 @@
- +
@@ -109,8 +109,8 @@

System details

- - + +