Firmware upgrade for OSTC3

This connects the bits and implements firmware upgrade for the OSTC3.

This code is inspired by JeanDo ostc-companion.

Reviewed-by: Jef Driesen <jef@libdivecomputer.org>
Signed-off-by: Anton Lundin <glance@acc.umu.se>
This commit is contained in:
Anton Lundin 2014-11-09 20:44:41 +01:00 committed by Jef Driesen
parent 2733a9dc53
commit 02d8c0f04a
3 changed files with 131 additions and 0 deletions

View File

@ -58,6 +58,9 @@ hw_ostc3_device_config_write (dc_device_t *abstract, unsigned int config, const
dc_status_t
hw_ostc3_device_config_reset (dc_device_t *abstract);
dc_status_t
hw_ostc3_device_fwupdate (dc_device_t *abstract, const char *filename);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -33,6 +33,10 @@
#include "array.h"
#include "aes.h"
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
#define ISINSTANCE(device) dc_device_isinstance((device), &hw_ostc3_device_vtable)
#define EXITCODE(rc) \
@ -947,3 +951,126 @@ hw_ostc3_firmware_upgrade (dc_device_t *abstract, unsigned int checksum)
return DC_STATUS_SUCCESS;
}
dc_status_t
hw_ostc3_device_fwupdate (dc_device_t *abstract, const char *filename)
{
dc_status_t rc = DC_STATUS_SUCCESS;
hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
dc_context_t *context = (abstract ? abstract->context : NULL);
// Enable progress notifications.
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
if (!ISINSTANCE (abstract))
return DC_STATUS_INVALIDARGS;
// load, erase, upload FZ, verify FZ, reprogram
progress.maximum = 3 + SZ_FIRMWARE * 2 / SZ_FIRMWARE_BLOCK;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
// Allocate memory for the firmware data.
hw_ostc3_firmware_t *firmware = (hw_ostc3_firmware_t *) malloc (sizeof (hw_ostc3_firmware_t));
if (firmware == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
}
// Read the hex file.
rc = hw_ostc3_firmware_readfile (firmware, context, filename);
if (rc != DC_STATUS_SUCCESS) {
free (firmware);
return rc;
}
// Make sure the device is in service mode
if (device->state == OPEN) {
rc = hw_ostc3_device_init_service (device);
if (rc != DC_STATUS_SUCCESS) {
free (firmware);
return rc;
}
} else if (device->state != SERVICE) {
free (firmware);
return DC_STATUS_INVALIDARGS;
}
// Device open and firmware loaded
progress.current++;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
hw_ostc3_device_display (abstract, " Erasing FW...");
rc = hw_ostc3_firmware_erase (device, FIRMWARE_AREA, SZ_FIRMWARE);
if (rc != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to erase old firmware");
free (firmware);
return rc;
}
// Memory erased
progress.current++;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
hw_ostc3_device_display (abstract, " Uploading...");
for (unsigned int len = 0; len < SZ_FIRMWARE; len += SZ_FIRMWARE_BLOCK) {
char status[16]; // Status message on the display
snprintf (status, 16, " Uploading %2d%%", (100 * len) / SZ_FIRMWARE);
hw_ostc3_device_display (abstract, status);
rc = hw_ostc3_firmware_block_write (device, FIRMWARE_AREA + len, firmware->data + len, SZ_FIRMWARE_BLOCK);
if (rc != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to write block to device");
free(firmware);
return rc;
}
// One block uploaded
progress.current++;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
}
hw_ostc3_device_display (abstract, " Verifying...");
for (unsigned int len = 0; len < SZ_FIRMWARE; len += SZ_FIRMWARE_BLOCK) {
unsigned char block[SZ_FIRMWARE_BLOCK];
char status[16]; // Status message on the display
snprintf (status, 16, " Verifying %2d%%", (100 * len) / SZ_FIRMWARE);
hw_ostc3_device_display (abstract, status);
rc = hw_ostc3_firmware_block_read (device, FIRMWARE_AREA + len, block, sizeof (block));
if (rc != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to read block.");
free (firmware);
return rc;
}
if (memcmp (firmware->data + len, block, sizeof (block)) != 0) {
ERROR (context, "Failed verify.");
hw_ostc3_device_display (abstract, " Verify FAILED");
free (firmware);
return DC_STATUS_PROTOCOL;
}
// One block verified
progress.current++;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
}
hw_ostc3_device_display (abstract, " Programming...");
rc = hw_ostc3_firmware_upgrade (abstract, firmware->checksum);
if (rc != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to start programing");
free (firmware);
return rc;
}
// Programing done!
progress.current++;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
free (firmware);
// Finished!
return DC_STATUS_SUCCESS;
}

View File

@ -160,6 +160,7 @@ hw_ostc3_device_customtext
hw_ostc3_device_config_read
hw_ostc3_device_config_write
hw_ostc3_device_config_reset
hw_ostc3_device_fwupdate
zeagle_n2ition3_device_open
atomics_cobalt_device_open
atomics_cobalt_device_version