rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
wifi_firmware_updater.cpp
Go to the documentation of this file.
1#include "spi_flash/include/spi_flash.h"
2
3#include "usbcfg.h"
4
5static bool isBigEndian() {
6 uint32_t test = 0x11223344;
7 uint8_t *pTest = reinterpret_cast<uint8_t *>(&test);
8 return pTest[0] == 0x11;
9}
10
11static uint32_t fromNetwork32(uint32_t from) {
12 static const bool be = isBigEndian();
13 if (be) {
14 return from;
15 } else {
16 uint8_t *pFrom = reinterpret_cast<uint8_t *>(&from);
17 uint32_t to;
18 to = pFrom[0]; to <<= 8;
19 to |= pFrom[1]; to <<= 8;
20 to |= pFrom[2]; to <<= 8;
21 to |= pFrom[3];
22 return to;
23 }
24}
25
26static uint16_t fromNetwork16(uint16_t from) {
27 static bool be = isBigEndian();
28 if (be) {
29 return from;
30 } else {
31 uint8_t *pFrom = reinterpret_cast<uint8_t *>(&from);
32 uint16_t to;
33 to = pFrom[0]; to <<= 8;
34 to |= pFrom[1];
35 return to;
36 }
37}
38
39static uint32_t toNetwork32(uint32_t to) {
40 return fromNetwork32(to);
41}
42
43static uint16_t toNetwork16(uint16_t to) {
44 return fromNetwork16(to);
45}
46
47
48typedef struct __attribute__((__packed__)) {
49 uint8_t command;
50 uint32_t address;
51 uint32_t arg1;
52 uint16_t payloadLength;
53
54 // payloadLenght bytes of data follows...
56
57static const int MAX_PAYLOAD_SIZE = 256;
58
59#define CMD_READ_FLASH 0x01
60#define CMD_WRITE_FLASH 0x02
61#define CMD_ERASE_FLASH 0x03
62#define CMD_MAX_PAYLOAD_SIZE 0x50
63#define CMD_HELLO 0x99
64
65static int readch() {
66 uint8_t buf;
67 int ret = chnReadTimeout(&SDU1, &buf, 1, TIME_MS2I(1));
68
69 if (ret == 0) {
70 return -1;
71 } else {
72 return (int)buf;
73 }
74}
75
76static void receivePacket(UartPacket *pkt, uint8_t *payload) {
77 // Read command
78 uint8_t *p = reinterpret_cast<uint8_t *>(pkt);
79 uint16_t l = sizeof(UartPacket);
80 while (l > 0) {
81 int c = readch();
82 if (c == -1)
83 continue;
84 *p++ = c;
85 l--;
86 }
87
88 // Convert parameters from network byte order to cpu byte order
89 pkt->address = fromNetwork32(pkt->address);
90 pkt->arg1 = fromNetwork32(pkt->arg1);
91 pkt->payloadLength = fromNetwork16(pkt->payloadLength);
92
93 // Read payload
94 l = pkt->payloadLength;
95 while (l > 0) {
96 int c = readch();
97 if (c == -1)
98 continue;
99 *payload++ = c;
100 l--;
101 }
102}
103
104// Allocated statically so the compiler can tell us
105// about the amount of used RAM
107static uint8_t payload[MAX_PAYLOAD_SIZE];
108
109static void serialPrint(const uint8_t* data, size_t length) {
110 chnWriteTimeout(&SDU1, data, length, TIME_MS2I(100));
111}
112
113static void serialPrintStr(const char* str) {
114 size_t len = strlen(str);
115 serialPrint(reinterpret_cast<const uint8_t*>(str), len);
116}
117
118struct WifiUpdaterThread : public ThreadController<4096> {
119 WifiUpdaterThread() : ThreadController("WifiPump", NORMALPRIO - 10) {}
120 void ThreadTask() override {
121 if (M2M_SUCCESS != m2m_wifi_download_mode()) {
122 return;
123 }
124
125 auto flashSize = spi_flash_get_size();
126 (void)flashSize;
127
128 //int ret = spi_flash_erase(0, FLASH_SECTOR_SZ);
129 //(void)ret;
130
132
133 while (true) {
134 while (!is_usb_serial_ready()) {
135 chThdSleepMilliseconds(1);
136 }
137
139
140 if (pkt.command == CMD_HELLO) {
141 if (pkt.address == 0x11223344 && pkt.arg1 == 0x55667788) {
142 serialPrintStr("v10000");
143 }
144 }
145
146 if (pkt.command == CMD_MAX_PAYLOAD_SIZE) {
147 uint16_t res = toNetwork16(MAX_PAYLOAD_SIZE);
148 serialPrint(reinterpret_cast<uint8_t *>(&res), sizeof(res));
149 }
150
151 if (pkt.command == CMD_READ_FLASH) {
152 uint32_t address = pkt.address;
153 uint32_t len = pkt.arg1;
154 if (spi_flash_read(payload, address, len) != M2M_SUCCESS) {
155 serialPrintStr("ER");
156 } else {
157 serialPrint(payload, len);
158 serialPrintStr("OK");
159 }
160 }
161
162 if (pkt.command == CMD_WRITE_FLASH) {
163 uint32_t address = pkt.address;
164 uint32_t len = pkt.payloadLength;
165 if (spi_flash_write(payload, address, len) != M2M_SUCCESS) {
166 serialPrintStr("ER");
167 } else {
168 serialPrintStr("OK");
169 }
170 }
171
172 if (pkt.command == CMD_ERASE_FLASH) {
173 uint32_t address = pkt.address;
174 uint32_t len = pkt.arg1;
175 if (spi_flash_erase(address, len) != M2M_SUCCESS) {
176 serialPrintStr("ER");
177 // serialPrintStr("OK");
178 } else {
179 serialPrintStr("OK");
180 }
181 }
182 }
183 }
184};
185
186static WifiUpdaterThread wifiUpdater;
187
189 wifiUpdater.start();
190}
191
typedef __attribute__
Ignition Mode.
A base class for a controller that requires its own thread.
virtual void ThreadTask()=0
BaseChannel SDU1
bool is_usb_serial_ready()
void usb_serial_start(void)
Main function of PDL.
union test_buffers test
Definition test.c:50
static uint16_t flashSize()
Definition mpu_util.cpp:21
static uint16_t toNetwork16(uint16_t to)
static uint8_t payload[MAX_PAYLOAD_SIZE]
static void serialPrint(const uint8_t *data, size_t length)
static uint32_t fromNetwork32(uint32_t from)
static int readch()
static const int MAX_PAYLOAD_SIZE
static bool isBigEndian()
static uint16_t fromNetwork16(uint16_t from)
void startWifiUpdater()
static void receivePacket(UartPacket *pkt, uint8_t *payload)
static UartPacket pkt
static uint32_t toNetwork32(uint32_t to)
static void serialPrintStr(const char *str)
static WifiUpdaterThread wifiUpdater