[PATCH v2 12/15] Firmware upgrade for OSTC3
Anton Lundin
glance at acc.umu.se
Wed Dec 17 14:11:09 PST 2014
This connects the bits and implements firmware upgrade for the OSTC3.
This code is inspired by JeanDo ostc-companion.
Reviewed-by: Jef Driesen <jef at libdivecomputer.org>
Signed-off-by: Anton Lundin <glance at acc.umu.se>
---
include/libdivecomputer/hw_ostc3.h | 3 +
src/hw_ostc3.c | 124 ++++++++++++++++++++++++++++++++++++-
src/libdivecomputer.symbols | 1 +
3 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/include/libdivecomputer/hw_ostc3.h b/include/libdivecomputer/hw_ostc3.h
index 267b7e3..bc56a9d 100644
--- a/include/libdivecomputer/hw_ostc3.h
+++ b/include/libdivecomputer/hw_ostc3.h
@@ -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 */
diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c
index 06e3827..1daa30e 100644
--- a/src/hw_ostc3.c
+++ b/src/hw_ostc3.c
@@ -936,7 +936,7 @@ hw_ostc3_firmware_upgrade (dc_device_t *abstract, unsigned int checksum)
buffer[4] = (buffer[4]<<1 | buffer[4]>>7);
}
- rc = hw_ostc3_transfer(device, NULL, S_UPGRADE, buffer, sizeof(buffer), NULL, 0);
+ rc = hw_ostc3_transfer (device, NULL, S_UPGRADE, buffer, sizeof(buffer), NULL, 0);
if (rc != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to send flash firmware command");
return rc;
@@ -947,3 +947,125 @@ 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(abstract);
+ 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) {
+ free (firmware);
+ ERROR (context, "Failed to erase old firmware");
+ return rc;
+ }
+
+ // Memory erased
+ progress.current++;
+ device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
+
+ hw_ostc3_device_display(abstract, " Uploading...");
+
+ for(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) {
+ free(firmware);
+ ERROR (context, "Failed to write block to device");
+ return rc;
+ }
+ // One block uploaded
+ progress.current++;
+ device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
+ }
+
+ hw_ostc3_device_display (abstract, " Verifying...");
+
+ for(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) {
+ free (firmware);
+ ERROR (context, "Failed to read block.");
+ return rc;
+ }
+ if (memcmp (firmware->data + len, block, sizeof (block)) != 0) {
+ free (firmware);
+ ERROR (context, "Failed verify.");
+ hw_ostc3_device_display (abstract, " Verify FAILED");
+ 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) {
+ free (firmware);
+ ERROR (context, "Failed to start programing");
+ return rc;
+ }
+
+ // Programing done!
+ progress.current++;
+ device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
+
+ // Finished!
+ return DC_STATUS_SUCCESS;
+}
diff --git a/src/libdivecomputer.symbols b/src/libdivecomputer.symbols
index 8dfd7be..8109f96 100644
--- a/src/libdivecomputer.symbols
+++ b/src/libdivecomputer.symbols
@@ -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
--
2.1.0
More information about the devel
mailing list