From 15d9a049b740b1cb1343bee05ac14700b51cd7a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Foucher?= <cfoucher@laas.fr>
Date: Fri, 25 Mar 2022 10:11:25 +0100
Subject: [PATCH] Add ability to set discontinuous mode on ADCs; Add support
 for various trigger sources from HRTIM to ADCs.

---
 .../zephyr/public_api/adc.c                   | 44 ++++++++++++++----
 .../zephyr/public_api/adc.h                   | 12 ++++-
 .../owntech_adc_driver/zephyr/src/adc_core.c  | 45 +++++++++++++++++--
 .../owntech_adc_driver/zephyr/src/adc_core.h  | 12 ++++-
 .../zephyr/src/adc_configuration.cpp          | 15 +++++--
 .../zephyr/src/adc_configuration.h            |  5 ++-
 .../zephyr/src/hrtim_common.c                 | 18 ++++----
 7 files changed, 124 insertions(+), 27 deletions(-)

diff --git a/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c b/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c
index a6d702f..f100abd 100644
--- a/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c
+++ b/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c
@@ -35,10 +35,17 @@
 #include "adc.h"
 
 
+/////
+// Constants
+
+#define NUMBER_OF_ADCS 3
+
+
 /////
 // Local variables
 
-static uint32_t adc_trigger_sources[3] = {0};
+static uint32_t adc_trigger_sources[NUMBER_OF_ADCS] = {0};
+static uint32_t adc_discontinuous_mode[NUMBER_OF_ADCS] = {0};
 
 
 /////
@@ -58,8 +65,19 @@ void adc_set_dual_mode(uint8_t dual_mode)
 void adc_configure_trigger_source(uint8_t adc_number, uint32_t trigger_source)
 {
 	// Only store configuration: it must be applied after ADC enable
-	if (adc_number < 3)
+	if ( (adc_number > 0) && (adc_number <= NUMBER_OF_ADCS) )
+	{
 		adc_trigger_sources[adc_number-1] = trigger_source;
+	}
+}
+
+void adc_configure_discontinuous_mode(uint8_t adc_number, uint32_t dicontinuous_count)
+{
+	// Only store configuration: it must be applied after ADC enable
+	if ( (adc_number > 0) && (adc_number <= NUMBER_OF_ADCS) )
+	{
+		adc_discontinuous_mode[adc_number-1] = dicontinuous_count;
+	}
 }
 
 int8_t adc_configure_adc_channels(uint8_t adc_number, const char* channel_list[], uint8_t channel_count)
@@ -69,16 +87,16 @@ int8_t adc_configure_adc_channels(uint8_t adc_number, const char* channel_list[]
 
 void adc_start()
 {
-	uint8_t enabled_channels_count[3];
+	uint8_t enabled_channels_count[NUMBER_OF_ADCS];
 
-	for (uint8_t i = 0 ; i < 3 ; i++)
+	for (uint8_t i = 0 ; i < NUMBER_OF_ADCS ; i++)
 	{
 		enabled_channels_count[i] = adc_channels_get_enabled_channels_count(i+1);
 	}
 
 	/////
 	// Enable ADCs
-	for (uint8_t i = 0 ; i < 3 ; i++)
+	for (uint8_t i = 0 ; i < NUMBER_OF_ADCS ; i++)
 	{
 		if (enabled_channels_count[i] > 0)
 		{
@@ -88,7 +106,7 @@ void adc_start()
 
 	/////
 	// Configure ADCs channels
-	for (uint8_t i = 0 ; i < 3 ; i++)
+	for (uint8_t i = 0 ; i < NUMBER_OF_ADCS ; i++)
 	{
 		if (enabled_channels_count[i] > 0)
 		{
@@ -98,7 +116,7 @@ void adc_start()
 
 	/////
 	// Configure ADCs
-	for (uint8_t i = 0 ; i < 3 ; i++)
+	for (uint8_t i = 0 ; i < NUMBER_OF_ADCS ; i++)
 	{
 		if (enabled_channels_count[i] > 0)
 		{
@@ -106,7 +124,15 @@ void adc_start()
 		}
 	}
 
-	for (uint8_t i = 0 ; i < 3 ; i++)
+	for (uint8_t i = 0 ; i < NUMBER_OF_ADCS ; i++)
+	{
+		if ( (enabled_channels_count[i] > 0) && (adc_discontinuous_mode[i] != 0) )
+		{
+			adc_core_configure_discontinuous_mode(i+1, adc_discontinuous_mode[i]);
+		}
+	}
+
+	for (uint8_t i = 0 ; i < NUMBER_OF_ADCS ; i++)
 	{
 		if ( (enabled_channels_count[i] > 0) && (adc_trigger_sources[i] != 0) )
 		{
@@ -116,7 +142,7 @@ void adc_start()
 
 	/////
 	// Finally, start ADCs
-	for (uint8_t i = 0 ; i < 3 ; i++)
+	for (uint8_t i = 0 ; i < NUMBER_OF_ADCS ; i++)
 	{
 		if (enabled_channels_count[i] > 0)
 		{
diff --git a/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.h b/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.h
index a7d6a7c..0b91a13 100644
--- a/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.h
+++ b/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.h
@@ -64,7 +64,7 @@ void adc_init();
 void adc_set_dual_mode(uint8_t dual_mode);
 
 /**
- * Regsters the triger source for an ADC.
+ * Registers the triger source for an ADC.
  * It will be applied when ADC is started.
  *
  * @param adc_number Number of the ADC to configure
@@ -73,6 +73,16 @@ void adc_set_dual_mode(uint8_t dual_mode);
  */
 void adc_configure_trigger_source(uint8_t adc_number, uint32_t trigger_source);
 
+/**
+ * Registers the discontinuous count for an ADC.
+ * It will be applied when ADC is started.
+ *
+ * @param adc_number Number of the ADC to configure
+ * @param dicontinuous_count Number of channels to acquire on each
+ *        trigger event. 0 to disable discontinuous mode (default).
+ */
+void adc_configure_discontinuous_mode(uint8_t adc_number, uint32_t dicontinuous_count);
+
 /**
  * This function is used to configure the channels to be
  * enabled on a given ADC.
diff --git a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.c b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.c
index b9935bf..2294820 100644
--- a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.c
+++ b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.c
@@ -117,15 +117,54 @@ void adc_core_configure_dma_mode(uint8_t adc_num)
 	LL_ADC_REG_SetDMATransfer(adc, LL_ADC_REG_DMA_TRANSFER_UNLIMITED);
 }
 
-void adc_core_configure_trigger_source(uint8_t adc_num, uint32_t ExternalTriggerEdge, uint32_t TriggerSource)
+void adc_core_configure_trigger_source(uint8_t adc_num, uint32_t external_trigger_edge, uint32_t trigger_source)
 {
 	ADC_TypeDef* adc = _get_adc_by_number(adc_num);
 
 	// Set trigger edge
-	LL_ADC_REG_SetTriggerEdge(adc, ExternalTriggerEdge);
+	LL_ADC_REG_SetTriggerEdge(adc, external_trigger_edge);
 
 	// Set trigger source
-	LL_ADC_REG_SetTriggerSource(adc, TriggerSource);
+	LL_ADC_REG_SetTriggerSource(adc, trigger_source);
+}
+
+void adc_core_configure_discontinuous_mode(uint8_t adc_num, uint32_t discontinuous_count)
+{
+	ADC_TypeDef* adc = _get_adc_by_number(adc_num);
+
+	uint32_t discontinuous_mode;
+
+	switch(discontinuous_count)
+	{
+		case 1:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_1RANK;
+			break;
+		case 2:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_2RANKS;
+			break;
+		case 3:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_3RANKS;
+			break;
+		case 4:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_4RANKS;
+			break;
+		case 5:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_5RANKS;
+			break;
+		case 6:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_6RANKS;
+			break;
+		case 7:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_7RANKS;
+			break;
+		case 8:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_8RANKS;
+			break;
+		default:
+			discontinuous_mode = LL_ADC_REG_SEQ_DISCONT_DISABLE;
+	}
+
+	LL_ADC_REG_SetSequencerDiscont(adc, discontinuous_mode);
 }
 
 void adc_core_init()
diff --git a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.h b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.h
index cb176c0..f83ac86 100644
--- a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.h
+++ b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.h
@@ -89,13 +89,21 @@ void adc_core_configure_dma_mode(uint8_t adc_num);
  * Defines the trigger source for an ADC.
  *
  * @param adc_num Number of the ADC to configure.
- * @param ExternalTriggerEdge Edge of the trigger as defined
+ * @param external_trigger_edge Edge of the trigger as defined
  *        in stm32gxx_ll_adc.h (LL_ADC_REG_TRIG_***).
  * @param trigger_source Source of the trigger as defined
  *        in stm32gxx_ll_adc.h (LL_ADC_REG_TRIG_***).
  */
-void adc_core_configure_trigger_source(uint8_t adc_num, uint32_t ExternalTriggerEdge, uint32_t TriggerSource);
+void adc_core_configure_trigger_source(uint8_t adc_num, uint32_t external_trigger_edge, uint32_t trigger_source);
 
+/**
+ * Configures the discontinuous mode for an ADC.
+ *
+ * @param adc_num Number of the ADC to configure.
+ * @param discontinuous_count Number of channels to acquire on each
+ *        trigger event. 0 to disable discontinuous mode (default).
+ */
+void adc_core_configure_discontinuous_mode(uint8_t adc_num, uint32_t discontinuous_count);
 
 #ifdef __cplusplus
 }
diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.cpp b/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.cpp
index 0c1b3e8..7187b8d 100644
--- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.cpp
+++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.cpp
@@ -47,8 +47,8 @@ void _initialize()
 		initialized = 1;
 
 		// Perform default configration
-		configure_adc_trigger_source(1, hrtim1);
-		configure_adc_trigger_source(2, hrtim1);
+		configure_adc_trigger_source(1, hrtim_ev1);
+		configure_adc_trigger_source(2, hrtim_ev1);
 		configure_adc_trigger_source(3, software);
 	}
 }
@@ -109,9 +109,18 @@ void configure_adc_trigger_source(uint8_t adc_number, adc_src_t trigger_source)
 	uint32_t trig;
 	switch (trigger_source)
 	{
-	case hrtim1:
+	case hrtim_ev1:
 		trig = LL_ADC_REG_TRIG_EXT_HRTIM_TRG1;
 		break;
+	case hrtim_ev2:
+		trig = LL_ADC_REG_TRIG_EXT_HRTIM_TRG2;
+		break;
+	case hrtim_ev3:
+		trig = LL_ADC_REG_TRIG_EXT_HRTIM_TRG3;
+		break;
+	case hrtim_ev4:
+		trig = LL_ADC_REG_TRIG_EXT_HRTIM_TRG4;
+		break;
 	case software:
 	default:
 		trig = LL_ADC_REG_TRIG_SOFTWARE;
diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.h b/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.h
index d08e852..482b658 100644
--- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.h
+++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.h
@@ -35,7 +35,10 @@
 // Public enums
 typedef enum
 {
-	hrtim1,
+	hrtim_ev1,
+	hrtim_ev2,
+	hrtim_ev3,
+	hrtim_ev4,
 	software
 } adc_src_t;
 
diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c b/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c
index f89a664..8629b66 100644
--- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c
+++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c
@@ -27,6 +27,12 @@
 #include "leg.h"
 
 
+void _hrtim_init_events()
+{
+	hrtim_adc_trigger_en(0, ADC1R, AD13_TAC3);
+	hrtim_cmp_set(0, TIMA, CMP3xR, 1);
+}
+
 void hrtim_init_current()
 {
 	hrtim_cm_init();
@@ -37,27 +43,23 @@ void hrtim_init_current()
 void hrtim_init_voltage_buck()
 {
 	leg_init(true,true);
-	hrtim_adc_trigger_en(0, ADC1R, AD13_TAC3);
-	hrtim_cmp_set(0, TIMA, CMP3xR, 1);
+	_hrtim_init_events();
 }
 
 void hrtim_init_voltage_boost()
 {
 	leg_init(false,false);
-	hrtim_adc_trigger_en(0, ADC1R, AD13_TAC3);
-	hrtim_cmp_set(0, TIMA, CMP3xR, 1);
+	_hrtim_init_events();
 }
 
 void hrtim_init_voltage_leg1_buck_leg2_boost()
 {
 	leg_init(true,false);
-	hrtim_adc_trigger_en(0, ADC1R, AD13_TAC3);
-	hrtim_cmp_set(0, TIMA, CMP3xR, 1);
+	_hrtim_init_events();
 }
 
 void hrtim_init_voltage_leg1_boost_leg2_buck()
 {
 	leg_init(false,true);
-	hrtim_adc_trigger_en(0, ADC1R, AD13_TAC3);
-	hrtim_cmp_set(0, TIMA, CMP3xR, 1);
+	_hrtim_init_events();
 }
-- 
GitLab