From 4284c036c0420727cccac9deffbbc56357cb04d4 Mon Sep 17 00:00:00 2001
From: uvos <devnull@uvos.xyz>
Date: Thu, 24 Aug 2023 01:38:25 +0200
Subject: [PATCH] implemen more commands

---
 coincellhell.c | 64 ++++++++++++++++++++++++++++++++++-------
 coincellhell.h | 42 ++++++++++++++++++++-------
 main.c         | 78 ++++++++++++++++++++++++++++++++++++++------------
 usbcommands.h  | 13 +++++----
 4 files changed, 151 insertions(+), 46 deletions(-)

diff --git a/coincellhell.c b/coincellhell.c
index bec0af7..c59eb0b 100644
--- a/coincellhell.c
+++ b/coincellhell.c
@@ -73,10 +73,10 @@ int coincellhell_get_temperature(struct coincellhell* hell, uint8_t heater, temp
 	int16_t temperatureRaw = 0;
 	uint8_t *dataPtr = (uint8_t*)&temperatureRaw;
 	int ret;
-	while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_GET_TEMPERATURE, location, heater, dataPtr, 2)) == USBSHM_ERROR_AGAIN)
+	while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_HEATER_GET_TEMPERATURE, location, heater, dataPtr, 2)) == USBSHM_ERROR_AGAIN)
 		usleep(1000000);
 	*temperature = temperatureRaw/10.0f;
-	return ret;
+	return ret == 2 ? 0 : -1;
 }
 
 int coincellhell_set_temperature(struct coincellhell* hell, uint8_t heater, float temperature)
@@ -84,9 +84,9 @@ int coincellhell_set_temperature(struct coincellhell* hell, uint8_t heater, floa
 	if(temperature*10.0f > INT16_MAX || temperature*10.0f < INT16_MIN)
 		return -6;
 	int ret;
-	while((ret = usbshm_writeControlTransfer(hell->priv, COMMAND_SET_TEMPERATURE, NULL, 0, temperature*10.0f, heater)) == USBSHM_ERROR_AGAIN)
+	while((ret = usbshm_writeControlTransfer(hell->priv, COMMAND_HEATER_SET_TEMPERATURE, NULL, 0, temperature*10.0f, heater)) == USBSHM_ERROR_AGAIN)
 		usleep(100000);
-	return ret;
+	return ret < 0 ? 0 : -1;
 }
 
 int coincellhell_get_temperature_setpoint(struct coincellhell* hell, uint8_t heater, float* temperature)
@@ -94,9 +94,56 @@ int coincellhell_get_temperature_setpoint(struct coincellhell* hell, uint8_t hea
 	int16_t temperatureRaw = 0;
 	uint8_t *dataPtr = (uint8_t*)&temperatureRaw;
 	int ret;
-	while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_GET_TEMPERATURE_SETPOINT, 0, heater, dataPtr, 2)) == USBSHM_ERROR_AGAIN)
+	while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_HEATER_GET_TEMPERATURE_SETPOINT, 0, heater, dataPtr, 2)) == USBSHM_ERROR_AGAIN)
 		usleep(100000);
 	*temperature = temperatureRaw/10.0f;
+	return ret == 2 ? 0 : -1;
+}
+
+
+int coincellhell_get_state(struct coincellhell* hell, uint8_t heater, struct heater_state* state)
+{
+	uint8_t buf[8];
+	int ret;
+	while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_HEATER_GET_STATE, 0, heater, buf, 8)) == USBSHM_ERROR_AGAIN)
+		usleep(100000);
+
+	if(ret != 8)
+		return -1;
+
+	int16_t* setpoint   = (int16_t*)(buf+1);
+	int16_t* rampTarget = (int16_t*)(buf+3);
+
+	state->enabled = buf[0] & (1 << 0);
+	state->ready = buf[0] & (1 << 2);
+	state->ramp = buf[0] & (1 << 3);
+
+	state->setpoint = *setpoint/10.0f;
+	state->rampTarget = *rampTarget/10.0f;
+	state->dacCommand = buf[5];
+
+	while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_HEATER_GET_STATE, 1, heater, buf, 8)) == USBSHM_ERROR_AGAIN)
+		usleep(100000);
+
+	if(ret != 8)
+		return -1;
+
+	time_t currentTime = time(NULL);
+	uint32_t microTime = coincellhell_get_seconds(hell);
+	uint32_t* startTime = (uint32_t*)buf;
+	uint32_t* endTime = (uint32_t*)(buf+4);
+
+	state->rampStartTime = currentTime + ((int64_t)*startTime - microTime);
+	state->rampStopTime = currentTime + ((int64_t)*endTime - microTime);
+
+	return 0;
+}
+
+int coincellhell_set_enabled(struct coincellhell* hell, uint8_t heater, bool enabled)
+{
+	int ret;
+	while((ret = usbshm_writeControlTransfer(hell->priv, COMMAND_HEATER_SET_ENABLED, NULL, 0, enabled, heater)) == USBSHM_ERROR_AGAIN)
+		usleep(100000);
 	return ret;
 }
 
@@ -106,7 +153,7 @@ int coincellhell_check_ready(struct coincellhell* hell, bool* ready)
 	int ret;
 	while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_READY, 0, 0, (uint8_t*)ready, 1)) == USBSHM_ERROR_AGAIN)
 		usleep(100000);
-	return ret;
+	return ret == 1 ? 0 : -1;
 }
 
 int coincellhell_set_temperature_ramp(struct coincellhell* hell, uint8_t heater, time_t end_time, float temperature)
@@ -119,11 +166,6 @@ int coincellhell_cancle_ramp(struct coincellhell* hell, uint8_t heater)
 	return -1;
 }
 
-int coincellhell_get_ramping(struct coincellhell* hell, uint8_t heater, bool* ramping)
-{
-	return -1;
-}
-
 int coincellhell_set_led(struct coincellhell* hell, bool on)
 {
 	int ret;
diff --git a/coincellhell.h b/coincellhell.h
index da3e85a..b0a490a 100644
--- a/coincellhell.h
+++ b/coincellhell.h
@@ -44,10 +44,24 @@ Api to controll EISmultiplexer devices.
 extern "C" {
 #endif
 
-struct coincellhell {
+struct coincellhell
+{
 	struct usbshm* priv;
 };
 
+struct heater_state
+{
+	bool enabled;
+	bool ready;
+	bool ramp;
+	uint8_t dacCommand;
+	float setpoint;
+
+	float rampTarget;
+	time_t rampStartTime;
+	time_t rampStopTime;
+};
+
 /**
  * @brief Attempts to connect to a EISmultiplexer device and initalizes a coincellhell struct
  * @param hell pointer to a coincellhell struct to initalize
@@ -82,7 +96,23 @@ int coincellhell_set_temperature(struct coincellhell* hell, uint8_t heater, floa
 int coincellhell_get_temperature_setpoint(struct coincellhell* hell, uint8_t heater, float* temperature);
 
 /**
- * @brief Checks if all temperatures are close to thair setpoins and all ramps have compleated
+ * @brief Gets the state struct for the given heater
+ * @param heater heater for which to set the temperature
+ * @param state A struct where the state will be stored
+ * @return 0 on sucess and < 0 on failure
+ */
+int coincellhell_get_state(struct coincellhell* hell, uint8_t heater, struct heater_state* state);
+
+/**
+ * @brief Sets the enabled state for a give heater
+ * @param heater heater for which to set the temperature
+ * @param state A struct where the state will be stored
+ * @return 0 on sucess and < 0 on failure
+ */
+int coincellhell_set_enabled(struct coincellhell* hell, uint8_t heater, bool enabled);
+
+/**
+ * @brief Checks if all temperatures are close to thair setpoins
  * @param ready a pointer to a bool where the result will be stored, true if all temperatures have been reatch, false otherwise
  * @return 0 on sucess and < 0 on failure
  */
@@ -103,14 +133,6 @@ int coincellhell_set_temperature_ramp(struct coincellhell* hell, uint8_t heater,
  */
 int coincellhell_cancle_ramp(struct coincellhell* hell, uint8_t heater);
 
-/**
- * @brief Checks wather the the given heater is currenly executeing a ramp
- * @param ramping a pointer to a bool where the ramping state will be stored
- * @param heater heater for which to cancle the ramp
- * @return 0 on sucess and < 0 on failure
- */
-int coincellhell_get_ramping(struct coincellhell* hell, uint8_t heater, bool* ramping);
-
 /**
  * @brief Turns the led on the pcb on or off
  * @param hell pointer to a coincellhell struct
diff --git a/main.c b/main.c
index 2a77a90..09c8650 100644
--- a/main.c
+++ b/main.c
@@ -39,10 +39,13 @@
 static void print_commands(void)
 {
 	puts("Valid commands:");
-	puts("set [HEATER] [TEMPERATURE]\t | set the temperature setpoint of the given heater");
+	puts("set [HEATER] [TEMP]\t | set the temperature setpoint of the given heater");
 	puts("get [HEATER] [LOCATION]\t | get the temperature of the given heater");
 	puts("get_setpoint [HEATER]\t | get the temperature setpoint of the given heater");
-	puts("ready\t | check the ready state of all heaters");
+	puts("state\t\t\t | get the state of eatch heater");
+	puts("ready\t\t\t | check the ready state of all heaters");
+	puts("enable\t\t\t | enable the heaters");
+	puts("disable\t\t\t | disable the heaters");
 	puts("read [ADDRESS] [LENGTH]\t | read from the device eeprom at address");
 	puts("write [ADDRESS] [LENGTH] | write to the device eeprom at address");
 }
@@ -51,7 +54,7 @@ static int convert_string_to_heater_id(const char* str)
 {
 	char* str_end;
 	long id = strtol(str, &str_end, 10);
-	if(str == str_end || id < 0 || id > 0)
+	if(str == str_end || id < 0 || id > 3)
 	{
 		puts("HEATER must be a whole nummber between 0 and 3");
 		return -1;
@@ -156,7 +159,6 @@ static int process_commands(char** commands, size_t command_count, struct coince
 					printf("Heater %i: setpoint %f\n", i, setpoint);
 				else
 					printf("Heater %i: UNABLE TO READ\n", i);
-
 			}
 		}
 		else
@@ -171,29 +173,67 @@ static int process_commands(char** commands, size_t command_count, struct coince
 				printf("%f\n", temperature);
 		}
 	}
-	else if(strcmp(commands[0], "ready") == 0)
+	else if(strcmp(commands[0], "state") == 0)
 	{
-		if(command_count == 1)
+		for(uint8_t i = 0; i < 4; ++i)
 		{
-			for(uint8_t i = 0; i < 4; ++i)
+			struct heater_state state;
+
+			ret = coincellhell_get_state(hell, i, &state);
+			if(ret < 0)
 			{
-				float setpoint = 0;
-				coincellhell_get_temperature_setpoint(hell, i, &setpoint);
-				printf("Heater %i: setpoint %f", i, setpoint);
+				puts("could not read");
+				break;
 			}
-		}
-		else
-		{
-			int id = convert_string_to_heater_id(commands[1]);
-			if(id < 0)
-				return 1;
+
+			printf("Heater %d:\n\tEnabled: %s\n\tReady: %s\n\tRamp: %s\n\tSet point: %f\n\tDAC command: %d\n",
+				   i, state.enabled ? "True" : "False", state.ready ? "True" : "False", state.ramp ? "True" : "False", state.setpoint, state.dacCommand);
 
 			float temperature;
-			ret = coincellhell_get_temperature_setpoint(hell, id, &temperature);
-			if(ret == 0)
-				printf("%f\n", temperature);
+			ret = coincellhell_get_temperature(hell, i, TEMP_LOCATION_BOTH, &temperature);
+			printf("\tTemperature: %f\n", temperature);
+
+			if(state.ramp)
+			{
+				printf("\tRamp Target: %f\n\tRamp Start Time: %lld\n\tRamp Stop Time: %lld\n",
+					   state.rampTarget, (long long)state.rampStartTime, (long long)state.rampStopTime);
+			}
 		}
 	}
+	else if(strcmp(commands[0], "enable") == 0)
+	{
+		for(uint8_t i = 0; i < 4; ++i)
+		{
+			ret = coincellhell_set_enabled(hell, i, true);
+			if(ret < 0)
+			{
+				puts("could not read");
+				break;
+			}
+		}
+	}
+	else if(strcmp(commands[0], "disable") == 0)
+	{
+		for(uint8_t i = 0; i < 4; ++i)
+		{
+			ret = coincellhell_set_enabled(hell, i, false);
+			if(ret < 0)
+			{
+				puts("could not read");
+				break;
+			}
+		}
+	}
+	else if(strcmp(commands[0], "ready") == 0)
+	{
+		bool ready = false;
+		ret = coincellhell_check_ready(hell, &ready);
+		if(ret == 0)
+				printf("%s\n", ready ? "true" : "false");
+		else
+				puts("could not read");
+
+	}
 	else if(strcmp(commands[0], "write") == 0)
 	{
 		if(command_count < 3)
diff --git a/usbcommands.h b/usbcommands.h
index 0c8dff4..6695cb1 100644
--- a/usbcommands.h
+++ b/usbcommands.h
@@ -3,13 +3,14 @@
 typedef enum {
 	COMMAND_LED_ON = 0,
 	COMMAND_LED_OFF,
-	COMMAND_SET_TEMPERATURE,
-	COMMAND_GET_TEMPERATURE,
-	COMMAND_GET_TEMPERATURE_SETPOINT,
+	COMMAND_HEATER_SET_TEMPERATURE,
+	COMMAND_HEATER_GET_TEMPERATURE,
+	COMMAND_HEATER_GET_TEMPERATURE_SETPOINT,
+	COMMAND_HEATER_GET_STATE,
+	COMMAND_HEATER_SET_ENABLED,
 	COMMAND_READY,
-	COMMAND_RAMP,
-	COMMAND_RAMP_RUNNING,
-	COMMAND_RAMP_CANCLE,
+	COMMAND_HEATER_SETUP_RAMP,
+	COMMAND_HEATER_RAMP_CANCLE,
 	COMMAND_GET_SECONDS = 200,
 	COMMAND_READ_EEPROM,
 	COMMAND_WRITE_EEPROM,
-- 
GitLab