Bluetooth flash firmware finished

This commit is contained in:
Bertrand Songis
2019-04-28 16:46:17 +02:00
parent c546d49b04
commit abb2c063db
2 changed files with 178 additions and 35 deletions
+167 -29
View File
@@ -40,6 +40,11 @@ void Bluetooth::write(const uint8_t * data, uint8_t length)
TRACE_NOCRLF("BT>");
for (int i=0; i<length; i++) {
TRACE_NOCRLF(" %02X", data[i]);
if (btTxFifo.isFull()) {
if (!bluetoothIsWriting())
bluetoothWriteWakeup();
RTOS_WAIT_MS(1);
}
btTxFifo.push(data[i]);
}
TRACE_NOCRLF("\r\n");
@@ -354,6 +359,10 @@ void Bluetooth::wakeup()
wakeupTime = now + 5; /* 50ms default */
if (state == BLUETOOTH_STATE_FLASH_FIRMWARE) {
return;
}
if (g_eeGeneral.bluetoothMode == BLUETOOTH_OFF || (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && !IS_BLUETOOTH_TRAINER())) {
if (state != BLUETOOTH_STATE_OFF) {
bluetoothDisable();
@@ -482,10 +491,10 @@ uint8_t Bluetooth::read(uint8_t * data, uint8_t size, uint8_t timeout)
uint8_t elapsed = 0;
uint8_t byte;
while (!btRxFifo.pop(byte)) {
RTOS_WAIT_MS(1);
if (elapsed++ >= timeout) {
return len;
}
RTOS_WAIT_MS(1);
}
data[len++] = byte;
}
@@ -495,10 +504,10 @@ uint8_t Bluetooth::read(uint8_t * data, uint8_t size, uint8_t timeout)
#define BLUETOOTH_ACK 0xCC
#define BLUETOOTH_NACK 0x33
const char * Bluetooth::waitBootloaderCommandResponse()
const char * Bluetooth::bootloaderWaitCommandResponse(uint8_t timeout)
{
uint8_t response[2];
if (read(response, 2) != 2) {
if (read(response, sizeof(response), timeout) != sizeof(response)) {
return "Bluetooth timeout";
}
@@ -513,7 +522,7 @@ const char * Bluetooth::waitBootloaderCommandResponse()
return "Bluetooth error";
}
const char * Bluetooth::waitBootloaderResponseData(uint8_t * data, uint8_t size)
const char * Bluetooth::bootloaderWaitResponseData(uint8_t *data, uint8_t size)
{
uint8_t header[2];
if (read(header, 2) != 2) {
@@ -538,79 +547,206 @@ const char * Bluetooth::waitBootloaderResponseData(uint8_t * data, uint8_t size)
return nullptr;
}
const char * Bluetooth::sendBootloaderAutoBaud()
const char * Bluetooth::bootloaderSetAutoBaud()
{
uint8_t packet[2] = {
0x55, 0x55
0x55,
0x55
};
write(packet, sizeof(packet));
return waitBootloaderCommandResponse();
return bootloaderWaitCommandResponse();
}
void Bluetooth::sendBootloaderCommand(uint8_t command, const uint8_t *data, uint8_t size)
void Bluetooth::bootloaderSendCommand(uint8_t command, const void *data, uint8_t size)
{
uint8_t packet[3] = {
uint8_t(3 + size),
bootloaderChecksum(command, data, size),
command
uint8_t(3 + size),
bootloaderChecksum(command, (uint8_t *) data, size),
command
};
write(packet, sizeof(packet));
if (size > 0) {
write(data, size);
write((uint8_t *)data, size);
}
}
void Bluetooth::sendBootloaderCommandResponse(uint8_t response)
void Bluetooth::bootloaderSendCommandResponse(uint8_t response)
{
uint8_t packet[2] = {
0x00, response
0x00,
response
};
write(packet, sizeof(packet));
}
enum
{
enum {
CMD_DOWNLOAD = 0x21,
CMD_GET_STATUS = 0x23,
CMD_SEND_DATA = 0x24,
CMD_SECTOR_ERASE = 0x26,
CMD_GET_CHIP_ID = 0x28,
};
enum {
CMD_RET_SUCCESS = 0x40,
};
#define CC26XX_FLASH_BASE 0x00001000
#define CC26XX_PAGE_ERASE_SIZE 4096
#define CC26XX_MAX_BYTES_PER_TRANSFER 252
const char * Bluetooth::bootloaderSendData(const uint8_t * data, uint8_t size)
{
bootloaderSendCommand(CMD_SEND_DATA, data, size);
return bootloaderWaitCommandResponse();
}
const char * Bluetooth::bootloaderReadStatus(uint8_t &status)
{
bootloaderSendCommand(CMD_GET_STATUS);
const char * result = bootloaderWaitCommandResponse();
if (result)
return result;
result = bootloaderWaitResponseData(&status, 1);
bootloaderSendCommandResponse(result == nullptr ? BLUETOOTH_ACK : BLUETOOTH_NACK);
return result;
}
const char * Bluetooth::bootloaderCheckStatus()
{
uint8_t status;
const char * result = bootloaderReadStatus(status);
if (result)
return result;
if (status != CMD_RET_SUCCESS)
return "Wrong status";
return nullptr;
}
const char * Bluetooth::bootloaderEraseFlash(uint32_t start, uint32_t size)
{
uint32_t address = start;
uint32_t end = start + size;
while (address < end) {
uint32_t addressBigEndian = __builtin_bswap32(address);
bootloaderSendCommand(CMD_SECTOR_ERASE, &addressBigEndian, sizeof(addressBigEndian));
const char * result = bootloaderWaitCommandResponse();
if (result)
return result;
result = bootloaderCheckStatus();
if (result)
return result;
address += CC26XX_PAGE_ERASE_SIZE;
}
return nullptr;
}
const char * Bluetooth::bootloaderStartWriteFlash(uint32_t start, uint32_t size)
{
uint32_t cmdArgs[2] = {
__builtin_bswap32(start),
__builtin_bswap32(size),
};
bootloaderSendCommand(CMD_DOWNLOAD, cmdArgs, sizeof(cmdArgs));
const char * result = bootloaderWaitCommandResponse();
if (result)
return result;
result = bootloaderCheckStatus();
if (result)
return result;
return result;
}
const char * Bluetooth::bootloaderWriteFlash(const uint8_t * data, uint32_t size)
{
while (size > 0) {
uint32_t len = min<uint32_t>(size, CC26XX_MAX_BYTES_PER_TRANSFER);
const char * result = bootloaderSendData(data, len);
if (result)
return result;
result = bootloaderCheckStatus();
if (result)
return result;
data += len;
size -= len;
}
return nullptr;
}
const char * Bluetooth::doFlashFirmware(const char * filename)
{
const char * result;
FIL file;
uint8_t buffer[CC26XX_MAX_BYTES_PER_TRANSFER * 4];
UINT count;
// Dummy command
sendBootloaderCommand(0);
result = waitBootloaderCommandResponse();
bootloaderSendCommand(0);
result = bootloaderWaitCommandResponse(0);
if (result)
result = sendBootloaderAutoBaud();
result = bootloaderSetAutoBaud();
if (result)
return result;
// Get chip ID
sendBootloaderCommand(CMD_GET_CHIP_ID);
result = waitBootloaderCommandResponse();
bootloaderSendCommand(CMD_GET_CHIP_ID);
result = bootloaderWaitCommandResponse();
if (result)
return result;
uint8_t id[4];
result = waitBootloaderResponseData(id, 4);
sendBootloaderCommandResponse(result == nullptr ? BLUETOOTH_ACK : BLUETOOTH_NACK);
result = bootloaderWaitResponseData(id, 4);
bootloaderSendCommandResponse(result == nullptr ? BLUETOOTH_ACK : BLUETOOTH_NACK);
return result;
if (f_open(&file, filename, FA_READ) != FR_OK) {
return "Error opening file";
}
drawProgressScreen(getBasename(filename), "Flash erase...", 0, 0);
result = bootloaderEraseFlash(CC26XX_FLASH_BASE, f_size(&file));
if (result)
return result;
uint32_t size = f_size(&file);
drawProgressScreen(getBasename(filename), "Flash write...", 0, size);
result = bootloaderStartWriteFlash(CC26XX_FLASH_BASE, size);
if (result)
return result;
uint32_t done = 0;
while (1) {
done += count;
drawProgressScreen(getBasename(filename), "Flash write...", done, size);
if (f_read(&file, buffer, sizeof(buffer), &count) != FR_OK) {
f_close(&file);
return "Error reading file";
}
result = bootloaderWriteFlash(buffer, count);
if (result)
return result;
if (count < sizeof(buffer)) {
f_close(&file);
return nullptr;
}
}
}
void Bluetooth::flashFirmware(const char * filename)
{
drawProgressScreen(getBasename(filename), "Bluetooth reset...", 0, 0);
drawProgressScreen(getBasename(filename), "Module reset...", 0, 0);
state = BLUETOOTH_STATE_FLASH_FIRMWARE;
pausePulses();
bluetoothInit(BLUETOOTH_BOOTLOADER_BAUDRATE, true); // normal mode
RTOS_WAIT_MS(500);
watchdogSuspend(1000);
RTOS_WAIT_MS(1000);
bluetoothInit(BLUETOOTH_BOOTLOADER_BAUDRATE, false); // bootloader mode
watchdogSuspend(1000);
RTOS_WAIT_MS(1000);
const char * result = doFlashFirmware(filename);
@@ -625,6 +761,8 @@ void Bluetooth::flashFirmware(const char * filename)
POPUP_INFORMATION(STR_FIRMWARE_UPDATE_SUCCESS);
}
drawProgressScreen(getBasename(filename), "Module reset...", 0, 0);
/* wait 1s off */
watchdogSuspend(1000);
RTOS_WAIT_MS(1000);
+11 -6
View File
@@ -73,12 +73,17 @@ class Bluetooth
void receiveTrainer();
uint8_t bootloaderChecksum(uint8_t command, const uint8_t * data, uint8_t size);
void sendBootloaderCommand(uint8_t command, const uint8_t * data = nullptr, uint8_t size = 0);
void sendBootloaderCommandResponse(uint8_t response);
const char * waitBootloaderCommandResponse();
const char * waitBootloaderResponseData(uint8_t * data, uint8_t size);
const char * sendBootloaderAutoBaud();
void bootloaderSendCommand(uint8_t command, const void *data = nullptr, uint8_t size = 0);
void bootloaderSendCommandResponse(uint8_t response);
const char * bootloaderWaitCommandResponse(uint8_t timeout=100/*ms*/);
const char * bootloaderWaitResponseData(uint8_t *data, uint8_t size);
const char * bootloaderSetAutoBaud();
const char * bootloaderReadStatus(uint8_t &status);
const char * bootloaderCheckStatus();
const char * bootloaderSendData(const uint8_t * data, uint8_t size);
const char * bootloaderEraseFlash(uint32_t start, uint32_t size);
const char * bootloaderStartWriteFlash(uint32_t start, uint32_t size);
const char * bootloaderWriteFlash(const uint8_t * data, uint32_t size);
const char * doFlashFirmware(const char * filename);
uint8_t buffer[BLUETOOTH_LINE_LENGTH+1];