forked from forkineye/ESPixelStick
-
Notifications
You must be signed in to change notification settings - Fork 5
/
EFUpdate.cpp
119 lines (109 loc) · 3.9 KB
/
EFUpdate.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
* EFUpdate.cpp
*
* Project: ESPixelStick - An ESP8266 and E1.31 based pixel driver
* Copyright (c) 2016 Shelby Merrick
* http://www.forkineye.com
*
* This program is provided free for you to use in any way that you wish,
* subject to the laws and regulations where you are using it. Due diligence
* is strongly suggested before using this code. Please give credit where due.
*
* The Author makes no warranty of any kind, express or implied, with regard
* to this program or the documentation contained in this document. The
* Author shall not be liable in any event for incidental or consequential
* damages in connection with, or arising out of, the furnishing, performance
* or use of these programs.
*
*/
#include <Arduino.h>
#include <FS.h>
#include <lwip/def.h>
#include "EFUpdate.h"
void EFUpdate::begin() {
_maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
_state = State::HEADER;
_loc = 0;
_error = EFUPDATE_ERROR_OK;
}
bool EFUpdate::process(uint8_t *data, size_t len) {
size_t index = 0;
bool retval = true;
while (index < len) {
switch (_state) {
case State::HEADER:
_header.raw[_loc++] = data[index++];
if (_loc == sizeof(efuheader_t)) {
if (_header.signature == EFU_ID) {
_header.version = ntohs(_header.version);
memset(&_record, 0, sizeof(efurecord_t));
_loc = 0;
_state = State::RECORD;
} else {
_state = State::FAIL;
_error = EFUPDATE_ERROR_SIG;
}
}
break;
case State::RECORD:
_record.raw[_loc++] = data[index++];
if (_loc == sizeof(efurecord_t)) {
_record.type = RecordType(ntohs((uint16_t)_record.type));
_record.size = ntohl(_record.size);
_loc = 0;
if (_record.type == RecordType::SKETCH_IMAGE) {
// Begin sketch update
if (!Update.begin(_record.size, U_FLASH)) {
_state = State::FAIL;
_error = Update.getError();
} else {
_state = State::DATA;
}
} else if (_record.type == RecordType::SPIFFS_IMAGE) {
// Begin spiffs update
SPIFFS.end();
if (!Update.begin(_record.size, U_SPIFFS)) {
_state = State::FAIL;
_error = Update.getError();
} else {
_state = State::DATA;
}
} else {
_state = State::FAIL;
_error = EFUPDATE_ERROR_REC;
}
}
break;
case State::DATA:
size_t toWrite;
toWrite = (_record.size - _loc < len) ? _record.size - _loc : len - index;
Update.write(data + index, toWrite);
index = index + toWrite;
_loc = _loc + toWrite;
if (_record.size == _loc) {
Update.end(true);
memset(&_record, 0, sizeof(efurecord_t));
_loc = 0;
_state = State::RECORD;
}
break;
case State::FAIL:
index = len;
retval = false;
break;
}
}
return retval;
}
bool EFUpdate::hasError() {
return _error != EFUPDATE_ERROR_OK;
}
uint8_t EFUpdate::getError() {
return _error;
}
bool EFUpdate::end() {
if (_state == State::FAIL)
return false;
else
return true;
}