From 9e4a9f0f30215457a12c759bdb2043d6e680891c Mon Sep 17 00:00:00 2001
From: Unknown <mdryden@chem.utoronto.ca>
Date: Fri, 29 Sep 2017 18:02:11 -0400
Subject: [PATCH] Switch experiment parameters to all DAC units.

---
 src/config/conf_board.h |   1 +
 src/experiment.c        | 162 +++++++++++++++++++++++++++-------------
 src/experiment.h        |  12 +--
 src/settings.c          |  12 ++-
 src/settings.h          |   3 +-
 5 files changed, 128 insertions(+), 62 deletions(-)

diff --git a/src/config/conf_board.h b/src/config/conf_board.h
index 37265f9..99f2af8 100644
--- a/src/config/conf_board.h
+++ b/src/config/conf_board.h
@@ -34,6 +34,7 @@
 #define SETTINGS_R100M_TRIM 0
 #define SETTINGS_EIS_CAL1 3000U
 #define SETTINGS_EIS_CAL2 3000000UL
+#define SETTINGS_DAC_UNITS_TRUE 0
 
 
 #endif // CONF_BOARD_H
diff --git a/src/experiment.c b/src/experiment.c
index e565b36..d5d9330 100644
--- a/src/experiment.c
+++ b/src/experiment.c
@@ -60,7 +60,7 @@ static port_callback_t portd_int1_callback;
 
 void experiment_handler(char command[]){
     static int16_t p1, p2, p3;
-    static uint16_t u1, u2, u3, u4;
+    static uint16_t u1, u2, u3, u4, u5, u6;
     static uint8_t p5, o1, o2, o3;
     static int16_t pcv1, pcv2;
     static uint16_t pct1, pct2;
@@ -83,27 +83,87 @@ void experiment_handler(char command[]){
             break;
             
         case 'L': //LSV - start, stop, slope
-            sscanf(command+1, "%u%u%i%i%i%i%u",&pct1,&pct2,&pcv1,&pcv2,&p1,&p2,&u1);
-            precond(pcv1,pct1,pcv2,pct2);
-            lsv_experiment(p1,p2,u1,2);
+            if (settings.settings.dac_units_true) {
+                sscanf(command+1, "%u%u%u%u%u%u%u",&pct1,&pct2,&pcv1,&pcv2,&u1,&u2,&u3);
+                precond(pcv1,pct1,pcv2,pct2);
+                lsv_experiment(u1,u2,u3,2);
+            } else {
+                sscanf(command+1, "%u%u%i%i%i%i%u",&pct1,&pct2,&pcv1,&pcv2,&p1,&p2,&u1);
+                
+                //start
+                u2 = ceil(p1*(65536/(double)3000)+32768);
+                //stop
+                u3 = ceil(p2*(65536/(double)3000)+32768);
+                
+                precond(pcv1,pct1,pcv2,pct2);
+                lsv_experiment(u2,u3,u1,2);
+            }
             break;
             
         case 'C': //CV - v1, v2, start, scans, slope
-            sscanf(command+1, "%u%u%i%i%i%i%i%hhu%u",&pct1,&pct2,&pcv1,&pcv2,&p1,&p2,&p3,&p5,&u1);
-            precond(pcv1,pct1,pcv2,pct2);
-            cv_experiment(p1,p2,p3,p5,u1);
+            if (settings.settings.dac_units_true) {
+                sscanf(command+1, "%u%u%i%i%u%u%u%hhu%u",&pct1,&pct2,&pcv1,&pcv2,&u1,&u2,&u3,&p5,&u4);
+                precond(pcv1,pct1,pcv2,pct2);
+                cv_experiment(u1,u2,u3,p5,u4);
+            } else {
+                sscanf(command+1, "%u%u%i%i%i%i%i%hhu%u",&pct1,&pct2,&pcv1,&pcv2,&p1,&p2,&p3,&p5,&u4);
+                
+                //v1
+                u1 = ceil(p1*(65536/(double)3000)+32768);
+                //v2
+                u2 = ceil(p2*(65536/(double)3000)+32768);
+                //start
+                u3 = ceil(p3*(65536/(double)3000)+32768);
+                //slope
+                u4 = ceil(u4*(65536/(double)3000));
+                
+                precond(pcv1,pct1,pcv2,pct2);
+                cv_experiment(u1,u2,u3,p5,u4);
+            }
             break;
             
         case 'S': //SWV - start, stop, step size, pulse_height, frequency, scans
-            sscanf(command+1, "%u%u%i%i%i%i%u%u%u%u",&pct1,&pct2,&pcv1,&pcv2,&p1,&p2,&u1,&u2,&u3,&u4);
-            precond(pcv1,pct1,pcv2,pct2);
-            swv_experiment(p1,p2,u1,u2,u3,u4);
+            if (settings.settings.dac_units_true) {
+                sscanf(command+1, "%u%u%i%i%u%u%u%u%u%hhu",&pct1,&pct2,&pcv1,&pcv2,&u1,&u2,&u3,&u4,&u5,&p5);
+                precond(pcv1,pct1,pcv2,pct2);
+                swv_experiment(u1,u2,u3,u4,u5,p5);
+            } else {
+                sscanf(command+1, "%u%u%i%i%i%i%u%u%u%hhu",&pct1,&pct2,&pcv1,&pcv2,&p1,&p2,&u1,&u2,&u3,&p5);
+                
+                //start
+                uint16_t start = ceil(p1*(65536/(double)3000)+32768);
+                //stop
+                uint16_t stop = ceil(p2*(65536/(double)3000)+32768);
+                //step
+                u1 = ceil(u1*(65536/(double)3000));
+                //pulse_height
+                u2 = ceil(u2*(65536/(double)3000));
+                
+                precond(pcv1,pct1,pcv2,pct2);
+                swv_experiment(start,stop,u1,u2,u3,p5);
+            }
             break;
             
         case 'D': //DPV - start, stop, step size, pulse_height, period, width
-            sscanf(command+1, "%u%u%i%i%i%i%u%u%u%u",&pct1,&pct2,&pcv1,&pcv2,&p1,&p2,&u1,&u2,&u3,&u4);
-            precond(pcv1,pct1,pcv2,pct2);
-            dpv_experiment(p1,p2,u1,u2,u3,u4);
+            if (settings.settings.dac_units_true) {
+                sscanf(command+1, "%u%u%i%i%u%u%u%u%u%u",&pct1,&pct2,&pcv1,&pcv2,&u1,&u2,&u3,&u4,&u5,&u6);
+                precond(pcv1,pct1,pcv2,pct2);
+                dpv_experiment(u1,u2,u3,u4,u5,u6);
+            } else {
+                sscanf(command+1, "%u%u%i%i%i%i%u%u%u%u",&pct1,&pct2,&pcv1,&pcv2,&p1,&p2,&u1,&u2,&u3,&u4);
+                
+                //start
+                uint16_t start = ceil(p1*(65536/(double)3000)+32768);
+                //stop
+                uint16_t stop = ceil(p2*(65536/(double)3000)+32768);
+                //step
+                u1 = ceil(u1*(65536/(double)3000));
+                //pulse_height
+                u2 = ceil(u2*(65536/(double)3000));
+                
+                precond(pcv1,pct1,pcv2,pct2);
+                dpv_experiment(start,stop,u1,u2,u3,u4);
+            }
             break;
             
         case 'M': //PMT idle mode - holds voltage at 0 V with no data output
@@ -462,7 +522,7 @@ void ocp_exp_start(void){
 }
 #endif
 
-void precond(int16_t v1, uint16_t t1, int16_t v2, uint16_t t2){ //assumes potentiostat switches are already set
+void precond(uint16_t v1, uint16_t t1, uint16_t v2, uint16_t t2){ //assumes potentiostat switches are already set
 	/**
 	 * Performs experiment preconditioning.
 	 *
@@ -536,16 +596,16 @@ static void precond_rtc_callback(uint32_t time){
 	RTC.INTCTRL |= RTC_COMPINTLVL_OFF_gc;
 }
 
-void cv_experiment(int16_t v1, int16_t v2, int16_t start, uint8_t scans, uint16_t slope){
+void cv_experiment(uint16_t v1, uint16_t v2, uint16_t start, uint8_t scans, uint16_t slope){
 	/**
 	 * Perform a CV experiment.
 	 *
 	 * Calls lsv_experiment several times to make a CV experiment.
-	 * @param v1 Vertex 1 in mV.
-	 * @param v2 Vertex 2 in mV.
-	 * @param start Start voltage in mV.
+	 * @param v1 Vertex 1 in dac units.
+	 * @param v2 Vertex 2 in dac units.
+	 * @param start Start voltage in dac units.
 	 * @param scans Number of scans.
-	 * @param slope Scan rate in mV/s.
+	 * @param slope Scan rate in dac units/s.
 	 */
 	// check if start is [v1,v2]
     
@@ -587,33 +647,33 @@ void cv_experiment(int16_t v1, int16_t v2, int16_t start, uint8_t scans, uint16_
 	return;
 }
 
-uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first_run){
+uint8_t lsv_experiment(uint16_t start, uint16_t stop, uint16_t slope, int8_t first_run){
 	/**
 	 * Perform a LSV experiment.
 	 *
 	 * Uses porte_int0_lsv to output to USB.
-	 * @param start Start potential in mV.
-	 * @param stop Stop potential in mV.
-	 * @param slope Scan rate in mV/s.
+	 * @param start Start potential in dac units.
+	 * @param stop Stop potential in dac units.
+	 * @param slope Scan rate in dac units/s.
 	 * @param first_run Keeps track of number of scans so potentiostat isn't initialized twice or disconnected when doing CV. Set to 2 for normal LSV.
 	 */
 	
 	uint8_t ret = 0;
 	
 	//check experiment limits
-	if(start<-1500 || start>=1500 ||start==stop|| stop<-1500 || stop>=1500 || slope>7000)
+	if(start==stop)
 	{
 		printf("#ERR: Experiment parameters outside limits\n");
 		return ret;
 	}
 	
-	uint16_t dacindex_start = ceil(start*(65536/(double)3000)+32768);
-	dacindex_stop = ceil(stop*(65536/(double)3000)+32768);
+//	uint16_t dacindex_start = ceil(start*(65536/(double)3000)+32768);
+//	dacindex_stop = ceil(stop*(65536/(double)3000)+32768);
 	uint32_t timer_period;
 	uint16_t temp_div;
 
 
-	max5443_set_voltage1(dacindex_start);
+	max5443_set_voltage1(start);
 	
 	if (first_run == 1 || first_run == 2){
 		volt_exp_start();
@@ -631,7 +691,7 @@ uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first
 		EVSYS.CH0MUX = EVSYS_CHMUX_TCD0_OVF_gc;
 		EVSYS.CH0CTRL = 0;
 
-		timer_period = ceil(1/((double)slope/(3000./65536))*(F_CPU));
+		timer_period = ceil(1/(double)slope*(F_CPU));
 		temp_div = ceil(timer_period/65536.);
 		
 		if (temp_div <= 1)
@@ -671,7 +731,7 @@ uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first
 
  	}
 	
-	EXP_TC1_0.CNT = dacindex_start;
+	EXP_TC1_0.CNT = start;
 	
 	if (stop > start)
 	{
@@ -684,7 +744,7 @@ uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first
 		tc_set_direction(&EXP_TC1_0, TC_DOWN);
 	}
 	
-	tc_write_cc(&EXP_TC1_0, TC_CCA, dacindex_stop);
+	tc_write_cc(&EXP_TC1_0, TC_CCA, stop);
 	tc_enable_cc_channels(&EXP_TC1_0, TC_CCAEN);
 	EXP_TC0_0.CNT = 0;
 	
@@ -944,23 +1004,23 @@ static void ca_cca_callback(void){
 	return;
 }
 
-void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_height, uint16_t frequency, uint16_t scans){
+void swv_experiment(uint16_t start, uint16_t stop, uint16_t step, uint16_t pulse_height, uint16_t frequency, uint8_t scans){
 	/**
 	 * Perform a SWV experiment
 	 *
-	 * @param start Start voltage in mV.
-	 * @param stop Stop voltage in mV.
-	 * @param step Step voltage in mV.
-	 * @param pulse_height Pulse amplitude in mV.
+	 * @param start Start voltage in dac units.
+	 * @param stop Stop voltage in dac units.
+	 * @param step Step voltage in dac units.
+	 * @param pulse_height Pulse amplitude in dac units.
 	 * @param frequency Frequency in Hz.
 	 * @param scans Number of scans (0 for single direction mode)
 	 */
 
 	uint8_t direction;
-	uint16_t dacindex_start = ceil((start)*(65536/(double)3000))+32768;
-	uint16_t dacindex_stop = ceil(stop*(65536/(double)3000))+32768;
-	uint16_t dacindex_step = ceil(step*(65536/(double)3000));
-	uint16_t dacindex_pulse_height = ceil(pulse_height*(65536/(double)3000));
+//	uint16_t dacindex_start = ceil((start)*(65536/(double)3000))+32768;
+//	uint16_t dacindex_stop = ceil(stop*(65536/(double)3000))+32768;
+//	uint16_t dacindex_step = ceil(step*(65536/(double)3000));
+//	uint16_t dacindex_pulse_height = ceil(pulse_height*(65536/(double)3000));
 	uint32_t period;
 	
 	if (start < stop)
@@ -988,13 +1048,13 @@ void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h
 		EXP_TC0_1.CNT = 0;
 		EXP_TC0_0.CNT = 0;
 	
-		if (_swv_singledir(dacindex_start, dacindex_stop, dacindex_pulse_height, dacindex_step, direction))
+		if (_swv_singledir(start, stop, pulse_height, step, direction))
 			goto aborting; //function will return non-zero if abort called over USB
 		
 		if (scans > 0){ //non-cyclic mode skips out after one direction
 			EXP_TC0_1.CNT = 0;
 			EXP_TC0_0.CNT = 0;
-			if (_swv_singledir(dacindex_stop, dacindex_start, dacindex_pulse_height, dacindex_step, !direction)) //swap start and stop and invert direction for second half of scan
+			if (_swv_singledir(stop, start, pulse_height, step, !direction)) //swap start and stop and invert direction for second half of scan
 				goto aborting;
 		}
 		
@@ -1111,23 +1171,23 @@ uint8_t _swv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t daci
 	return 0;
 }
 
-void dpv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_height, uint16_t pulse_period, uint16_t pulse_width){
+void dpv_experiment(uint16_t start, uint16_t stop, uint16_t step, uint16_t pulse_height, uint16_t pulse_period, uint16_t pulse_width){
 	/**
 	 * Perform a DPV experiment
 	 *
-	 * @param start Start voltage in mV.
-	 * @param stop Stop voltage in mV.
-	 * @param step Step voltage in mV.
-	 * @param pulse_height Pulse amplitude in mV.
+	 * @param start Start voltage in dac units.
+	 * @param stop Stop voltage in dac units.
+	 * @param step Step voltage in dac units.
+	 * @param pulse_height Pulse amplitude in dac units.
 	 * @param pulse_period Pulse period in ms.
 	 * @param pulse_width Pulse width in ms.
 	 */
 
 	uint8_t direction;
-	uint16_t dacindex_start = ceil((start)*(65536/(double)3000))+32768;
-	uint16_t dacindex_stop = ceil(stop*(65536/(double)3000))+32768;
-	uint16_t dacindex_step = ceil(step*(65536/(double)3000));
-	uint16_t dacindex_pulse_height = ceil(pulse_height*(65536/(double)3000));
+//	uint16_t dacindex_start = ceil((start)*(65536/(double)3000))+32768;
+//	uint16_t dacindex_stop = ceil(stop*(65536/(double)3000))+32768;
+//	uint16_t dacindex_step = ceil(step*(65536/(double)3000));
+//	uint16_t dacindex_pulse_height = ceil(pulse_height*(65536/(double)3000));
 	uint32_t cpu_period;
 	uint32_t cpu_width;
 	
@@ -1160,7 +1220,7 @@ void dpv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h
 	EXP_TC0_1.CNT = 0;
 	EXP_TC0_0.CNT = 0;
 	
-	if (_dpv_singledir(dacindex_start, dacindex_stop, dacindex_pulse_height, dacindex_step, direction))
+	if (_dpv_singledir(start, stop, pulse_height, step, direction))
 		goto aborting; //function will return non-zero if abort called over USB
 	
 	printf("D\n"); //signal end of experiment
diff --git a/src/experiment.h b/src/experiment.h
index a410b82..684d6df 100644
--- a/src/experiment.h
+++ b/src/experiment.h
@@ -91,9 +91,9 @@ void pot_init(void);
 void pot_set_gain(void);
 void volt_exp_start(void);
 void volt_exp_stop(void);
-void precond(int16_t v1, uint16_t t1, int16_t v2, uint16_t t2);
-void cv_experiment(int16_t v1, int16_t v2, int16_t start, uint8_t scans, uint16_t slope);
-uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first_run);
+void precond(uint16_t v1, uint16_t t1, uint16_t v2, uint16_t t2);
+void cv_experiment(uint16_t v1, uint16_t v2, uint16_t start, uint8_t scans, uint16_t slope);
+uint8_t lsv_experiment(uint16_t start, uint16_t stop, uint16_t slope, int8_t first_run);
 
 #if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR >= 2
 void ocp_exp_start(void);
@@ -102,7 +102,7 @@ void pot_experiment(uint16_t time_seconds, uint8_t exp_type);
 #endif
 
 void ca_experiment(uint16_t steps, uint16_t step_dac[], uint16_t step_seconds[]);
-void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_height, uint16_t frequency, uint16_t scans);
-void dpv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_height, uint16_t pulse_period, uint16_t pulse_width);
+void swv_experiment(uint16_t start, uint16_t stop, uint16_t step, uint16_t pulse_height, uint16_t frequency, uint8_t scans);
+void dpv_experiment(uint16_t start, uint16_t stop, uint16_t step, uint16_t pulse_height, uint16_t pulse_period, uint16_t pulse_width);
 
-#endif /* EXPERIMENT_H_ */
\ No newline at end of file
+#endif /* EXPERIMENT_H_ */
diff --git a/src/settings.c b/src/settings.c
index a03a25b..06e0db6 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -31,7 +31,7 @@ void settings_handler(char command[]){
             break;
             
         case 'W': //Write new settings
-            sscanf(command+1, "%i%hhu%u%i%i%i%i%i%i%i%lu%lu",
+            sscanf(command+1, "%i%hhu%u%i%i%i%i%i%i%i%lu%lu%hhu",
                   &settings.settings.max5443_offset,
                   &settings.settings.tcs_enabled,
                   &settings.settings.tcs_clear_threshold,
@@ -43,7 +43,8 @@ void settings_handler(char command[]){
                   &settings.settings.r30M_trim,
                   &settings.settings.r100M_trim,
                   &settings.settings.eis_cal1,
-                  &settings.settings.eis_cal2);
+                  &settings.settings.eis_cal2,
+                  &settings.settings.dac_units_true);
             settings_write_eeprom();
             break;
             
@@ -84,7 +85,8 @@ void settings_read_eeprom(void){
     printf("#INFO: r100M_trim = %i\n", settings.settings.r100M_trim);
     printf("#INFO: eis_cal1 = %lu\n", settings.settings.eis_cal1);
     printf("#INFO: eis_cal2 = %lu\n", settings.settings.eis_cal2);
-    printf("Smax5443_offset.%u:tcs_enabled.%u:tcs_clear_threshold.%u:r100_trim.%i:r3k_trim.%i:r30k_trim.%i:r300k_trim.%i:r3M_trim.%i:r30M_trim.%i:r100M_trim.%i:eit_cal1.%lu:eis_cal2.%lu\n",
+    printf("#INFO: dac_units_true = %u\n", settings.settings.dac_units_true);
+    printf("Smax5443_offset.%u:tcs_enabled.%u:tcs_clear_threshold.%u:r100_trim.%i:r3k_trim.%i:r30k_trim.%i:r300k_trim.%i:r3M_trim.%i:r30M_trim.%i:r100M_trim.%i:eit_cal1.%lu:eis_cal2.%lu:dac_units_true.%u\n",
            settings.settings.max5443_offset,
            settings.settings.tcs_enabled,
            settings.settings.tcs_clear_threshold,
@@ -96,7 +98,8 @@ void settings_read_eeprom(void){
            settings.settings.r30M_trim,
            settings.settings.r100M_trim,
            settings.settings.eis_cal1,
-           settings.settings.eis_cal2);
+           settings.settings.eis_cal2,
+           settings.settings.dac_units_true);
 }
 
 void settings_write_eeprom(void){
@@ -119,6 +122,7 @@ void settings_restore_defaults(void){
     settings.settings.r100M_trim = SETTINGS_R100M_TRIM;
     settings.settings.eis_cal1 = SETTINGS_EIS_CAL1;
     settings.settings.eis_cal2 = SETTINGS_EIS_CAL2;
+    settings.settings.dac_units_true = SETTINGS_DAC_UNITS_TRUE;
     
     settings_write_eeprom();
 }
diff --git a/src/settings.h b/src/settings.h
index b2b5091..32b6d9d 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -30,7 +30,8 @@ struct settings_list { //Make sure this doesn't exceed 32 bytes
     int16_t r30M_trim;
     int16_t r100M_trim;
     uint32_t eis_cal1;
-    uint32_t eis_cal2; //28 bytes
+    uint32_t eis_cal2;
+    uint8_t dac_units_true; //29 bytes
 };
 
 union {
-- 
GitLab