Skip to content

Commit dfe17ac

Browse files
committed
Dynamic QML-script write support
1 parent 7a0e560 commit dfe17ac

6 files changed

+194
-49
lines changed

CHANGELOG

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* Limit hall sensor angle rate of change based on ERPM.
2424
* Added p_pid_gain_dec_angle parameter.
2525
* Low pass filter input voltage.
26+
* Dual hardware CAN-scan fix.
27+
* Dynamic QML-script write support.
2628

2729
=== FW 5.02 ===
2830
* IMU calibration improvement.

commands.c

+55-7
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ void commands_process_packet(unsigned char *data, unsigned int len,
196196
switch (packet_id) {
197197
case COMM_FW_VERSION: {
198198
int32_t ind = 0;
199-
uint8_t send_buffer[50];
199+
uint8_t send_buffer[60];
200200
send_buffer[ind++] = COMM_FW_VERSION;
201201
send_buffer[ind++] = FW_VERSION_MAJOR;
202202
send_buffer[ind++] = FW_VERSION_MINOR;
@@ -243,7 +243,11 @@ void commands_process_packet(unsigned char *data, unsigned int len,
243243
send_buffer[ind++] = 1;
244244
#endif
245245
#else
246-
send_buffer[ind++] = 0;
246+
if (flash_helper_qmlui_data()) {
247+
send_buffer[ind++] = flash_helper_qmlui_flags();
248+
} else {
249+
send_buffer[ind++] = 0;
250+
}
247251
#endif
248252

249253
fw_version_sent_cnt++;
@@ -1321,27 +1325,71 @@ void commands_process_packet(unsigned char *data, unsigned int len,
13211325
} break;
13221326

13231327
case COMM_GET_QML_UI_APP: {
1324-
#ifdef QMLUI_SOURCE_APP
13251328
int32_t ind = 0;
13261329

13271330
int32_t len_qml = buffer_get_int32(data, &ind);
13281331
int32_t ofs_qml = buffer_get_int32(data, &ind);
13291332

1330-
if ((len_qml + ofs_qml) > DATA_QML_APP_SIZE || len_qml > (PACKET_MAX_PL_LEN - 10)) {
1333+
uint8_t *qmlui_data = flash_helper_qmlui_data();
1334+
int32_t qmlui_len = flash_helper_qmlui_size();
1335+
1336+
#ifdef QMLUI_SOURCE_APP
1337+
qmlui_data = data_qml_app;
1338+
qmlui_len = DATA_QML_APP_SIZE;
1339+
#endif
1340+
1341+
if (!qmlui_data) {
1342+
break;
1343+
}
1344+
1345+
if ((len_qml + ofs_qml) > qmlui_len || len_qml > (PACKET_MAX_PL_LEN - 10)) {
13311346
break;
13321347
}
13331348

13341349
chMtxLock(&send_buffer_mutex);
13351350
ind = 0;
13361351
send_buffer_global[ind++] = packet_id;
1337-
buffer_append_int32(send_buffer_global, DATA_QML_APP_SIZE, &ind);
1352+
buffer_append_int32(send_buffer_global, qmlui_len, &ind);
13381353
buffer_append_int32(send_buffer_global, ofs_qml, &ind);
1339-
memcpy(send_buffer_global + ind, data_qml_app + ofs_qml, len_qml);
1354+
memcpy(send_buffer_global + ind, qmlui_data + ofs_qml, len_qml);
13401355
ind += len_qml;
13411356
reply_func(send_buffer_global, ind);
13421357

13431358
chMtxUnlock(&send_buffer_mutex);
1344-
#endif
1359+
} break;
1360+
1361+
case COMM_QMLUI_ERASE: {
1362+
int32_t ind = 0;
1363+
1364+
if (nrf_driver_ext_nrf_running()) {
1365+
nrf_driver_pause(6000);
1366+
}
1367+
uint16_t flash_res = flash_helper_erase_qmlui();
1368+
1369+
ind = 0;
1370+
uint8_t send_buffer[50];
1371+
send_buffer[ind++] = COMM_QMLUI_ERASE;
1372+
send_buffer[ind++] = flash_res == FLASH_COMPLETE ? 1 : 0;
1373+
reply_func(send_buffer, ind);
1374+
} break;
1375+
1376+
case COMM_QMLUI_WRITE: {
1377+
int32_t ind = 0;
1378+
uint32_t qmlui_offset = buffer_get_uint32(data, &ind);
1379+
1380+
if (nrf_driver_ext_nrf_running()) {
1381+
nrf_driver_pause(2000);
1382+
}
1383+
uint16_t flash_res = flash_helper_write_qmlui(qmlui_offset, data + ind, len - ind);
1384+
1385+
SHUTDOWN_RESET();
1386+
1387+
ind = 0;
1388+
uint8_t send_buffer[50];
1389+
send_buffer[ind++] = COMM_QMLUI_WRITE;
1390+
send_buffer[ind++] = flash_res == FLASH_COMPLETE ? 1 : 0;
1391+
buffer_append_uint32(send_buffer, qmlui_offset, &ind);
1392+
reply_func(send_buffer, ind);
13451393
} break;
13461394

13471395
// Blocking commands. Only one of them runs at any given time, in their

conf_general.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#define FW_VERSION_MAJOR 5
2525
#define FW_VERSION_MINOR 03
2626
// Set to 0 for building a release and iterate during beta test builds
27-
#define FW_TEST_VERSION_NUMBER 28
27+
#define FW_TEST_VERSION_NUMBER 30
2828

2929
#include "datatypes.h"
3030

datatypes.h

+2
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,8 @@ typedef enum {
972972
COMM_GET_QML_UI_HW,
973973
COMM_GET_QML_UI_APP,
974974
COMM_CUSTOM_HW_DATA,
975+
COMM_QMLUI_ERASE,
976+
COMM_QMLUI_WRITE,
975977
} COMM_PACKET_ID;
976978

977979
// CAN commands

flash_helper.c

+126-40
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2016 - 2019 Benjamin Vedder [email protected]
2+
Copyright 2016 - 2021 Benjamin Vedder [email protected]
33
44
This file is part of the VESC firmware.
55
@@ -26,6 +26,7 @@
2626
#include "timeout.h"
2727
#include "hw.h"
2828
#include "crc.h"
29+
#include "buffer.h"
2930
#include <string.h>
3031

3132
/*
@@ -36,7 +37,9 @@
3637
#define APP_BASE 0
3738
#define NEW_APP_BASE 8
3839
#define NEW_APP_SECTORS 3
39-
#define APP_MAX_SIZE (393216 - 8) // Note that the bootloader needs 8 extra bytes
40+
#define APP_MAX_SIZE (1024 * 128 * 3 - 8) // Note that the bootloader needs 8 extra bytes
41+
#define QMLUI_BASE 7
42+
#define QMLUI_MAX_SIZE (1024 * 128 - 8)
4043

4144
// Base address of the Flash sectors
4245
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) // Base @ of Sector 0, 16 Kbytes
@@ -66,11 +69,20 @@
6669
typedef struct {
6770
uint32_t crc_flag;
6871
uint32_t crc;
69-
}crc_info_t;
72+
} crc_info_t;
7073

71-
//Make sure the app image has the CRC bits set to '1' to later write the flag and CRC.
74+
// Make sure the app image has the CRC bits set to '1' to later write the flag and CRC.
7275
const crc_info_t __attribute__((section (".crcinfo"))) crc_info = {0xFFFFFFFF, 0xFFFFFFFF};
7376

77+
// Private functions
78+
static uint16_t erase_sector(uint32_t sector);
79+
static uint16_t write_data(uint32_t base, uint8_t *data, uint32_t len);
80+
static void qmlui_check(void);
81+
82+
// Private variables
83+
static bool qmlui_check_done = false;
84+
static bool qmlui_ok = false;
85+
7486
// Private constants
7587
static const uint32_t flash_addr[FLASH_SECTORS] = {
7688
ADDR_FLASH_SECTOR_0,
@@ -135,52 +147,57 @@ uint16_t flash_helper_erase_new_app(uint32_t new_app_size) {
135147
}
136148

137149
uint16_t flash_helper_erase_bootloader(void) {
138-
FLASH_Unlock();
139-
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
140-
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
141-
142-
mc_interface_unlock();
143-
mc_interface_release_motor();
144-
utils_sys_lock_cnt();
145-
timeout_configure_IWDT_slowest();
146-
147-
uint16_t res = FLASH_EraseSector(flash_sector[BOOTLOADER_BASE], VoltageRange_3);
148-
if (res != FLASH_COMPLETE) {
149-
FLASH_Lock();
150-
return res;
151-
}
150+
return erase_sector(flash_sector[BOOTLOADER_BASE]);
151+
}
152152

153-
FLASH_Lock();
154-
timeout_configure_IWDT();
155-
utils_sys_unlock_cnt();
153+
uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_t len) {
154+
return write_data(flash_addr[NEW_APP_BASE] + offset, data, len);
155+
}
156156

157-
return FLASH_COMPLETE;
157+
uint16_t flash_helper_erase_qmlui(void) {
158+
qmlui_check_done = false;
159+
qmlui_ok = false;
160+
return erase_sector(flash_sector[QMLUI_BASE]);
158161
}
159162

160-
uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_t len) {
161-
FLASH_Unlock();
162-
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
163-
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
163+
uint16_t flash_helper_write_qmlui(uint32_t offset, uint8_t *data, uint32_t len) {
164+
qmlui_check_done = false;
165+
qmlui_ok = false;
166+
return write_data(flash_addr[QMLUI_BASE] + offset, data, len);
167+
}
164168

165-
mc_interface_unlock();
166-
mc_interface_release_motor();
167-
utils_sys_lock_cnt();
168-
timeout_configure_IWDT_slowest();
169+
uint8_t *flash_helper_qmlui_data(void) {
170+
qmlui_check();
169171

170-
for (uint32_t i = 0;i < len;i++) {
171-
uint16_t res = FLASH_ProgramByte(flash_addr[NEW_APP_BASE] + offset + i, data[i]);
172-
if (res != FLASH_COMPLETE) {
173-
FLASH_Lock();
174-
return res;
175-
}
172+
if (qmlui_check_done && qmlui_ok) {
173+
return (uint8_t*)(flash_addr[QMLUI_BASE]) + 8;
174+
} else {
175+
return 0;
176176
}
177-
FLASH_Lock();
177+
}
178178

179-
timeout_configure_IWDT();
179+
uint32_t flash_helper_qmlui_size(void) {
180+
qmlui_check();
180181

181-
utils_sys_unlock_cnt();
182+
if (qmlui_check_done && qmlui_ok) {
183+
uint8_t *qmlui_base = (uint8_t*)(flash_addr[QMLUI_BASE]);
184+
int32_t ind = 0;
185+
return buffer_get_uint32(qmlui_base, &ind);
186+
} else {
187+
return 0;
188+
}
189+
}
182190

183-
return FLASH_COMPLETE;
191+
uint16_t flash_helper_qmlui_flags(void) {
192+
qmlui_check();
193+
194+
if (qmlui_check_done && qmlui_ok) {
195+
uint8_t *qmlui_base = (uint8_t*)(flash_addr[QMLUI_BASE]);
196+
int32_t ind = 6;
197+
return buffer_get_uint16(qmlui_base, &ind);
198+
} else {
199+
return 0;
200+
}
184201
}
185202

186203
/**
@@ -339,3 +356,72 @@ uint32_t flash_helper_verify_flash_memory_chunk(void) {
339356

340357
return res;
341358
}
359+
360+
static uint16_t erase_sector(uint32_t sector) {
361+
FLASH_Unlock();
362+
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
363+
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
364+
365+
mc_interface_unlock();
366+
mc_interface_release_motor();
367+
utils_sys_lock_cnt();
368+
timeout_configure_IWDT_slowest();
369+
370+
uint16_t res = FLASH_EraseSector(sector, VoltageRange_3);
371+
if (res != FLASH_COMPLETE) {
372+
FLASH_Lock();
373+
return res;
374+
}
375+
376+
FLASH_Lock();
377+
timeout_configure_IWDT();
378+
utils_sys_unlock_cnt();
379+
380+
return FLASH_COMPLETE;
381+
}
382+
383+
static uint16_t write_data(uint32_t base, uint8_t *data, uint32_t len) {
384+
FLASH_Unlock();
385+
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
386+
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
387+
388+
mc_interface_unlock();
389+
mc_interface_release_motor();
390+
utils_sys_lock_cnt();
391+
timeout_configure_IWDT_slowest();
392+
393+
for (uint32_t i = 0;i < len;i++) {
394+
uint16_t res = FLASH_ProgramByte(base + i, data[i]);
395+
if (res != FLASH_COMPLETE) {
396+
FLASH_Lock();
397+
return res;
398+
}
399+
}
400+
FLASH_Lock();
401+
402+
timeout_configure_IWDT();
403+
404+
utils_sys_unlock_cnt();
405+
406+
return FLASH_COMPLETE;
407+
}
408+
409+
static void qmlui_check(void) {
410+
if (qmlui_check_done) {
411+
return;
412+
}
413+
414+
uint8_t *qmlui_base = (uint8_t*)(flash_addr[QMLUI_BASE]);
415+
int32_t ind = 0;
416+
uint32_t qmlui_len = buffer_get_uint32(qmlui_base, &ind);
417+
uint16_t qmlui_crc = buffer_get_uint16(qmlui_base, &ind);
418+
419+
if (qmlui_len <= QMLUI_MAX_SIZE) {
420+
uint16_t crc_calc = crc16(qmlui_base + ind, qmlui_len + 2); // CRC includes the 2 byte flags
421+
qmlui_ok = crc_calc == qmlui_crc;
422+
} else {
423+
qmlui_ok = false;
424+
}
425+
426+
qmlui_check_done = true;
427+
}

flash_helper.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2016 - 2019 Benjamin Vedder [email protected]
2+
Copyright 2016 - 2021 Benjamin Vedder [email protected]
33
44
This file is part of the VESC firmware.
55
@@ -26,6 +26,13 @@
2626
uint16_t flash_helper_erase_new_app(uint32_t new_app_size);
2727
uint16_t flash_helper_erase_bootloader(void);
2828
uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_t len);
29+
30+
uint16_t flash_helper_erase_qmlui(void);
31+
uint16_t flash_helper_write_qmlui(uint32_t offset, uint8_t *data, uint32_t len);
32+
uint8_t *flash_helper_qmlui_data(void);
33+
uint32_t flash_helper_qmlui_size(void);
34+
uint16_t flash_helper_qmlui_flags(void);
35+
2936
void flash_helper_jump_to_bootloader(void);
3037
uint8_t* flash_helper_get_sector_address(uint32_t fsector);
3138
uint32_t flash_helper_verify_flash_memory(void);

0 commit comments

Comments
 (0)