[PATCH 03/11] Lift the OSTC3 INIT out of open

Anton Lundin glance at acc.umu.se
Fri Nov 21 12:28:30 PST 2014


This lifts the OSTC3 INIT command out from the open function and does
that separately. This is refactoring to be able to enter service mode so
we can access service mode commands.

Signed-off-by: Anton Lundin <glance at acc.umu.se>
---
 src/hw_ostc3.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 92 insertions(+), 18 deletions(-)

diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c
index de1d865..7fa38f8 100644
--- a/src/hw_ostc3.c
+++ b/src/hw_ostc3.c
@@ -67,6 +67,11 @@ typedef struct hw_ostc3_device_t {
 	dc_device_t base;
 	serial_t *port;
 	unsigned char fingerprint[5];
+	enum hw_ostc3_state {
+		NONE,
+		OPEN,
+		DOWNLOAD,
+	} state;
 } hw_ostc3_device_t;
 
 static dc_status_t hw_ostc3_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
@@ -220,6 +225,7 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name
 	// Set the default values.
 	device->port = NULL;
 	memset (device->fingerprint, 0, sizeof (device->fingerprint));
+	device->state = NONE;
 
 	// Open the device.
 	int rc = serial_open (&device->port, context, name);
@@ -249,18 +255,48 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name
 	// Make sure everything is in a sane state.
 	serial_sleep (device->port, 300);
 	serial_flush (device->port, SERIAL_QUEUE_BOTH);
+	device->state = OPEN;
+
+	*out = (dc_device_t *) device;
+
+	return DC_STATUS_SUCCESS;
+}
+
+
+static dc_status_t
+hw_ostc3_device_init (dc_device_t *abstract)
+{
+	hw_ostc3_device_t *device = (hw_ostc3_device_t*) abstract;
+	dc_context_t *context = (abstract ? abstract->context : NULL);
+
+	if (device->state != OPEN)
+		return DC_STATUS_INVALIDARGS;
 
 	// Send the init command.
 	dc_status_t status = hw_ostc3_transfer (device, NULL, INIT, NULL, 0, NULL, 0);
 	if (status != DC_STATUS_SUCCESS) {
 		ERROR (context, "Failed to send the command.");
-		serial_close (device->port);
-		free (device);
 		return status;
 	}
 
-	*out = (dc_device_t *) device;
+	device->state = DOWNLOAD;
+
+	return DC_STATUS_SUCCESS;
+}
+
 
+static dc_status_t
+hw_ostc3_check_state_or_init(dc_device_t *abstract)
+{
+	hw_ostc3_device_t *device = (hw_ostc3_device_t*) abstract;
+	dc_status_t rc;
+
+	if (device->state == OPEN) {
+		if ((rc = hw_ostc3_device_init(abstract)) != DC_STATUS_SUCCESS)
+			return rc;
+	} else if (device->state != DOWNLOAD) {
+		return DC_STATUS_INVALIDARGS;
+	}
 	return DC_STATUS_SUCCESS;
 }
 
@@ -269,14 +305,20 @@ static dc_status_t
 hw_ostc3_device_close (dc_device_t *abstract)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t*) abstract;
+	dc_status_t status;
 
-	// Send the exit command.
-	dc_status_t status = hw_ostc3_transfer (device, NULL, EXIT, NULL, 0, NULL, 0);
-	if (status != DC_STATUS_SUCCESS) {
-		ERROR (abstract->context, "Failed to send the command.");
-		serial_close (device->port);
-		free (device);
-		return status;
+	if (device->state == NONE)
+		return DC_STATUS_INVALIDARGS;
+
+	// Send the exit command
+	if (device->state != OPEN) {
+		status = hw_ostc3_transfer (device, NULL, EXIT, NULL, 0, NULL, 0);
+		if (status != DC_STATUS_SUCCESS) {
+			ERROR (abstract->context, "Failed to send the command.");
+			serial_close (device->port);
+			free (device);
+			return status;
+		}
 	}
 
 	// Close the device.
@@ -313,6 +355,7 @@ dc_status_t
 hw_ostc3_device_version (dc_device_t *abstract, unsigned char data[], unsigned int size)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
+	dc_status_t rc;
 
 	if (!ISINSTANCE (abstract))
 		return DC_STATUS_INVALIDARGS;
@@ -320,8 +363,11 @@ hw_ostc3_device_version (dc_device_t *abstract, unsigned char data[], unsigned i
 	if (size != SZ_VERSION)
 		return DC_STATUS_INVALIDARGS;
 
+	if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
+		return rc;
+
 	// Send the command.
-	dc_status_t rc = hw_ostc3_transfer (device, NULL, IDENTITY, NULL, 0, data, size);
+	rc = hw_ostc3_transfer (device, NULL, IDENTITY, NULL, 0, data, size);
 	if (rc != DC_STATUS_SUCCESS)
 		return rc;
 
@@ -333,15 +379,19 @@ static dc_status_t
 hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
+	dc_status_t rc;
 
 	// Enable progress notifications.
 	dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
 	progress.maximum = (RB_LOGBOOK_SIZE * RB_LOGBOOK_COUNT) + SZ_MEMORY;
 	device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
 
+	if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
+		return rc;
+
 	// Download the version data.
 	unsigned char id[SZ_VERSION] = {0};
-	dc_status_t rc = hw_ostc3_device_version (abstract, id, sizeof (id));
+	rc = hw_ostc3_device_version (abstract, id, sizeof (id));
 	if (rc != DC_STATUS_SUCCESS) {
 		ERROR (abstract->context, "Failed to read the version.");
 		return rc;
@@ -497,6 +547,7 @@ dc_status_t
 hw_ostc3_device_clock (dc_device_t *abstract, const dc_datetime_t *datetime)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
+	dc_status_t rc;
 
 	if (!ISINSTANCE (abstract))
 		return DC_STATUS_INVALIDARGS;
@@ -506,11 +557,14 @@ hw_ostc3_device_clock (dc_device_t *abstract, const dc_datetime_t *datetime)
 		return DC_STATUS_INVALIDARGS;
 	}
 
+	if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
+		return rc;
+
 	// Send the command.
 	unsigned char packet[6] = {
 		datetime->hour, datetime->minute, datetime->second,
 		datetime->month, datetime->day, datetime->year - 2000};
-	dc_status_t rc = hw_ostc3_transfer (device, NULL, CLOCK, packet, sizeof (packet), NULL, 0);
+	rc = hw_ostc3_transfer (device, NULL, CLOCK, packet, sizeof (packet), NULL, 0);
 	if (rc != DC_STATUS_SUCCESS)
 		return rc;
 
@@ -522,10 +576,14 @@ dc_status_t
 hw_ostc3_device_display (dc_device_t *abstract, const char *text)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
+	dc_status_t rc;
 
 	if (!ISINSTANCE (abstract))
 		return DC_STATUS_INVALIDARGS;
 
+	if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
+		return rc;
+
 	// Pad the data packet with spaces.
 	unsigned char packet[SZ_DISPLAY] = {0};
 	if (hw_ostc3_strncpy (packet, sizeof (packet), text) != 0) {
@@ -534,7 +592,7 @@ hw_ostc3_device_display (dc_device_t *abstract, const char *text)
 	}
 
 	// Send the command.
-	dc_status_t rc = hw_ostc3_transfer (device, NULL, DISPLAY, packet, sizeof (packet), NULL, 0);
+	rc = hw_ostc3_transfer (device, NULL, DISPLAY, packet, sizeof (packet), NULL, 0);
 	if (rc != DC_STATUS_SUCCESS)
 		return rc;
 
@@ -546,10 +604,14 @@ dc_status_t
 hw_ostc3_device_customtext (dc_device_t *abstract, const char *text)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
+	dc_status_t rc;
 
 	if (!ISINSTANCE (abstract))
 		return DC_STATUS_INVALIDARGS;
 
+	if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
+		return rc;
+
 	// Pad the data packet with spaces.
 	unsigned char packet[SZ_CUSTOMTEXT] = {0};
 	if (hw_ostc3_strncpy (packet, sizeof (packet), text) != 0) {
@@ -558,7 +620,7 @@ hw_ostc3_device_customtext (dc_device_t *abstract, const char *text)
 	}
 
 	// Send the command.
-	dc_status_t rc = hw_ostc3_transfer (device, NULL, CUSTOMTEXT, packet, sizeof (packet), NULL, 0);
+	rc = hw_ostc3_transfer (device, NULL, CUSTOMTEXT, packet, sizeof (packet), NULL, 0);
 	if (rc != DC_STATUS_SUCCESS)
 		return rc;
 
@@ -569,6 +631,7 @@ dc_status_t
 hw_ostc3_device_config_read (dc_device_t *abstract, unsigned int config, unsigned char data[], unsigned int size)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
+	dc_status_t rc;
 
 	if (!ISINSTANCE (abstract))
 		return DC_STATUS_INVALIDARGS;
@@ -578,9 +641,12 @@ hw_ostc3_device_config_read (dc_device_t *abstract, unsigned int config, unsigne
 		return DC_STATUS_INVALIDARGS;
 	}
 
+	if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
+		return rc;
+
 	// Send the command.
 	unsigned char command[1] = {config};
-	dc_status_t rc = hw_ostc3_transfer (device, NULL, READ, command, sizeof (command), data, size);
+	rc = hw_ostc3_transfer (device, NULL, READ, command, sizeof (command), data, size);
 	if (rc != DC_STATUS_SUCCESS)
 		return rc;
 
@@ -591,6 +657,7 @@ dc_status_t
 hw_ostc3_device_config_write (dc_device_t *abstract, unsigned int config, const unsigned char data[], unsigned int size)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
+	dc_status_t rc;
 
 	if (!ISINSTANCE (abstract))
 		return DC_STATUS_INVALIDARGS;
@@ -600,10 +667,13 @@ hw_ostc3_device_config_write (dc_device_t *abstract, unsigned int config, const
 		return DC_STATUS_INVALIDARGS;
 	}
 
+	if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
+		return rc;
+
 	// Send the command.
 	unsigned char command[SZ_CONFIG + 1] = {config};
 	memcpy(command + 1, data, size);
-	dc_status_t rc = hw_ostc3_transfer (device, NULL, WRITE, command, size + 1, NULL, 0);
+	rc = hw_ostc3_transfer (device, NULL, WRITE, command, size + 1, NULL, 0);
 	if (rc != DC_STATUS_SUCCESS)
 		return rc;
 
@@ -614,12 +684,16 @@ dc_status_t
 hw_ostc3_device_config_reset (dc_device_t *abstract)
 {
 	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
+	dc_status_t rc;
 
 	if (!ISINSTANCE (abstract))
 		return DC_STATUS_INVALIDARGS;
 
+	if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
+		return rc;
+
 	// Send the command.
-	dc_status_t rc = hw_ostc3_transfer (device, NULL, RESET, NULL, 0, NULL, 0);
+	rc = hw_ostc3_transfer (device, NULL, RESET, NULL, 0, NULL, 0);
 	if (rc != DC_STATUS_SUCCESS)
 		return rc;
 
-- 
1.9.1



More information about the devel mailing list