Autodetect the bootloader protocol variant.
When updating the firmware while the OSTC is running in normal mode, the V2 protocol should be used. However, the OSTC can also be rebooted from the menu or reset using the magnetic switch, and then the V1 protocol should be used. The only difference with the V2 protocol is the slower baudrate (19200 vs 115200). True autodetection of the protocol variant is difficult, because the bootloader will abort the firmware update when not receiving a 0xC1 byte. But we can still take advantage of the fact that the normal firmware does ignore any 0xC1 bytes sent at the wrong baudrate, and probe with the V1 protocol first. If the bootloader is already running, it will respond immediately and we're done. If the normal firmware is still running, it won't respond and the probing with the V1 protocol will fail. If we then switch to the V2 protocol, the firmware update will continue as before. The result is a firmware updater which supports both bootloader protocols without requiring any manual configuration.
This commit is contained in:
parent
14286e8236
commit
bc89e0a3de
@ -793,7 +793,7 @@ hw_ostc_firmware_setup_internal (hw_ostc_device_t *device)
|
||||
|
||||
|
||||
static dc_status_t
|
||||
hw_ostc_firmware_setup (hw_ostc_device_t *device)
|
||||
hw_ostc_firmware_setup (hw_ostc_device_t *device, unsigned int maxretries)
|
||||
{
|
||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||
|
||||
@ -803,7 +803,7 @@ hw_ostc_firmware_setup (hw_ostc_device_t *device)
|
||||
break;
|
||||
|
||||
// Abort if the maximum number of retries is reached.
|
||||
if (nretries++ >= MAXRETRIES)
|
||||
if (nretries++ >= maxretries)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -893,7 +893,21 @@ hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename)
|
||||
serial_set_timeout (device->port, 300);
|
||||
|
||||
// Setup the bootloader.
|
||||
rc = hw_ostc_firmware_setup (device);
|
||||
const unsigned int baudrates[] = {19200, 115200};
|
||||
for (unsigned int i = 0; i < C_ARRAY_SIZE(baudrates); ++i) {
|
||||
// Adjust the baudrate.
|
||||
if (serial_configure (device->port, baudrates[i], 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE) == -1) {
|
||||
ERROR (abstract->context, "Failed to set the terminal attributes.");
|
||||
free (firmware);
|
||||
return DC_STATUS_IO;
|
||||
}
|
||||
|
||||
// Try to setup the bootloader.
|
||||
unsigned int maxretries = (i == 0 ? 1 : MAXRETRIES);
|
||||
rc = hw_ostc_firmware_setup (device, maxretries);
|
||||
if (rc == DC_STATUS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to setup the bootloader.");
|
||||
free (firmware);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user