Christopher Haster / Mbed 2 deprecated ESPQuickFlash

Dependencies:   BufferedSerial mbed

Committer:
geky
Date:
Mon Apr 18 20:36:49 2016 +0000
Revision:
0:d84cdaf22096
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
geky 0:d84cdaf22096 1 #ifndef ESP_COMMAND_H
geky 0:d84cdaf22096 2 #define ESP_COMMAND_H
geky 0:d84cdaf22096 3
geky 0:d84cdaf22096 4 #include "slip.h"
geky 0:d84cdaf22096 5
geky 0:d84cdaf22096 6
geky 0:d84cdaf22096 7 #define FLASH_BLOCK_SIZE 0x400
geky 0:d84cdaf22096 8 #define RESET_WAIT_MS 250
geky 0:d84cdaf22096 9
geky 0:d84cdaf22096 10 enum esp_commands {
geky 0:d84cdaf22096 11 ESP_FLASH_START = 0x02,
geky 0:d84cdaf22096 12 ESP_FLASH_DATA = 0x03,
geky 0:d84cdaf22096 13 ESP_FLASH_FINISH = 0x04,
geky 0:d84cdaf22096 14 ESP_RAM_START = 0x05,
geky 0:d84cdaf22096 15 ESP_RAM_DATA = 0x07,
geky 0:d84cdaf22096 16 ESP_RAM_FINISH = 0x06,
geky 0:d84cdaf22096 17 ESP_SYNC_FRAME = 0x08,
geky 0:d84cdaf22096 18 ESP_WRITE_REG = 0x09,
geky 0:d84cdaf22096 19 ESP_READ_REG = 0x0a,
geky 0:d84cdaf22096 20 ESP_SPI_CONFIG = 0x0b,
geky 0:d84cdaf22096 21 };
geky 0:d84cdaf22096 22
geky 0:d84cdaf22096 23
geky 0:d84cdaf22096 24
geky 0:d84cdaf22096 25
geky 0:d84cdaf22096 26 // Commands follow the following format
geky 0:d84cdaf22096 27 // request:
geky 0:d84cdaf22096 28 // [- 0x00 -|- command -|- size -|- value -|-- body --]
geky 0:d84cdaf22096 29 // 1 1 2 4 size
geky 0:d84cdaf22096 30 //
geky 0:d84cdaf22096 31 // response:
geky 0:d84cdaf22096 32 // [- 0x01 -|- command -|- size -|- value -|-- body --|- status -|- error -]
geky 0:d84cdaf22096 33 // 1 1 2 4 size-error 1 1
geky 0:d84cdaf22096 34 //
geky 0:d84cdaf22096 35 template <typename SERIAL>
geky 0:d84cdaf22096 36 class ESPCommand {
geky 0:d84cdaf22096 37 private:
geky 0:d84cdaf22096 38 SLIPPacket<SERIAL> _slip;
geky 0:d84cdaf22096 39 DigitalOut _reset;
geky 0:d84cdaf22096 40 DigitalOut _prog;
geky 0:d84cdaf22096 41
geky 0:d84cdaf22096 42 public:
geky 0:d84cdaf22096 43 ESPCommand(PinName tx, PinName rx, PinName reset, PinName prog) :
geky 0:d84cdaf22096 44 _slip(tx, rx), _reset(reset, 1), _prog(prog, 1) {}
geky 0:d84cdaf22096 45
geky 0:d84cdaf22096 46 private:
geky 0:d84cdaf22096 47 bool command_start(char cmd, uint16_t len) {
geky 0:d84cdaf22096 48 len -= 4; // First word not included in length
geky 0:d84cdaf22096 49
geky 0:d84cdaf22096 50 return _slip.req_start() &&
geky 0:d84cdaf22096 51 _slip.putc(0x00) &&
geky 0:d84cdaf22096 52 _slip.putc(cmd) &&
geky 0:d84cdaf22096 53 _slip.send(&len, 2);
geky 0:d84cdaf22096 54 }
geky 0:d84cdaf22096 55
geky 0:d84cdaf22096 56 bool command_flush() {
geky 0:d84cdaf22096 57 uint16_t len;
geky 0:d84cdaf22096 58
geky 0:d84cdaf22096 59 return _slip.resp_start() &&
geky 0:d84cdaf22096 60 _slip.getc() == 0x01 &&
geky 0:d84cdaf22096 61 _slip.getc() >= 0 &&
geky 0:d84cdaf22096 62 _slip.recv(&len, 2) &&
geky 0:d84cdaf22096 63 _slip.recv(0, 4+len-2) &&
geky 0:d84cdaf22096 64 _slip.getc() == 0x00 &&
geky 0:d84cdaf22096 65 _slip.getc() >= 0 &&
geky 0:d84cdaf22096 66 _slip.resp_finish();
geky 0:d84cdaf22096 67 }
geky 0:d84cdaf22096 68
geky 0:d84cdaf22096 69 bool command_finish() {
geky 0:d84cdaf22096 70 return _slip.req_finish() &&
geky 0:d84cdaf22096 71 command_flush();
geky 0:d84cdaf22096 72 }
geky 0:d84cdaf22096 73
geky 0:d84cdaf22096 74 public:
geky 0:d84cdaf22096 75 bool sync() {
geky 0:d84cdaf22096 76 #ifdef LED_STATUS
geky 0:d84cdaf22096 77 led_green = 0; // Show progress
geky 0:d84cdaf22096 78 #endif
geky 0:d84cdaf22096 79 while (true) {
geky 0:d84cdaf22096 80 if (sync_frame()) {
geky 0:d84cdaf22096 81 #ifdef LED_STATUS
geky 0:d84cdaf22096 82 led_green = 1; // Show progress
geky 0:d84cdaf22096 83 #endif
geky 0:d84cdaf22096 84 return true;
geky 0:d84cdaf22096 85 }
geky 0:d84cdaf22096 86 }
geky 0:d84cdaf22096 87 }
geky 0:d84cdaf22096 88
geky 0:d84cdaf22096 89 bool sync_frame() {
geky 0:d84cdaf22096 90 // Reset board
geky 0:d84cdaf22096 91 _reset = 0;
geky 0:d84cdaf22096 92 _prog = 1;
geky 0:d84cdaf22096 93 wait_ms(250);
geky 0:d84cdaf22096 94 _reset = 1;
geky 0:d84cdaf22096 95 wait_ms(250);
geky 0:d84cdaf22096 96 _reset = 0;
geky 0:d84cdaf22096 97 _prog = 0;
geky 0:d84cdaf22096 98 wait_ms(250);
geky 0:d84cdaf22096 99 _reset = 1;
geky 0:d84cdaf22096 100 wait_ms(250);
geky 0:d84cdaf22096 101
geky 0:d84cdaf22096 102 // Flush serial line
geky 0:d84cdaf22096 103 _slip.flush();
geky 0:d84cdaf22096 104
geky 0:d84cdaf22096 105 // Send sync frame
geky 0:d84cdaf22096 106 uint32_t x = 0;
geky 0:d84cdaf22096 107
geky 0:d84cdaf22096 108 if (!(command_start(ESP_SYNC_FRAME, 2*4 + 32) &&
geky 0:d84cdaf22096 109 _slip.send(&x, 4) &&
geky 0:d84cdaf22096 110 _slip.putc(0x07) &&
geky 0:d84cdaf22096 111 _slip.putc(0x07) &&
geky 0:d84cdaf22096 112 _slip.putc(0x12) &&
geky 0:d84cdaf22096 113 _slip.putc(0x20)))
geky 0:d84cdaf22096 114 return false;
geky 0:d84cdaf22096 115
geky 0:d84cdaf22096 116 for (int i = 0; i < 32; i++) {
geky 0:d84cdaf22096 117 if (!_slip.putc(0x55))
geky 0:d84cdaf22096 118 return false;
geky 0:d84cdaf22096 119 }
geky 0:d84cdaf22096 120
geky 0:d84cdaf22096 121 if (!command_finish())
geky 0:d84cdaf22096 122 return false;
geky 0:d84cdaf22096 123
geky 0:d84cdaf22096 124 for (int i = 0; i < 7; i++) {
geky 0:d84cdaf22096 125 if (!command_flush())
geky 0:d84cdaf22096 126 return false;
geky 0:d84cdaf22096 127 }
geky 0:d84cdaf22096 128
geky 0:d84cdaf22096 129 return true;
geky 0:d84cdaf22096 130 }
geky 0:d84cdaf22096 131
geky 0:d84cdaf22096 132 bool flash_start(uint32_t blocks, uint32_t block_size, uint32_t address) {
geky 0:d84cdaf22096 133 uint32_t x = 0;
geky 0:d84cdaf22096 134 uint32_t size = blocks * block_size;
geky 0:d84cdaf22096 135
geky 0:d84cdaf22096 136 return command_start(ESP_FLASH_START, 5*4) &&
geky 0:d84cdaf22096 137 _slip.send(&x, 4) &&
geky 0:d84cdaf22096 138 _slip.send(&size, 4) &&
geky 0:d84cdaf22096 139 _slip.send(&blocks, 4) &&
geky 0:d84cdaf22096 140 _slip.send(&block_size, 4) &&
geky 0:d84cdaf22096 141 _slip.send(&address, 4) &&
geky 0:d84cdaf22096 142 command_finish();
geky 0:d84cdaf22096 143 }
geky 0:d84cdaf22096 144
geky 0:d84cdaf22096 145 bool flash_data(const char *data, uint32_t len, uint32_t n) {
geky 0:d84cdaf22096 146 uint32_t zero = 0;
geky 0:d84cdaf22096 147
geky 0:d84cdaf22096 148 uint32_t x = 0xef;
geky 0:d84cdaf22096 149 for (int i = 0; i < len; i++) {
geky 0:d84cdaf22096 150 x ^= data[i];
geky 0:d84cdaf22096 151 }
geky 0:d84cdaf22096 152
geky 0:d84cdaf22096 153 return command_start(ESP_FLASH_DATA, 5*4 + len) &&
geky 0:d84cdaf22096 154 _slip.send(&x, 4) &&
geky 0:d84cdaf22096 155 _slip.send(&len, 4) &&
geky 0:d84cdaf22096 156 _slip.send(&n, 4) &&
geky 0:d84cdaf22096 157 _slip.send(&zero, 4) &&
geky 0:d84cdaf22096 158 _slip.send(&zero, 4) &&
geky 0:d84cdaf22096 159 _slip.send(data, len) &&
geky 0:d84cdaf22096 160 command_finish();
geky 0:d84cdaf22096 161 }
geky 0:d84cdaf22096 162
geky 0:d84cdaf22096 163 bool flash_finish() {
geky 0:d84cdaf22096 164 uint32_t x = 0;
geky 0:d84cdaf22096 165
geky 0:d84cdaf22096 166 return command_start(ESP_FLASH_FINISH, 2*4) &&
geky 0:d84cdaf22096 167 _slip.send(&x, 4) &&
geky 0:d84cdaf22096 168 _slip.send(&x, 4) &&
geky 0:d84cdaf22096 169 command_finish();
geky 0:d84cdaf22096 170 }
geky 0:d84cdaf22096 171
geky 0:d84cdaf22096 172 bool flash_write(uint32_t address, const char *data, uint32_t size) {
geky 0:d84cdaf22096 173 uint32_t blocks = (size-1)/FLASH_BLOCK_SIZE + 1;
geky 0:d84cdaf22096 174
geky 0:d84cdaf22096 175 printf("Synching...\r\n");
geky 0:d84cdaf22096 176 if (!sync())
geky 0:d84cdaf22096 177 error("Sync error!");
geky 0:d84cdaf22096 178
geky 0:d84cdaf22096 179 printf("Starting transfer 0x%05x - 0x%05x\r\n", address, address + blocks*FLASH_BLOCK_SIZE);
geky 0:d84cdaf22096 180 if (!flash_start(blocks, FLASH_BLOCK_SIZE, address))
geky 0:d84cdaf22096 181 return false;
geky 0:d84cdaf22096 182
geky 0:d84cdaf22096 183 for (int i = 0; i < blocks; i++) {
geky 0:d84cdaf22096 184 printf("Flashing address 0x%05x\r\n", address + i*FLASH_BLOCK_SIZE);
geky 0:d84cdaf22096 185 if (!flash_data(&data[i*FLASH_BLOCK_SIZE], FLASH_BLOCK_SIZE, i))
geky 0:d84cdaf22096 186 return false;
geky 0:d84cdaf22096 187 }
geky 0:d84cdaf22096 188
geky 0:d84cdaf22096 189 printf("Finishing transfer\r\n");
geky 0:d84cdaf22096 190 if (!flash_finish())
geky 0:d84cdaf22096 191 return false;
geky 0:d84cdaf22096 192
geky 0:d84cdaf22096 193 wait_ms(250);
geky 0:d84cdaf22096 194 return true;
geky 0:d84cdaf22096 195 }
geky 0:d84cdaf22096 196 };
geky 0:d84cdaf22096 197
geky 0:d84cdaf22096 198 #endif