diff --git a/DSTAT/src/experiment.c b/DSTAT/src/experiment.c index 857f8a59639930eec9fd028562b3f531c59fc9e3..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); @@ -144,10 +144,11 @@ 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 (unless 0 or saturated) - if (tcs_data[3] == tcs_data1[3]){ - if (!(tcs_data[3] == 0 || tcs_data[3] == 65535)) { + 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; } @@ -573,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 @@ -622,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){ @@ -665,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; @@ -689,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"); @@ -701,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; } @@ -739,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) @@ -769,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()){ @@ -782,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(); @@ -827,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(); @@ -847,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]); @@ -864,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(); @@ -881,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(); @@ -924,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(); @@ -941,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; } @@ -962,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; @@ -993,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; @@ -1008,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; @@ -1031,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; @@ -1092,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 @@ -1123,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; @@ -1154,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; @@ -1171,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; @@ -1188,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 f9db411e96c5248939908322f4d58936650d45c6..67c1801e553295fea271d316824d739fda7427cd 100644 --- a/DSTAT/src/experiment.h +++ b/DSTAT/src/experiment.h @@ -77,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 d95289e287d809dc444c9630538be90510e32cb8..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); @@ -110,7 +130,7 @@ int main(void){ } tcs_init(); - + shutter_init(); program_loop: while(getchar() != '!'); 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 */