From ebbb70487a6cf0f90ed27d0fc2cf67b951119d71 Mon Sep 17 00:00:00 2001 From: "Michael D. M. Dryden" Date: Wed, 16 Jul 2014 17:11:09 -0400 Subject: [PATCH] DPV implemented mostly copying SWV, but using TC CCA to signal end of pulse. --- DSTAT-temp/src/experiment.c | 178 ++++++++++++++++++++++++++++++++++ DSTAT-temp/src/experiment.h | 1 + DSTAT-temp/src/main.c | 6 ++ EEPROM init/EEPROM init.cproj | 100 +++++++++---------- 4 files changed, 235 insertions(+), 50 deletions(-) diff --git a/DSTAT-temp/src/experiment.c b/DSTAT-temp/src/experiment.c index a262d0f..68f6b78 100644 --- a/DSTAT-temp/src/experiment.c +++ b/DSTAT-temp/src/experiment.c @@ -44,6 +44,7 @@ static void lsv_dma_callback1(void); static void ca_cca_callback(void); static void portd_int0_ca(void); static uint8_t _swv_singledir(uint16_t dacindex, uint16_t dacindex_stop, uint16_t dacindex_pulse_height, uint16_t dacindex_step, uint8_t direction); +static uint8_t _dpv_singledir(uint16_t dacindex, uint16_t dacindex_stop, uint16_t dacindex_pulse_height, uint16_t dacindex_step, uint8_t direction); //interrupt callback setup typedef void (*port_callback_t) (void); @@ -645,6 +646,7 @@ void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h * @param step Step voltage in mV. * @param pulse_height Pulse amplitude in mV. * @param frequency Frequency in Hz. + * @param scans Number of scans (0 for single direction mode) */ uint8_t direction; @@ -743,6 +745,15 @@ void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h } uint8_t _swv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t dacindex_pulse_height, uint16_t dacindex_step, uint8_t direction){ + /** + * Internal function that performs a single direction sweep for SWV + * + * @param dacindex Starting voltage as dac index + * @param dacindex_stop Stop voltage in dac index. + * @param dacindex_step Step voltage in dac index. + * @param dacindex_pulse_height Pulse amplitude in dac index. + * @param direction Scan direction - 1 for up, 0 for down. + */ int32_t forward = 0; int32_t reverse = 0; uint16_t lastindex = 0; @@ -807,6 +818,173 @@ 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){ + /** + * 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 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 = dacindex_start; + uint32_t cpu_period; + uint32_t cpu_width; + + if (start < stop) + direction = 1; + else + direction = 0; + + tc_enable(&TCF0); + + //calculate time to ADC trigger + cpu_period = ceil((double)pulse_period*1e-3*F_CPU); + uint16_t temp_div = ceil((double)cpu_period/65536); + + if (temp_div == 1) + tc_write_clock_source(&TCF0,TC_CLKSEL_DIV1_gc); + else if (temp_div == 2) + tc_write_clock_source(&TCF0,TC_CLKSEL_DIV2_gc); + else if (temp_div <= 4){ + tc_write_clock_source(&TCF0,TC_CLKSEL_DIV4_gc); + temp_div = 4; + } + else if (temp_div <= 8){ + tc_write_clock_source(&TCF0,TC_CLKSEL_DIV8_gc); + temp_div = 8; + } + else if (temp_div <= 64){ + tc_write_clock_source(&TCF0,TC_CLKSEL_DIV64_gc); + temp_div = 64; + } + else if (temp_div <= 256){ + tc_write_clock_source(&TCF0,TC_CLKSEL_DIV256_gc); + temp_div = 256; + } + else if (temp_div <= 1024){ + tc_write_clock_source(&TCF0,TC_CLKSEL_DIV1024_gc); + temp_div = 1024; + } + else{ + printf("#Frequency/ADC rate is too low\n\r"); + return; + } + + tc_write_period(&TCF0, (uint16_t)(cpu_period/temp_div)); + cpu_width = (double)pulse_width*1e-3*F_CPU; + tc_write_cc(&TCF0, TC_CCA, (uint16_t)(cpu_width/temp_div)); + tc_enable_cc_channels(&TCF0, TC_CCAEN); + + if (direction == 1) + max5443_set_voltage1(dacindex+dacindex_pulse_height); + else + max5443_set_voltage1(dacindex-dacindex_pulse_height); + + ads1255_wakeup(); + ads1255_rdatac(); + ads1255_sync(); + pot_exp_start(); + + TCF0.CNT = 0; + while (!tc_is_overflow(&TCF0)); + ads1255_wakeup(); //synchronize ADC + TCF0.CNT = 0; + + if (_dpv_singledir(dacindex_start, dacindex_stop, dacindex_pulse_height, dacindex_step, direction)) + goto aborting; //function will return non-zero if abort called over USB + + printf("D\n\r"); //signal end of experiment + + aborting: + pot_exp_stop(); + tc_write_clock_source(&TCF0, TC_CLKSEL_OFF_gc); + tc_disable(&TCF0); + TCF0.CNT = 0; + ads1255_standby(); + + return; +} + +uint8_t _dpv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t dacindex_pulse_height, uint16_t dacindex_step, uint8_t direction){ + /** + * Internal function that performs a single direction sweep for DPV + * + * @param dacindex Starting voltage as dac index + * @param dacindex_stop Stop voltage in dac index. + * @param dacindex_step Step voltage in dac index. + * @param dacindex_pulse_height Pulse amplitude in dac index. + * @param direction Scan direction - 1 for up, 0 for down. + */ + int32_t forward = 0; + int32_t reverse = 0; + uint16_t lastindex = 0; + + if (direction == 1) + max5443_set_voltage1(dacindex+dacindex_pulse_height); + else + max5443_set_voltage1(dacindex-dacindex_pulse_height); + + while ((dacindex <= dacindex_stop && direction == 1) || (dacindex >= dacindex_stop && direction == 0)){ + tc_clear_overflow(&TCF0); + tc_clear_cc_interrupt(&TCF0, TC_CCA); + + while (!tc_is_cc_interrupt(&TCF0, TC_CCA)){ //convert continuously until tc CCA match - datum is last collected point + while (ioport_pin_is_low(IOPORT_CREATE_PIN(PORTD, 5))); //wait for next valid datum + while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTD, 5))); + forward = ads1255_read_fast24(); + if (udi_cdc_is_rx_ready()){ //check for abort signal over USB + if (getchar() == 'a') + return 1; + } + } + + //switch voltage to baseline + max5443_set_voltage1(dacindex); + + while (!tc_is_overflow(&TCF0)){ //wait for tc overflow + while (ioport_pin_is_low(IOPORT_CREATE_PIN(PORTD, 5))); //wait for next valid datum + while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTD, 5))); + reverse = ads1255_read_fast24(); + + if (udi_cdc_is_rx_ready()){ + if (getchar() == 'a') + return 1; + } + } + + lastindex = dacindex; + + //increment dacindex + if (direction == 1){ + dacindex += dacindex_step; + max5443_set_voltage1(dacindex+dacindex_pulse_height); + } + + else{ + dacindex -= dacindex_step; + max5443_set_voltage1(dacindex-dacindex_pulse_height); + } + + //data output + printf("B\n"); + send_data_uint16(lastindex); + send_data_int32(forward); + send_data_int32(reverse); + printf("\n"); + } + + return 0; +} + ISR(PORTD_INT0_vect){ if (portd_int0_callback) { portd_int0_callback(); diff --git a/DSTAT-temp/src/experiment.h b/DSTAT-temp/src/experiment.h index 549a466..f9cea97 100644 --- a/DSTAT-temp/src/experiment.h +++ b/DSTAT-temp/src/experiment.h @@ -71,5 +71,6 @@ void cv_experiment(int16_t v1, int16_t v2, int16_t start, uint8_t scans, uint16_ uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first_run); 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); #endif /* EXPERIMENT_H_ */ \ No newline at end of file diff --git a/DSTAT-temp/src/main.c b/DSTAT-temp/src/main.c index e82cba2..bb6514f 100644 --- a/DSTAT-temp/src/main.c +++ b/DSTAT-temp/src/main.c @@ -60,6 +60,12 @@ int8_t command_handler(char command){ swv_experiment(p1,p2,u1,u2,u3,u4); break; + case 'D': //DPV - start, stop, step size, pulse_height, period, width + scanf("%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); + break; + case 'R': //CA - steps, step_dac[], step_seconds[] scanf("%u",&p5); //get number of steps printf("#Steps: %u\n\r", p5); diff --git a/EEPROM init/EEPROM init.cproj b/EEPROM init/EEPROM init.cproj index 9066da0..61a951b 100644 --- a/EEPROM init/EEPROM init.cproj +++ b/EEPROM init/EEPROM init.cproj @@ -26,14 +26,14 @@ 2 1 - + - + @@ -41,59 +41,59 @@ - True - True - True - True - True - False - True - True - - - NDEBUG - - - Optimize for size (-Os) - True - True - True - - - libm - - - + True + True + True + True + True + False + True + True + + + NDEBUG + + + Optimize for size (-Os) + True + True + True + + + libm + + + - True - True - True - True - True - False - True - True - - - DEBUG - - - Optimize (-O1) - True - True - Default (-g2) - True - - - libm - - - Default (-Wa,-g) - + True + True + True + True + True + False + True + True + + + DEBUG + + + Optimize (-O1) + True + True + Default (-g2) + True + + + libm + + + Default (-Wa,-g) + -- GitLab