diff --git a/DSTAT/src/config/conf_board.h b/DSTAT/src/config/conf_board.h index a57fbf644da8d935693f8647a5f8531ed1f17a7c..4d91caba27facebd8c3a206d7fbf1ce2937b690d 100644 --- a/DSTAT/src/config/conf_board.h +++ b/DSTAT/src/config/conf_board.h @@ -14,7 +14,7 @@ // Default Settings (only used if EEPROM is empty) #define SETTINGS_MAX5443_OFFSET 0 -#define SETTINGS_TCS_ENABLED 0 +#define SETTINGS_TCS_ENABLED 1 #define SETTINGS_TCS_CLEAR_THRESHOLD 10000U #define SETTINGS_R100_TRIM 0 #define SETTINGS_R3k_TRIM 0 diff --git a/DSTAT/src/experiment.c b/DSTAT/src/experiment.c index e2dde886719a675d66828b4ed4bfff7bbdd10fd5..86db848a00f3513b572568db63fa6a3a71fa92c6 100644 --- a/DSTAT/src/experiment.c +++ b/DSTAT/src/experiment.c @@ -38,7 +38,7 @@ volatile uint16_t tcf0period = 0; uint32_t skip_samples = 0; //Private function declarations -uint16_t set_timer_period(uint32_t period, volatile void *tc); +//uint16_t set_timer_period(uint32_t period, volatile void *tc); static void precond_rtc_callback(uint32_t time); static void porte_int0_lsv(void); static void tcf0_ovf_callback(void); @@ -48,6 +48,7 @@ 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); +static void pmt_idle(void); //interrupt callback setup typedef void (*port_callback_t) (void); @@ -101,6 +102,10 @@ void experiment_handler(char command){ dpv_experiment(p1,p2,u1,u2,u3,u4); break; + case 'M': //PMT idle mode - holds voltage at 0 V with no data output + pmt_idle(); + break; + #if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR >= 2 case 'P': //potentiometry - time, OCP/poteniometry scanf("%u%hhu",&pct1, &o1); @@ -139,17 +144,20 @@ void experiment_handler(char command){ if (o1 > 0) { if (settings.settings.tcs_enabled > 0){ tcs_readvalues(tcs_data); - delay_ms(25); - tcs_readvalues(tcs_data1); // If sensor disconnected, second measurement should be exactly the same + tcs_readvalues(tcs_data1); // If sensor disconnected, second measurement should be exactly the same (unless 0 or saturated) + printf("#INFO: TCS0—%u %u %u %u\n\r", tcs_data[0], tcs_data[1], tcs_data[2], tcs_data[3]); + printf("#INFO: TCS1—%u %u %u %u\n\r", tcs_data1[0], tcs_data1[1], tcs_data1[2], tcs_data1[3]); + if (tcs_data[0] == tcs_data1[0]){ + if (!(tcs_data[0] == 0 || tcs_data[0] == 65535)) { + printf("#ERR: Ambient light sensor seems to be disconnected \n\r"); + return; + } + } if (tcs_data[0] > settings.settings.tcs_clear_threshold){ printf("#ERR: Ambient light exceeds threshold %u\n\r", tcs_data[0]); printf("#INFO: TCS—%u %u %u %u\n\r", tcs_data[0], tcs_data[1], tcs_data[2], tcs_data[3]); return; } - else if (tcs_data[3] == tcs_data1[3]){ - printf("#ERR: Ambient light sensor seems to be disconnected \n\r"); - return; - } } else { printf("#ERR: Ambient light sensor disabled.\n\r"); @@ -360,17 +368,20 @@ void volt_exp_start(void){ * Connects measurement cell to rest of circuit. */ #if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR == 1 - ioport_set_port_level(IOPORT_PORTB, PIN3_bm|PIN4_bm|PIN5_bm, PIN3_bm|PIN4_bm|PIN5_bm); + ioport_set_port_level(IOPORT_PORTB, PIN3_bm|PIN4_bm|PIN5_bm, PIN3_bm|PIN4_bm); #endif #if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR == 2 - ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm, PIN2_bm|PIN4_bm|PIN5_bm); + ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm, PIN2_bm|PIN4_bm); #endif + + delay_ms(100); // Make sure WE circuit is connected before control voltage applied + ioport_set_pin_level(PIN_POT_CE, 1); if (g_short == 1) - ioport_set_port_level(IOPORT_PORTB, PIN3_bm, PIN3_bm); + ioport_set_pin_level(PIN_POT_2ELECTRODE, 1); else - ioport_set_port_level(IOPORT_PORTB, PIN3_bm, 0); + ioport_set_pin_level(PIN_POT_2ELECTRODE, 0); } void volt_exp_stop(void){ @@ -378,13 +389,16 @@ void volt_exp_stop(void){ * Disconnects measurement cell. */ #if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR == 1 - ioport_set_port_level(IOPORT_PORTB, PIN3_bm|PIN4_bm|PIN5_bm, 0); + ioport_set_port_level(IOPORT_PORTB, PIN3_bm|PIN5_bm, 0); #endif #if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR == 2 - ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm, 0); + ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN5_bm, 0); #endif - ioport_set_port_level(IOPORT_PORTB, PIN3_bm, PIN3_bm); + delay_ms(100); // Make sure WE is last to disconnect + ioport_set_pin_level(PIN_POT_WE, 0); + + ioport_set_pin_level(PIN_POT_2ELECTRODE, 1); } #if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR >= 2 @@ -560,14 +574,13 @@ uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first if (first_run == 1 || first_run == 2){ volt_exp_start(); ads1255_rdatac(); - tc_enable(&TCC1); - ads1255_sync(); - tc_enable(&TCC0); - tc_set_overflow_interrupt_callback(&TCC0, tcf0_ovf_callback); - tc_set_overflow_interrupt_callback(&TCC1, tce1_ovf_callback_lsv); - tc_set_cca_interrupt_callback(&TCC1, lsv_cca_callback); + tc_enable(&EXP_TC0_0); + tc_enable(&EXP_TC1_0); + tc_set_overflow_interrupt_callback(&EXP_TC0_0, tcf0_ovf_callback); + tc_set_overflow_interrupt_callback(&EXP_TC1_0, tce1_ovf_callback_lsv); + tc_set_cca_interrupt_callback(&EXP_TC1_0, lsv_cca_callback); portd_int0_callback = porte_int0_lsv; //ADC read //set EVCH0 event @@ -609,33 +622,33 @@ uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first } ads1255_wakeup(); - tc_write_period(&TCC1, 0xffff); - tc_write_period(&TCC0, (uint16_t)timer_period); + tc_write_period(&EXP_TC1_0, 0xffff); + tc_write_period(&EXP_TC0_0, (uint16_t)timer_period); } - TCC1.CNT = dacindex_start; + EXP_TC1_0.CNT = dacindex_start; if (stop > start) { up = 1; - tc_set_direction(&TCC1, TC_UP); + tc_set_direction(&EXP_TC1_0, TC_UP); } else { up = -1; - tc_set_direction(&TCC1, TC_DOWN); + tc_set_direction(&EXP_TC1_0, TC_DOWN); } - tc_write_cc(&TCC1, TC_CCA, dacindex_stop); - tc_enable_cc_channels(&TCC1, TC_CCAEN); - TCC0.CNT = 0; + tc_write_cc(&EXP_TC1_0, TC_CCA, dacindex_stop); + tc_enable_cc_channels(&EXP_TC1_0, TC_CCAEN); + EXP_TC0_0.CNT = 0; - tc_set_cca_interrupt_level(&TCC1, TC_INT_LVL_HI); //Stop experiment - tc_set_overflow_interrupt_level(&TCC0, TC_OVFINTLVL_LO_gc); //Set DAC + tc_set_cca_interrupt_level(&EXP_TC1_0, TC_INT_LVL_HI); //Stop experiment + tc_set_overflow_interrupt_level(&EXP_TC0_0, TC_OVFINTLVL_LO_gc); //Set DAC PORTD.INTCTRL = PORT_INT0LVL_MED_gc; //ADC read - tc_write_clock_source(&TCC1, TC_CLKSEL_EVCH0_gc); + tc_write_clock_source(&EXP_TC1_0, TC_CLKSEL_EVCH0_gc); //Experiment run with interrupts while (up != 0){ @@ -652,9 +665,9 @@ uint8_t lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first if (first_run == -1 || first_run == 2) { aborting: - tc_disable(&TCC0); - TCC0.CNT = 0x0; - tc_disable(&TCC1); + tc_disable(&EXP_TC0_0); + EXP_TC0_0.CNT = 0x0; + tc_disable(&EXP_TC1_0); volt_exp_stop(); ads1255_standby(); return ret; @@ -676,7 +689,7 @@ static void porte_int0_lsv(void){ data.result = ads1255_read_fast24(); static uint16_t last_value = 0; - uint32_t current = TCC1.CNT; + uint32_t current = EXP_TC1_0.CNT; data.index = (current+last_value)>>1; //DAC value is average of current and last timer - approximation of center of averaging window printf("B\n"); @@ -688,21 +701,21 @@ static void porte_int0_lsv(void){ } static void tcf0_ovf_callback(void){ - max5443_set_voltage1(TCC1.CNT); + max5443_set_voltage1(EXP_TC1_0.CNT); } static void tce1_ovf_callback_lsv(void){ PORTD.INTCTRL = PORT_INT0LVL_OFF_gc; - tc_set_overflow_interrupt_level(&TCC0, TC_OVFINTLVL_OFF_gc); - tc_set_overflow_interrupt_level(&TCC1, TC_OVFINTLVL_OFF_gc); + tc_set_overflow_interrupt_level(&EXP_TC0_0, TC_OVFINTLVL_OFF_gc); + tc_set_overflow_interrupt_level(&EXP_TC1_0, TC_OVFINTLVL_OFF_gc); up = 0; return; } static void lsv_cca_callback(void){ PORTD.INTCTRL = PORT_INT0LVL_OFF_gc; - tc_set_overflow_interrupt_level(&TCC0, TC_OVFINTLVL_OFF_gc); - tc_set_cca_interrupt_level(&TCC1, TC_INT_LVL_OFF); + tc_set_overflow_interrupt_level(&EXP_TC0_0, TC_OVFINTLVL_OFF_gc); + tc_set_cca_interrupt_level(&EXP_TC1_0, TC_INT_LVL_OFF); up = 0; return; } @@ -726,23 +739,23 @@ void pot_experiment(uint16_t time_seconds, uint8_t exp_type){ portd_int0_callback = portd_int0_ca; //ADC interrupt - tc_enable(&TCC0); + tc_enable(&EXP_TC0_0); ads1255_mux(ADS_MUX_POT); ads1255_rdatac(); ads1255_wakeup(); - tc_write_period(&TCC0,0xffff); - tc_write_clock_source(&TCC0, TC_CLKSEL_EVCH0_gc); - tc_set_direction(&TCC0, TC_UP); + tc_write_period(&EXP_TC0_0,0xffff); + tc_write_clock_source(&EXP_TC0_0, TC_CLKSEL_EVCH0_gc); + tc_set_direction(&EXP_TC0_0, TC_UP); up = 1; if (time_seconds >= 1){ //only enable interrupt if non-zero timeout specified - tc_set_cca_interrupt_callback(&TCC0, ca_cca_callback); - tc_write_cc(&TCC0, TC_CCA, time_seconds-1); - tc_enable_cc_channels(&TCC0, TC_CCAEN); - tc_clear_cc_interrupt(&TCC0, TC_CCA); - tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_MED); + tc_set_cca_interrupt_callback(&EXP_TC0_0, ca_cca_callback); + tc_write_cc(&EXP_TC0_0, TC_CCA, time_seconds-1); + tc_enable_cc_channels(&EXP_TC0_0, TC_CCAEN); + tc_clear_cc_interrupt(&EXP_TC0_0, TC_CCA); + tc_set_cca_interrupt_level(&EXP_TC0_0, TC_INT_LVL_MED); } if (exp_type == POT_OCP) @@ -756,7 +769,7 @@ void pot_experiment(uint16_t time_seconds, uint8_t exp_type){ RTC.CNT=0; PORTD.INTCTRL = PORT_INT0LVL_LO_gc; - TCC0.CNT = 0; + EXP_TC0_0.CNT = 0; while (up !=0){ if (udi_cdc_is_rx_ready()){ @@ -769,9 +782,9 @@ void pot_experiment(uint16_t time_seconds, uint8_t exp_type){ } aborting: - tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_OFF); - tc_write_clock_source(&TCC0, TC_CLKSEL_OFF_gc); - tc_disable(&TCC0); + tc_set_cca_interrupt_level(&EXP_TC0_0, TC_INT_LVL_OFF); + tc_write_clock_source(&EXP_TC0_0, TC_CLKSEL_OFF_gc); + tc_disable(&EXP_TC0_0); volt_exp_stop(); ads1255_standby(); @@ -779,6 +792,23 @@ void pot_experiment(uint16_t time_seconds, uint8_t exp_type){ } #endif +void pmt_idle(void){ + max5443_set_voltage1(65535); + ioport_set_pin_level(PIN_POT_2ELECTRODE, 1); + delay_ms(100); + ioport_set_pin_level(PIN_POT_CE, 1); + + while (1){ + if (udi_cdc_is_rx_ready()){ + if (getchar() == 'a'){ + printf("##ABORT\n\r"); + // Doesn't disconnect control line to minimize time this is floating + return; + } + } + } +} + void ca_experiment(uint16_t steps, uint16_t step_dac[], uint16_t step_seconds[]){ /** * Performs a chronoamperometry experiment. @@ -797,19 +827,19 @@ void ca_experiment(uint16_t steps, uint16_t step_dac[], uint16_t step_seconds[]) portd_int0_callback = portd_int0_ca; //ADC interrupt - tc_enable(&TCC0); - tc_set_cca_interrupt_callback(&TCC0, ca_cca_callback); + tc_enable(&EXP_TC0_0); + tc_set_cca_interrupt_callback(&EXP_TC0_0, ca_cca_callback); ads1255_rdatac(); ads1255_wakeup(); - tc_write_period(&TCC0,0xffff); - tc_write_clock_source(&TCC0, TC_CLKSEL_EVCH0_gc); - tc_set_direction(&TCC0, TC_UP); - tc_enable_cc_channels(&TCC0, TC_CCAEN); - tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_MED); + tc_write_period(&EXP_TC0_0,0xffff); + tc_write_clock_source(&EXP_TC0_0, TC_CLKSEL_EVCH0_gc); + tc_set_direction(&EXP_TC0_0, TC_UP); + tc_enable_cc_channels(&EXP_TC0_0, TC_CCAEN); + tc_set_cca_interrupt_level(&EXP_TC0_0, TC_INT_LVL_MED); - TCC0.CNT = 0; + EXP_TC0_0.CNT = 0; max5443_set_voltage1(step_dac[0]); volt_exp_start(); @@ -817,7 +847,7 @@ void ca_experiment(uint16_t steps, uint16_t step_dac[], uint16_t step_seconds[]) for (uint8_t i = 0; i < steps; ++i) { up = 1; - tc_write_cc(&TCC0, TC_CCA, TCC0.CNT+step_seconds[i]-1); + tc_write_cc(&EXP_TC0_0, TC_CCA, EXP_TC0_0.CNT+step_seconds[i]-1); RTC.CNT=0; max5443_set_voltage1(step_dac[i]); printf("#DAC: %u\n\r", step_dac[i]); @@ -834,9 +864,9 @@ void ca_experiment(uint16_t steps, uint16_t step_dac[], uint16_t step_seconds[]) } aborting: - tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_OFF); - tc_write_clock_source(&TCC0, TC_CLKSEL_OFF_gc); - tc_disable(&TCC0); + tc_set_cca_interrupt_level(&EXP_TC0_0, TC_INT_LVL_OFF); + tc_write_clock_source(&EXP_TC0_0, TC_CLKSEL_OFF_gc); + tc_disable(&EXP_TC0_0); volt_exp_stop(); ads1255_standby(); @@ -851,7 +881,7 @@ static void portd_int0_ca(void){ int32_t current; } data; - data.time1 = TCC0.CNT; + data.time1 = EXP_TC0_0.CNT; data.time2 = RTC.CNT; data.current = ads1255_read_fast24(); @@ -894,16 +924,16 @@ void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h else direction = 0; - tc_enable(&TCF0); - tc_enable(&TCC0); + tc_enable(&EXP_TC0_1); + tc_enable(&EXP_TC0_0); frequency *= 2; //compensate for half-period triggers //calculate time to ADC trigger period = ceil((1/(double)frequency)*F_CPU); uint32_t adc_period = ceil(((1/(double)frequency)-(double)(sample_delay_ms_100div/1e5))*F_CPU); - set_timer_period(period, &TCF0); - set_timer_period(adc_period, &TCC0); + set_timer_period(period, &EXP_TC0_1); + set_timer_period(adc_period, &EXP_TC0_0); ads1255_wakeup(); ads1255_standby(); @@ -911,15 +941,15 @@ void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h volt_exp_start(); do{ - TCF0.CNT = 0; - TCC0.CNT = 0; + EXP_TC0_1.CNT = 0; + EXP_TC0_0.CNT = 0; if (_swv_singledir(dacindex_start, dacindex_stop, dacindex_pulse_height, dacindex_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 - TCF0.CNT = 0; - TCC0.CNT = 0; + 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 goto aborting; } @@ -932,12 +962,12 @@ void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h aborting: volt_exp_stop(); - tc_write_clock_source(&TCF0, TC_CLKSEL_OFF_gc); - tc_disable(&TCF0); - TCF0.CNT = 0; - tc_write_clock_source(&TCC0, TC_CLKSEL_OFF_gc); - tc_disable(&TCC0); - TCC0.CNT = 0; + tc_write_clock_source(&EXP_TC0_1, TC_CLKSEL_OFF_gc); + tc_disable(&EXP_TC0_1); + EXP_TC0_1.CNT = 0; + tc_write_clock_source(&EXP_TC0_0, TC_CLKSEL_OFF_gc); + tc_disable(&EXP_TC0_0); + EXP_TC0_0.CNT = 0; ads1255_standby(); return; @@ -963,10 +993,10 @@ uint8_t _swv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t daci max5443_set_voltage1(dacindex-dacindex_pulse_height); while ((dacindex <= dacindex_stop && direction == 1) || (dacindex >= dacindex_stop && direction == 0)){ - tc_clear_overflow(&TCF0); - tc_clear_overflow(&TCC0); + tc_clear_overflow(&EXP_TC0_1); + tc_clear_overflow(&EXP_TC0_0); - while (!tc_is_overflow(&TCC0)){ //ADC tc overflow + while (!tc_is_overflow(&EXP_TC0_0)){ //ADC tc overflow if (udi_cdc_is_rx_ready()){ //check for abort signal over USB if (getchar() == 'a') return 1; @@ -978,18 +1008,18 @@ uint8_t _swv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t daci forward = ads1255_read_single24(); ads1255_standby(); - while (!tc_is_overflow(&TCF0)); //wait for end of half-cycle - TCC0.CNT = 0; + while (!tc_is_overflow(&EXP_TC0_1)); //wait for end of half-cycle + EXP_TC0_0.CNT = 0; if (direction == 1) //switch voltage to other half of cycle max5443_set_voltage1(dacindex-dacindex_pulse_height); else max5443_set_voltage1(dacindex+dacindex_pulse_height); - tc_clear_overflow(&TCF0); //reset timer OVF - tc_clear_overflow(&TCC0); + tc_clear_overflow(&EXP_TC0_1); //reset timer OVF + tc_clear_overflow(&EXP_TC0_0); - while (!tc_is_overflow(&TCC0)){ //ADC tc overflow + while (!tc_is_overflow(&EXP_TC0_0)){ //ADC tc overflow if (udi_cdc_is_rx_ready()){ //check for abort signal over USB if (getchar() == 'a') return 1; @@ -1001,8 +1031,8 @@ uint8_t _swv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t daci reverse = ads1255_read_single24(); ads1255_standby(); - while (!tc_is_overflow(&TCF0)); //wait for end of half-cycle - TCC0.CNT = 0; + while (!tc_is_overflow(&EXP_TC0_1)); //wait for end of half-cycle + EXP_TC0_0.CNT = 0; lastindex = dacindex; @@ -1062,29 +1092,29 @@ void dpv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h else direction = 0; - tc_enable(&TCF0); - tc_enable(&TCC0); + tc_enable(&EXP_TC0_1); + tc_enable(&EXP_TC0_0); //calculate time to ADC trigger cpu_period = ceil((double)pulse_period*1e-3*F_CPU); uint32_t adc_period = ceil((((double)pulse_period*1e-3)-(double)(sample_delay_ms_100div/1e5))*F_CPU); - uint16_t divider = set_timer_period(cpu_period, &TCF0); - uint16_t adc_divider = set_timer_period(adc_period, &TCC0); + uint16_t divider = set_timer_period(cpu_period, &EXP_TC0_1); + uint16_t adc_divider = set_timer_period(adc_period, &EXP_TC0_0); cpu_width = (double)pulse_width*1e-3*F_CPU; uint32_t adc_width = ceil((((double)pulse_width*1e-3)-(double)(sample_delay_ms_100div/1e5))*F_CPU); - tc_write_cc(&TCF0, TC_CCA, (uint16_t)(cpu_width/divider)); - tc_enable_cc_channels(&TCF0, TC_CCAEN); - tc_write_cc(&TCC0, TC_CCA, (uint16_t)(adc_width/adc_divider)); - tc_enable_cc_channels(&TCC0, TC_CCAEN); + tc_write_cc(&EXP_TC0_1, TC_CCA, (uint16_t)(cpu_width/divider)); + tc_enable_cc_channels(&EXP_TC0_1, TC_CCAEN); + tc_write_cc(&EXP_TC0_0, TC_CCA, (uint16_t)(adc_width/adc_divider)); + tc_enable_cc_channels(&EXP_TC0_0, TC_CCAEN); ads1255_wakeup(); ads1255_standby(); volt_exp_start(); - TCF0.CNT = 0; - TCC0.CNT = 0; + EXP_TC0_1.CNT = 0; + EXP_TC0_0.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 @@ -1093,12 +1123,12 @@ void dpv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_h aborting: volt_exp_stop(); - tc_write_clock_source(&TCF0, TC_CLKSEL_OFF_gc); - tc_disable(&TCF0); - tc_write_clock_source(&TCC0, TC_CLKSEL_OFF_gc); - tc_disable(&TCC0); - TCF0.CNT = 0; - TCC0.CNT = 0; + tc_write_clock_source(&EXP_TC0_1, TC_CLKSEL_OFF_gc); + tc_disable(&EXP_TC0_1); + tc_write_clock_source(&EXP_TC0_0, TC_CLKSEL_OFF_gc); + tc_disable(&EXP_TC0_0); + EXP_TC0_1.CNT = 0; + EXP_TC0_0.CNT = 0; ads1255_standby(); return; @@ -1124,12 +1154,12 @@ uint8_t _dpv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t daci 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); - tc_clear_overflow(&TCC0); - tc_clear_cc_interrupt(&TCC0, TC_CCA); + tc_clear_overflow(&EXP_TC0_1); + tc_clear_cc_interrupt(&EXP_TC0_1, TC_CCA); + tc_clear_overflow(&EXP_TC0_0); + tc_clear_cc_interrupt(&EXP_TC0_0, TC_CCA); - while (!tc_is_cc_interrupt(&TCC0, TC_CCA)){ //wait until ADC TC CCA match + while (!tc_is_cc_interrupt(&EXP_TC0_0, TC_CCA)){ //wait until ADC TC CCA match if (udi_cdc_is_rx_ready()){ //check for abort signal over USB if (getchar() == 'a') return 1; @@ -1141,12 +1171,12 @@ uint8_t _dpv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t daci forward = ads1255_read_single24(); ads1255_standby(); - while (!tc_is_cc_interrupt(&TCF0, TC_CCA)); //wait for end of half-cycle + while (!tc_is_cc_interrupt(&EXP_TC0_1, TC_CCA)); //wait for end of half-cycle //switch voltage to baseline max5443_set_voltage1(dacindex); - while (!tc_is_overflow(&TCC0)){ //wait for ADC TC overflow + while (!tc_is_overflow(&EXP_TC0_0)){ //wait for ADC TC overflow if (udi_cdc_is_rx_ready()){ if (getchar() == 'a') return 1; @@ -1158,8 +1188,8 @@ uint8_t _dpv_singledir (uint16_t dacindex, uint16_t dacindex_stop, uint16_t daci reverse = ads1255_read_single24(); ads1255_standby(); - while (!tc_is_overflow(&TCF0)); //wait for end of half-cycle - TCC0.CNT = 0; // Resync ADC TC + while (!tc_is_overflow(&EXP_TC0_1)); //wait for end of half-cycle + EXP_TC0_0.CNT = 0; // Resync ADC TC lastindex = dacindex; diff --git a/DSTAT/src/experiment.h b/DSTAT/src/experiment.h index 7c171aea2be798167f29b4689a9807aecced69b7..67c1801e553295fea271d316824d739fda7427cd 100644 --- a/DSTAT/src/experiment.h +++ b/DSTAT/src/experiment.h @@ -45,6 +45,11 @@ #define POT_GAIN_100M 7 #endif +#define PIN_POT_CE IOPORT_CREATE_PIN(PORTB,5) +#define PIN_POT_2ELECTRODE IOPORT_CREATE_PIN(PORTB,3) +#define PIN_POT_CTRL IOPORT_CREATE_PIN(PORTB,2) +#define PIN_POT_WE IOPORT_CREATE_PIN(PORTB,4) + #define POT_OCP 0 #define POT_POTENT 1 @@ -72,10 +77,15 @@ #define RTC_COMPARE_INT_LEVEL RTC_COMPINTLVL_HI_gc +#define EXP_TC0_0 TCC0 +#define EXP_TC1_0 TCC1 +#define EXP_TC0_1 TCF0 + extern uint16_t g_gain; extern uint8_t g_short; extern uint8_t autogain_enable; +uint16_t set_timer_period(uint32_t period, volatile void *tc); void experiment_handler(char command); void pot_init(void); void pot_set_gain(void); diff --git a/DSTAT/src/main.c b/DSTAT/src/main.c index c7e5c687ef0e8ef2f30b44c0690450eeecb38ad3..92089f10b1152e6d126014be079266ce6564260c 100644 --- a/DSTAT/src/main.c +++ b/DSTAT/src/main.c @@ -9,6 +9,7 @@ #include "asf.h" #include "settings.h" #include "tcs.h" +#include "shutter.h" #include <string.h> #include <math.h> #include <stdint.h> @@ -23,6 +24,8 @@ int8_t command_handler(char command){ * Calls functions in * @param command Command character input. */ + + double p1; switch (command){ case 'E': //Experiment options @@ -44,6 +47,23 @@ int8_t command_handler(char command){ printf("T%u.%u.%u.%u\n\r", tcs_data[0], tcs_data[1], tcs_data[2], tcs_data[3]); } break; + + case 'Z': //Test shutter + scanf("%lg",&p1); + shutter_cont(p1); + break; + + case 'z': + shutter_cont_stop(); + break; + + case '1': + shutter_close(); + break; + + case '2': + shutter_open(); + break; case 'V': //check version printf("V%u.%u\n\r", BOARD_VER_MAJOR, BOARD_VER_MINOR); @@ -100,7 +120,7 @@ int main(void){ settings_read_eeprom(); -// Wait for application connection - Get 'c', reply 'K', get 'k' + // Wait for application connection - Get 'c', reply 'K', get 'k' while(1){ while(getchar() != 'c'); putchar('#'); @@ -110,7 +130,7 @@ int main(void){ } tcs_init(); - + shutter_init(); program_loop: while(getchar() != '!'); diff --git a/DSTAT/src/max5443.c b/DSTAT/src/max5443.c index b36b22a2eb285d8c9a6f96bdd57173c68544ba18..3ff7e9cd43cec7ba0138715bb4f2672756bc9426 100644 --- a/DSTAT/src/max5443.c +++ b/DSTAT/src/max5443.c @@ -20,8 +20,8 @@ struct usart_spi_device spi_device_conf_c = { }; void max5443_init_pins(void){ - arch_ioport_set_port_dir(IOPORT_PORTC, PIN4_bm|PIN5_bm|PIN7_bm, IOPORT_DIR_OUTPUT); - arch_ioport_set_port_level(IOPORT_PORTC, PIN4_bm|PIN5_bm|PIN7_bm, PIN4_bm|PIN5_bm|PIN7_bm); + ioport_set_port_dir(IOPORT_PORTC, PIN4_bm|PIN5_bm|PIN7_bm, IOPORT_DIR_OUTPUT); + ioport_set_port_level(IOPORT_PORTC, PIN4_bm|PIN5_bm|PIN7_bm, PIN4_bm|PIN5_bm|PIN7_bm); } void max5443_init_module(void){ diff --git a/DSTAT/src/settings.c b/DSTAT/src/settings.c index b68b37ce842ecc4be209358f07b09bb80a362bb2..ac6e6ad5540ee4832d8810d6a62debb06dc57cef 100644 --- a/DSTAT/src/settings.c +++ b/DSTAT/src/settings.c @@ -51,8 +51,8 @@ void settings_read_eeprom(void){ settings_restore_defaults(); } printf("#INFO: max5443_offset = %u\n\r", settings.settings.max5443_offset); - printf("#INFO: tls_enabled = %u\n\r", settings.settings.tcs_enabled); - printf("#INFO: tls_clear_threshold = %u\n\r", settings.settings.tcs_clear_threshold); + printf("#INFO: tcs_enabled = %u\n\r", settings.settings.tcs_enabled); + printf("#INFO: tcs_clear_threshold = %u\n\r", settings.settings.tcs_clear_threshold); printf("#INFO: r100_trim = %i\n\r", settings.settings.r100_trim); printf("#INFO: r3k_trim = %i\n\r", settings.settings.r3k_trim); printf("#INFO: r30k_trim = %i\n\r", settings.settings.r30k_trim); diff --git a/DSTAT/src/shutter.c b/DSTAT/src/shutter.c new file mode 100644 index 0000000000000000000000000000000000000000..1c8a4ac0cbacb47d001711f400ea84dd016d2ed7 --- /dev/null +++ b/DSTAT/src/shutter.c @@ -0,0 +1,71 @@ +// +// shutter.c +// dstat-firmware +// +// Created by Michael Dryden on 2016-01-27. +// Copyright © 2016 wheeler lab. All rights reserved. +// + +#include "shutter.h" +#include <stdint.h> +#include <tc.h> +#include <math.h> + +void shutter_init(void){ + ioport_set_pin_dir(SHUTTER_PIN, IOPORT_DIR_OUTPUT); + ioport_set_pin_level(SHUTTER_PIN, 0); +} + +void shutter_open(void){ + ioport_set_pin_level(SHUTTER_PIN, 1); +} + +void shutter_close(void){ + ioport_set_pin_level(SHUTTER_PIN, 0); +} + +uint8_t shutter_cont(double freq){ + tc_write_clock_source(&SHUTTER_TC, TC_CLKSEL_OFF_gc); + if (freq > 30 || freq < 0.23842) { + return 1; + } + + else{ + tc_enable(&SHUTTER_TC); + tc_set_wgm(&SHUTTER_TC, TC_WG_FRQ); + tc_enable_cc_channels(&SHUTTER_TC, TC_CCAEN); + + tc_write_clock_source(&SHUTTER_TC, TC_CLKSEL_DIV64_gc); + + uint16_t temp_div = ceil((1/(2*freq))*F_CPU/65536); + uint16_t divider = 0; + + if (temp_div <= 64){ + tc_write_clock_source(&SHUTTER_TC,TC_CLKSEL_DIV64_gc); + divider = 64; + } + else if (temp_div <= 256){ + tc_write_clock_source(&SHUTTER_TC,TC_CLKSEL_DIV256_gc); + divider = 256; + } + else if (temp_div <= 1024){ + tc_write_clock_source(&SHUTTER_TC,TC_CLKSEL_DIV1024_gc); + divider = 1024; + } + else{ + printf("#ERR: Frequency/ADC rate is too low\n\r"); + return 0; + } + + SHUTTER_TC.CCA = ((uint16_t)((F_CPU/divider)/(2*freq)))-1; //f=1/(2*(CCA+1)*f_clk) + + return 0; + } +} + +void shutter_cont_stop(void){ + tc_write_clock_source(&SHUTTER_TC, TC_CLKSEL_OFF_gc); + tc_set_wgm(&SHUTTER_TC, TC_WG_NORMAL); + tc_disable(&SHUTTER_TC); + ioport_set_pin_level(SHUTTER_PIN, 0); +} \ No newline at end of file diff --git a/DSTAT/src/shutter.h b/DSTAT/src/shutter.h new file mode 100644 index 0000000000000000000000000000000000000000..c1ba5dd7cd68749551c0508c0a80d74941d79690 --- /dev/null +++ b/DSTAT/src/shutter.h @@ -0,0 +1,24 @@ +// +// shutter.h +// dstat-firmware +// +// Created by Michael Dryden on 2016-01-27. +// Copyright © 2016 wheeler lab. All rights reserved. +// + +#ifndef shutter_h +#define shutter_h + +#include <stdio.h> +#include <ioport.h> + +#define SHUTTER_PIN IOPORT_CREATE_PIN(PORTE,0) +#define SHUTTER_TC TCE0 + +void shutter_init(void); +void shutter_open(void); +void shutter_close(void); +uint8_t shutter_cont(double freq); +void shutter_cont_stop(void); + +#endif /* shutter_h */