From 00f4a1212ea3c515552ca436c8f0e5a6db0ba03d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Foucher?= <cfoucher@laas.fr>
Date: Fri, 16 Jul 2021 17:16:58 +0000
Subject: [PATCH] DAC driver: - Add functions to change the reset value and
 step value of function mode; - Per-channel independent configuration; - Do
 not allow channel start if not correctly configured.

---
 .../zephyr/public_include/dac.h               | 19 ++++++
 .../zephyr/src/stm32_dac_driver.c             | 58 +++++++++++++++----
 .../zephyr/src/stm32_dac_driver.h             |  9 ++-
 3 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/zephyr/modules/owntech_dac_driver/zephyr/public_include/dac.h b/zephyr/modules/owntech_dac_driver/zephyr/public_include/dac.h
index 3729d5c..2b2de88 100644
--- a/zephyr/modules/owntech_dac_driver/zephyr/public_include/dac.h
+++ b/zephyr/modules/owntech_dac_driver/zephyr/public_include/dac.h
@@ -64,6 +64,8 @@ typedef struct
 
 typedef void (*dac_api_setconstvalue) (const struct device* dev, uint8_t channel, uint32_t value);
 typedef void (*dac_api_setfunction)   (const struct device* dev, uint8_t channel, const dac_function_config_t* config);
+typedef void (*dac_api_fn_upd_reset)  (const struct device* dev, uint8_t channel, uint32_t reset_data);
+typedef void (*dac_api_fn_upd_step)   (const struct device* dev, uint8_t channel, uint32_t step_data);
 typedef void (*dac_api_pinconfigure)  (const struct device* dev, uint8_t channel, const dac_pin_config_t* config);
 typedef void (*dac_api_start)         (const struct device* dev, uint8_t channel);
 typedef void (*dac_api_stop)          (const struct device* dev, uint8_t channel);
@@ -72,6 +74,8 @@ __subsystem struct dac_driver_api
 {
     dac_api_setconstvalue setconstvalue;
 	dac_api_setfunction   setfunction;
+	dac_api_fn_upd_reset  fn_upd_reset;
+	dac_api_fn_upd_step   fn_upd_step;
 	dac_api_pinconfigure  pinconfigure;
 	dac_api_start         start;
 	dac_api_stop          stop;
@@ -91,6 +95,21 @@ static inline void dac_set_function(const struct device* dev, uint8_t channel, c
 	api->setfunction(dev, channel, function_config);
 }
 
+static inline void dac_function_update_reset(const struct device* dev, uint8_t channel, uint32_t reset_data)
+{
+	const struct dac_driver_api* api = (const struct dac_driver_api*)(dev->api);
+
+	api->fn_upd_reset(dev, channel, reset_data);
+}
+
+static inline void dac_function_update_step(const struct device* dev, uint8_t channel, uint32_t step_data)
+{
+	const struct dac_driver_api* api = (const struct dac_driver_api*)(dev->api);
+
+	api->fn_upd_step(dev, channel, step_data);
+}
+
+
 static inline void dac_pin_configure(const struct device* dev, uint8_t channel, const dac_pin_config_t* pin_config)
 {
 	const struct dac_driver_api* api = (const struct dac_driver_api*)(dev->api);
diff --git a/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c b/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c
index 10a66a4..78f5a35 100644
--- a/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c
+++ b/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c
@@ -65,6 +65,8 @@ static const struct dac_driver_api dac_funcs =
 {
 	.setconstvalue = dac_stm32_set_const_value,
 	.setfunction   = dac_stm32_set_function,
+	.fn_upd_reset  = dac_stm32_function_update_reset,
+	.fn_upd_step   = dac_stm32_function_update_step,
 	.pinconfigure  = dac_stm32_pin_configure,
 	.start         = dac_stm32_start,
 	.stop          = dac_stm32_stop
@@ -77,9 +79,10 @@ static void dac_stm32_set_const_value(const struct device* dev, uint8_t channel,
 
 	uint8_t dac_channel = __LL_DAC_DECIMAL_NB_TO_CHANNEL(channel);
 
-	if (data->dac_mode != dac_mode_constant)
+	if (data->dac_mode[channel-1] != dac_mode_constant)
 	{
-		data->dac_mode = dac_mode_constant;
+		data->dac_mode[channel-1] = dac_mode_constant;
+		data->dac_config->constant_value = value;
 
 		LL_DAC_SetSignedFormat(dac_dev, dac_channel, LL_DAC_SIGNED_FORMAT_DISABLE);
 
@@ -99,10 +102,12 @@ static void dac_stm32_set_function(const struct device* dev, uint8_t channel, co
 
 	uint8_t dac_channel = __LL_DAC_DECIMAL_NB_TO_CHANNEL(channel);
 
-	data->dac_mode = dac_mode_function;
+	data->dac_mode[channel-1] = dac_mode_function;
 
 	if (function_config->dac_function == dac_function_sawtooth)
 	{
+		data->dac_config->function_config = *function_config;
+
 		LL_DAC_SetSignedFormat(dac_dev, dac_channel, LL_DAC_SIGNED_FORMAT_DISABLE);
 
 		LL_DAC_SetWaveAutoGeneration(dac_dev, dac_channel, LL_DAC_WAVE_AUTO_GENERATION_SAWTOOTH);
@@ -117,6 +122,36 @@ static void dac_stm32_set_function(const struct device* dev, uint8_t channel, co
 	}
 }
 
+static void dac_stm32_function_update_reset(const struct device* dev, uint8_t channel, uint32_t reset_data)
+{
+	struct stm32_dac_driver_data* data = (struct stm32_dac_driver_data*)dev->data;
+
+	if (data->dac_mode[channel-1] == dac_mode_function)
+	{
+		dac_function_config_t new_config = data->dac_config->function_config;
+		new_config.reset_data = reset_data;
+
+		dac_stm32_stop(dev, channel);
+		dac_stm32_set_function(dev, channel, &new_config);
+		dac_stm32_start(dev, channel);
+	}
+}
+
+static void dac_stm32_function_update_step(const struct device* dev, uint8_t channel, uint32_t step_data)
+{
+	struct stm32_dac_driver_data* data = (struct stm32_dac_driver_data*)dev->data;
+
+	if (data->dac_mode[channel-1] == dac_mode_function)
+	{
+		dac_function_config_t new_config = data->dac_config->function_config;
+		new_config.step_data = step_data;
+
+		dac_stm32_stop(dev, channel);
+		dac_stm32_set_function(dev, channel, &new_config);
+		dac_stm32_start(dev, channel);
+	}
+}
+
 static void dac_stm32_pin_configure(const struct device* dev, uint8_t channel, const dac_pin_config_t* pin_config)
 {
 	struct stm32_dac_driver_data* data = (struct stm32_dac_driver_data*)dev->data;
@@ -134,11 +169,14 @@ static void dac_stm32_start(const struct device* dev, uint8_t channel)
 
 	uint8_t dac_channel = __LL_DAC_DECIMAL_NB_TO_CHANNEL(channel);
 
-	LL_DAC_Enable(dac_dev, dac_channel);
-
-	while (LL_DAC_IsReady(dac_dev, dac_channel) == 0)
+	if (data->dac_mode[channel-1] != dac_mode_unset)
 	{
-		// Wait
+		LL_DAC_Enable(dac_dev, dac_channel);
+
+		while (LL_DAC_IsReady(dac_dev, dac_channel) == 0)
+		{
+			// Wait
+		}
 	}
 }
 
@@ -162,7 +200,7 @@ static void dac_stm32_stop(const struct device* dev, uint8_t channel)
 struct stm32_dac_driver_data dac1_data =
 {
 	.dac_struct = DAC1,
-	.dac_mode   = dac_mode_unset
+	.dac_mode   = {dac_mode_unset, dac_mode_unset}
 };
 
 DEVICE_DT_DEFINE(DAC1_NODELABEL,
@@ -183,7 +221,7 @@ DEVICE_DT_DEFINE(DAC1_NODELABEL,
 struct stm32_dac_driver_data dac2_data =
 {
 	.dac_struct = DAC2,
-	.dac_mode   = dac_mode_unset
+	.dac_mode   = {dac_mode_unset, dac_mode_unset}
 };
 
 DEVICE_DT_DEFINE(DAC2_NODELABEL,
@@ -204,7 +242,7 @@ DEVICE_DT_DEFINE(DAC2_NODELABEL,
 struct stm32_dac_driver_data dac3_data =
 {
 	.dac_struct = DAC3,
-	.dac_mode   = dac_mode_unset
+	.dac_mode   = {dac_mode_unset, dac_mode_unset}
 };
 
 DEVICE_DT_DEFINE(DAC3_NODELABEL,
diff --git a/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.h b/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.h
index 88674ff..edc67d4 100644
--- a/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.h
+++ b/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.h
@@ -50,7 +50,12 @@ typedef enum
 struct stm32_dac_driver_data
 {
 	DAC_TypeDef* dac_struct;
-	dac_mode_t   dac_mode;
+	dac_mode_t   dac_mode[2];
+	union
+	{
+		uint32_t              constant_value;
+		dac_function_config_t function_config;
+	} dac_config[2];
 };
 
 
@@ -58,6 +63,8 @@ struct stm32_dac_driver_data
 static int  dac_stm32_init(const struct device* dev);
 static void dac_stm32_set_const_value(const struct device* dev, uint8_t channel, uint32_t value);
 static void dac_stm32_set_function(const struct device* dev, uint8_t channel, const dac_function_config_t* function_config);
+static void dac_stm32_function_update_reset(const struct device* dev, uint8_t channel, uint32_t reset_data);
+static void dac_stm32_function_update_step(const struct device* dev, uint8_t channel, uint32_t step_data);
 static void dac_stm32_pin_configure(const struct device* dev, uint8_t channel, const dac_pin_config_t* pin_config);
 static void dac_stm32_start(const struct device* dev, uint8_t channel);
 static void dac_stm32_stop(const struct device* dev, uint8_t channel);
-- 
GitLab