Christopher Haster / Mbed 2 deprecated ESPQuickFlash

Dependencies:   BufferedSerial mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers esp_command.h Source File

esp_command.h

00001 #ifndef ESP_COMMAND_H
00002 #define ESP_COMMAND_H
00003 
00004 #include "slip.h"
00005 
00006 
00007 #define FLASH_BLOCK_SIZE 0x400
00008 #define RESET_WAIT_MS 250
00009 
00010 enum esp_commands {
00011     ESP_FLASH_START     = 0x02,
00012     ESP_FLASH_DATA      = 0x03,
00013     ESP_FLASH_FINISH    = 0x04,
00014     ESP_RAM_START       = 0x05,
00015     ESP_RAM_DATA        = 0x07,
00016     ESP_RAM_FINISH      = 0x06,
00017     ESP_SYNC_FRAME      = 0x08,
00018     ESP_WRITE_REG       = 0x09,
00019     ESP_READ_REG        = 0x0a,
00020     ESP_SPI_CONFIG      = 0x0b,
00021 };
00022 
00023 
00024 
00025 
00026 // Commands follow the following format
00027 // request:
00028 // [- 0x00 -|- command -|- size -|- value -|-- body --]
00029 //     1          1         2         4        size
00030 //
00031 // response:
00032 // [- 0x01 -|- command -|- size -|- value -|-- body --|- status -|- error -]
00033 //     1          1         2         4     size-error     1          1
00034 //
00035 template <typename SERIAL>
00036 class ESPCommand {
00037 private:
00038     SLIPPacket<SERIAL> _slip;
00039     DigitalOut _reset;
00040     DigitalOut _prog;
00041     
00042 public:
00043     ESPCommand(PinName tx, PinName rx, PinName reset, PinName prog) : 
00044             _slip(tx, rx), _reset(reset, 1), _prog(prog, 1) {}
00045     
00046 private:
00047     bool command_start(char cmd, uint16_t len) {
00048         len -= 4; // First word not included in length
00049         
00050         return _slip.req_start() &&
00051                _slip.putc(0x00) &&
00052                _slip.putc(cmd) &&
00053                _slip.send(&len, 2);
00054     }
00055     
00056     bool command_flush() {
00057         uint16_t len;
00058 
00059         return _slip.resp_start() &&
00060                _slip.getc() == 0x01 &&
00061                _slip.getc() >= 0 &&
00062                _slip.recv(&len, 2) &&
00063                _slip.recv(0, 4+len-2) &&
00064                _slip.getc() == 0x00 &&
00065                _slip.getc() >= 0 &&
00066                _slip.resp_finish();
00067     }
00068     
00069     bool command_finish() {
00070         return _slip.req_finish() && 
00071                command_flush();
00072     }
00073     
00074 public:
00075     bool sync() {
00076 #ifdef LED_STATUS
00077         led_green = 0; // Show progress
00078 #endif
00079         while (true) {
00080             if (sync_frame()) {
00081 #ifdef LED_STATUS
00082                 led_green = 1; // Show progress
00083 #endif
00084                 return true;
00085             }
00086         }
00087     }
00088 
00089     bool sync_frame() {
00090         // Reset board
00091         _reset = 0;
00092         _prog = 1;
00093         wait_ms(250);
00094         _reset = 1;
00095         wait_ms(250);
00096         _reset = 0;
00097         _prog = 0;
00098         wait_ms(250);
00099         _reset = 1;
00100         wait_ms(250);
00101         
00102         // Flush serial line
00103         _slip.flush();
00104         
00105         // Send sync frame
00106         uint32_t x = 0;
00107         
00108         if (!(command_start(ESP_SYNC_FRAME, 2*4 + 32) &&
00109               _slip.send(&x, 4) &&
00110               _slip.putc(0x07) &&
00111               _slip.putc(0x07) &&
00112               _slip.putc(0x12) &&
00113               _slip.putc(0x20)))
00114             return false;
00115             
00116         for (int i = 0; i < 32; i++) {
00117             if (!_slip.putc(0x55))
00118                 return false;
00119         }
00120         
00121         if (!command_finish())
00122             return false;
00123         
00124         for (int i = 0; i < 7; i++) {
00125             if (!command_flush())
00126                 return false;
00127         }
00128         
00129         return true;
00130     }
00131  
00132     bool flash_start(uint32_t blocks, uint32_t block_size, uint32_t address) {
00133         uint32_t x = 0;
00134         uint32_t size = blocks * block_size;
00135         
00136         return command_start(ESP_FLASH_START, 5*4) &&
00137                _slip.send(&x, 4) &&
00138                _slip.send(&size, 4) &&
00139                _slip.send(&blocks, 4) &&
00140                _slip.send(&block_size, 4) &&
00141                _slip.send(&address, 4) && 
00142                command_finish();
00143     }
00144     
00145     bool flash_data(const char *data, uint32_t len, uint32_t n) {
00146         uint32_t zero = 0;
00147         
00148         uint32_t x = 0xef;
00149         for (int i = 0; i < len; i++) {
00150             x ^= data[i];
00151         }
00152         
00153         return command_start(ESP_FLASH_DATA, 5*4 + len) &&
00154                _slip.send(&x, 4) &&
00155                _slip.send(&len, 4) &&
00156                _slip.send(&n, 4) &&
00157                _slip.send(&zero, 4) &&
00158                _slip.send(&zero, 4) &&
00159                _slip.send(data, len) &&
00160                command_finish();
00161     }
00162 
00163     bool flash_finish() {
00164         uint32_t x = 0;
00165         
00166         return command_start(ESP_FLASH_FINISH, 2*4) &&
00167                _slip.send(&x, 4) &&
00168                _slip.send(&x, 4) &&
00169                command_finish();
00170     }
00171     
00172     bool flash_write(uint32_t address, const char *data, uint32_t size) {
00173         uint32_t blocks = (size-1)/FLASH_BLOCK_SIZE + 1;
00174         
00175         printf("Synching...\r\n");
00176         if (!sync())
00177             error("Sync error!");
00178         
00179         printf("Starting transfer 0x%05x - 0x%05x\r\n", address, address + blocks*FLASH_BLOCK_SIZE);
00180         if (!flash_start(blocks, FLASH_BLOCK_SIZE, address))
00181             return false;
00182             
00183         for (int i = 0; i < blocks; i++) {
00184             printf("Flashing address 0x%05x\r\n", address + i*FLASH_BLOCK_SIZE);
00185             if (!flash_data(&data[i*FLASH_BLOCK_SIZE], FLASH_BLOCK_SIZE, i))
00186                 return false;
00187         }
00188         
00189         printf("Finishing transfer\r\n");
00190         if (!flash_finish())
00191             return false;
00192             
00193         wait_ms(250);
00194         return true;
00195     }
00196 };
00197 
00198 #endif