Newer
Older
Michael DM Dryden
committed
/*
* experiment.c
*
* Created: 01/10/2012 10:59:48 PM
* Author: mdryden
*/
Michael DM Dryden
committed
/**
* @file experiment.c
* @author Michael DM Dryden <mdryden@chem.utoronto.ca>
* @version 1.0
*
*
* @section DESCRIPTION
*
* Contains Functions for performing experiments and adjusting potentiostat settings other than DAC and ADC.
*/
Michael DM Dryden
committed
#include "experiment.h"
Michael DM Dryden
committed
//Public variable definitions
uint8_t g_gain = POT_GAIN_30k;
uint8_t autogain_enable = 1;
Michael DM Dryden
committed
//Private variables
volatile int32_t voltage = 0;
volatile uint16_t dacindex = 0;
uint16_t dacindex_stop = 0;
volatile int8_t up = 1;
volatile uint16_t iter = 0;
uint16_t* eis_ptr = 0;
volatile uint16_t cycles = 0;
volatile uint16_t samples = 0;
volatile uint16_t tcf0period = 0;
uint32_t skip_samples = 0;
//Private function declarations
static void porte_int0_lsv(void);
static void tcf0_ovf_callback(void);
static void tce1_ovf_callback_lsv(void);
static void lsv_cca_callback(void);
Michael DM Dryden
committed
static void ca_cca_callback(void);
static void portd_int0_ca(void);
Michael DM Dryden
committed
//interrupt callback setup
typedef void (*port_callback_t) (void);
static port_callback_t portd_int0_callback;
static port_callback_t portd_int1_callback;
void pot_init(void){
Michael DM Dryden
committed
/**
* Initializes AVR port directions and levels
*
* @return Nothing.
*/
Michael DM Dryden
committed
arch_ioport_set_port_dir(IOPORT_PORTB, PIN3_bm|PIN4_bm|PIN5_bm|PIN6_bm|PIN7_bm, IOPORT_DIR_OUTPUT);
arch_ioport_set_port_dir(IOPORT_PORTD, PIN4_bm, IOPORT_DIR_OUTPUT);
arch_ioport_set_port_level(IOPORT_PORTB, PIN3_bm|PIN4_bm|PIN5_bm|PIN6_bm|PIN7_bm, PIN6_bm|PIN7_bm);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, PIN4_bm);
}
int8_t autogainswitch(void){
Michael DM Dryden
committed
/**
* Automatic gain switching.
*
* Reads last samples from over_under var from ads1255.h and changes gain if more than ADS_OVER_UNDER_SAMPLES off scale.
* Uses g_gain global variable.
* @return 0 when no switch occurs (due to hysteresis internal static var or if 500M resistor chosen). 1 if gain switch.
*/
Michael DM Dryden
committed
//Need to change this to set variable max/min gains
Michael DM Dryden
committed
extern int8_t over_under[ADS_OVER_UNDER_SAMPLES]; //from ads1255.h
int8_t overcurrent = 0;
static uint8_t hysteresis = 0;
static uint8_t last_return = 0;
Michael DM Dryden
committed
if (autogain_enable == 0)
return 0;
Michael DM Dryden
committed
if (g_gain == POT_GAIN_500M)
Michael DM Dryden
committed
return 0;
Michael DM Dryden
committed
if (last_return==1){
Michael DM Dryden
committed
last_return=0;
return 1;
}
if (hysteresis < ADS_OVER_UNDER_SAMPLES-1){
++hysteresis;
return 0;
}
for (uint16_t i = 0; i < ADS_OVER_UNDER_SAMPLES; ++i)
overcurrent += over_under[i];
Michael DM Dryden
committed
if (overcurrent == ADS_OVER_UNDER_SAMPLES && g_gain > POT_GAIN_100){
Michael DM Dryden
committed
--g_gain;
Michael DM Dryden
committed
pot_set_gain();
last_return=1;
hysteresis = 0;
for (uint16_t i = 0; i < ADS_OVER_UNDER_SAMPLES; ++i)
Michael DM Dryden
committed
over_under[i]=0;
Michael DM Dryden
committed
return 1;
}
Michael DM Dryden
committed
if ((overcurrent*-1) == (ADS_OVER_UNDER_SAMPLES) && g_gain < POT_GAIN_3M){
Michael DM Dryden
committed
if (hysteresis < ADS_OVER_UNDER_SAMPLES+3){
++hysteresis;
return 0;
}
Michael DM Dryden
committed
++g_gain;
Michael DM Dryden
committed
pot_set_gain();
last_return=1;
hysteresis = 0;
for (uint16_t i = 0; i < ADS_OVER_UNDER_SAMPLES; ++i)
over_under[i]=0;
return 1;
}
Michael DM Dryden
committed
Michael DM Dryden
committed
hysteresis = 0;
return 0;
}
void pot_set_gain(void){
Michael DM Dryden
committed
/**
* Sets iV gain according to current g_gain value
*
* @return Nothing.
*/
switch (g_gain){
Michael DM Dryden
committed
case POT_GAIN_500M:
arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, 0);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, 0);
Michael DM Dryden
committed
printf("#INFO: 500M\n\r");
Michael DM Dryden
committed
break;
case POT_GAIN_30M:
arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN6_bm);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, 0);
Michael DM Dryden
committed
printf("#INFO: 30M\n\r");
Michael DM Dryden
committed
break;
Michael DM Dryden
committed
case POT_GAIN_3M:
Michael DM Dryden
committed
arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN7_bm);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, 0);
Michael DM Dryden
committed
printf("#INFO: 3M\n\r");
Michael DM Dryden
committed
break;
case POT_GAIN_300k:
arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN6_bm|PIN7_bm);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, 0);
Michael DM Dryden
committed
printf("#INFO: 300k\n\r");
Michael DM Dryden
committed
break;
case POT_GAIN_30k:
arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, 0);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, PIN4_bm);
Michael DM Dryden
committed
printf("#INFO: 30k\n\r");
Michael DM Dryden
committed
break;
case POT_GAIN_3k:
arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN6_bm);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, PIN4_bm);
Michael DM Dryden
committed
printf("#INFO: 3k\n\r");
Michael DM Dryden
committed
break;
case POT_GAIN_300:
arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN7_bm);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, PIN4_bm);
Michael DM Dryden
committed
printf("#INFO: 300\n\r");
Michael DM Dryden
committed
break;
case POT_GAIN_100:
arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN6_bm|PIN7_bm);
arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, PIN4_bm);
Michael DM Dryden
committed
printf("#INFO: 100\n\r");
Michael DM Dryden
committed
break;
default:
Michael DM Dryden
committed
printf("#WAR: Invalid pot gain.\n\r");
Michael DM Dryden
committed
break;
return;
}
}
void pot_exp_start(void){
Michael DM Dryden
committed
/**
* Connects measurement cell to rest of circuit.
*/
Michael DM Dryden
committed
arch_ioport_set_port_level(IOPORT_PORTB, PIN3_bm|PIN4_bm|PIN5_bm, PIN3_bm|PIN4_bm|PIN5_bm);
}
void pot_exp_stop(void){
Michael DM Dryden
committed
/**
* Disconnects measurement cell and shorts RE and CE terminals.
*/
Michael DM Dryden
committed
arch_ioport_set_port_level(IOPORT_PORTB, PIN3_bm|PIN4_bm|PIN5_bm, 0);
}
void cv_experiment(int16_t v1, int16_t v2, int16_t start, uint8_t scans, uint16_t slope){
Michael DM Dryden
committed
/**
* 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 scans Number of scans.
* @param slope Scan rate in mV/s.
*/
Michael DM Dryden
committed
// check if start is [v1,v2]
int8_t firstrun = 1;
Michael DM Dryden
committed
if((start < v1 && start < v2) || (start > v1 && start > v2)){
Michael DM Dryden
committed
printf("ERR: Start must be within [v1, v2]\n\r");
return;
}
// RTC.CTRL = RTC_PRESCALER_OFF_gc;
// while (RTC.STATUS & RTC_SYNCBUSY_bm);
// RTC.CNT = 0;
// RTC.PER = 0xffff;
// RTC.CTRL = RTC_PRESCALER_DIV1024_gc; // 1 s tick
Michael DM Dryden
committed
while(scans > 0){
if (start != v1){
lsv_experiment(start,v1,slope,firstrun);
firstrun = 0;
}
if (start == v2 && scans == 1)
firstrun = -1;
lsv_experiment(v1,v2,slope,firstrun);
if (scans == 1)
firstrun = -1;
if (start != v2)
lsv_experiment(v2,start,slope,firstrun);
--scans;
firstrun = 0;
}
// printf("Time: %lu s \n\r", rtc_get_time());
Michael DM Dryden
committed
return;
}
void lsv_experiment(int16_t start, int16_t stop, uint16_t slope, int8_t first_run){
Michael DM Dryden
committed
/**
* 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 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.
*/
Michael DM Dryden
committed
//check experiment limits
Michael DM Dryden
committed
if(start<-1500 || start>=1500 ||start==stop|| stop<-1500 || stop>=1500 || slope>7000)
Michael DM Dryden
committed
{
printf("ERR: Experiment parameters outside limits\n\r");
return;
}
Michael DM Dryden
committed
uint16_t dacindex_start = ceil(start*(65536/(double)3000)+32768);
dacindex_stop = ceil(stop*(65536/(double)3000)+32768);
Michael DM Dryden
committed
// uint16_t period;
uint32_t timer_period;
uint16_t temp_div;
max5443_set_voltage1(dacindex_start);
if (first_run == 1 || first_run == 2){
pot_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);
Michael DM Dryden
committed
portd_int0_callback = porte_int0_lsv; //ADC read
Michael DM Dryden
committed
//set EVCH0 event
EVSYS.CH0MUX = EVSYS_CHMUX_TCC0_OVF_gc;
EVSYS.CH0CTRL = 0;
Michael DM Dryden
committed
timer_period = ceil(1/((double)slope/(3000./65536))*(F_CPU));
temp_div = ceil(timer_period/65536.);
Michael DM Dryden
committed
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
if (temp_div <= 1)
tc_write_clock_source(&TCC0,TC_CLKSEL_DIV1_gc);
else if (temp_div == 2){
tc_write_clock_source(&TCC0,TC_CLKSEL_DIV2_gc);
timer_period /= 2;
}
else if (temp_div <= 4){
tc_write_clock_source(&TCC0,TC_CLKSEL_DIV4_gc);
timer_period /= 4;
}
else if (temp_div <= 8){
tc_write_clock_source(&TCC0,TC_CLKSEL_DIV8_gc);
timer_period /= 8;
}
else if (temp_div <= 64){
tc_write_clock_source(&TCC0,TC_CLKSEL_DIV64_gc);
timer_period /= 64;
}
else if (temp_div <= 256){
tc_write_clock_source(&TCC0,TC_CLKSEL_DIV256_gc);
timer_period /= 256;
}
else if (temp_div <= 1024){
tc_write_clock_source(&TCC0,TC_CLKSEL_DIV1024_gc);
timer_period /= 1024;
}
else{
printf("ERR: Frequency/ADC rate is too low\n\r");
return;
}
Michael DM Dryden
committed
//printf("Period:%lu\n\r", timer_period);
Michael DM Dryden
committed
ads1255_wakeup();
tc_write_period(&TCC1, 0xffff);
tc_write_period(&TCC0, (uint16_t)timer_period);
}
TCC1.CNT = dacindex_start;
if (stop > start)
{
up = 1;
tc_set_direction(&TCC1, TC_UP);
}
else
{
up = -1;
tc_set_direction(&TCC1, TC_DOWN);
}
tc_write_cc(&TCC1, TC_CCA, dacindex_stop);
tc_enable_cc_channels(&TCC1, TC_CCAEN);
TCC0.CNT = 0;
Michael DM Dryden
committed
tc_set_cca_interrupt_level(&TCC1, TC_INT_LVL_HI); //Stop experiment
Michael DM Dryden
committed
tc_set_overflow_interrupt_level(&TCC0, TC_OVFINTLVL_LO_gc); //Set DAC
PORTD.INTCTRL = PORT_INT0LVL_MED_gc; //ADC read
Michael DM Dryden
committed
tc_write_clock_source(&TCC1, TC_CLKSEL_EVCH0_gc);
while (up != 0); //Experiment run with interrupts
if (first_run == -1 || first_run == 2)
{
tc_disable(&TCC0);
TCC0.CNT = 0x0;
tc_disable(&TCC1);
pot_exp_stop();
ads1255_standby();
}
return;
}
static void porte_int0_lsv(void){
Michael DM Dryden
committed
/**
* ISR for taking LSV measurements.
*/
Michael DM Dryden
committed
int32_t result;
if (autogain_enable == 0){
// while (arch_ioport_get_pin_level(IOPORT_CREATE_PIN(PORTD, 5)));
result=ads1255_read_fast24();
goto noauto;
}
else{
Michael DM Dryden
committed
while (arch_ioport_get_pin_level(IOPORT_CREATE_PIN(PORTD, 5)));
Michael DM Dryden
committed
result=ads1255_read();
}
if (autogainswitch()==0){
noauto:
// if (g_gain == POT_GAIN_300)
// printf("%u %ld\n\r", TCC1.CNT,result);
// else if (g_gain == POT_GAIN_3k)
// printf("%u %ld\n\r", TCC1.CNT, result);
// else if (g_gain == POT_GAIN_30k)
// printf("%u %ld000\n\r", TCC1.CNT, result);
// else if (g_gain == POT_GAIN_300k)
// printf("%u %ld00\n\r", TCC1.CNT, result);
// else if (g_gain == POT_GAIN_3M)
// printf("%u %ld0\n\r", TCC1.CNT, result);
// else if (g_gain == POT_GAIN_30M)
// printf("%u %ld\n\r", TCC1.CNT, result);
// else
Michael DM Dryden
committed
printf("%u %ld\n\r", TCC1.CNT, result);
Michael DM Dryden
committed
}
Michael DM Dryden
committed
Michael DM Dryden
committed
return;
Michael DM Dryden
committed
}
static void tcf0_ovf_callback(void){
max5443_set_voltage1(TCC1.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);
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);
up = 0;
return;
Michael DM Dryden
committed
}
void chronoamp(uint16_t steps, uint16_t step_dac[], uint16_t step_seconds[]){
Michael DM Dryden
committed
/**
* Performs a chronoamperometry experiment.
*
* @param steps Total number of steps.
* @param step_dac[] Array containing DAC indices.
* @param step_seconds[] Array containing step durations in seconds.
*/
Michael DM Dryden
committed
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
while (RTC.STATUS & RTC_SYNCBUSY_bm);
RTC.PER = 999;
while (RTC.STATUS & RTC_SYNCBUSY_bm);
RTC.CTRL = RTC_PRESCALER_DIV1_gc;
EVSYS.CH0MUX = EVSYS_CHMUX_RTC_OVF_gc;
portd_int0_callback = portd_int0_ca;
tc_enable(&TCC0);
tc_set_cca_interrupt_callback(&TCC0, 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_HI);
TCC0.CNT = 0;
pot_exp_start();
for (uint8_t i = 0; i < steps; ++i)
{
up = 1;
tc_write_cc(&TCC0, TC_CCA, TCC0.CNT+step_seconds[i]-1);
RTC.CNT=0;
max5443_set_voltage1(step_dac[i]);
//PORTE.INTCTRL = PORT_INT0LVL_LO_gc;
PORTD.INTCTRL = PORT_INT0LVL_LO_gc;
while (up !=0);
}
tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_OFF);
tc_write_clock_source(&TCC0, TC_CLKSEL_OFF_gc);
tc_disable(&TCC0);
pot_exp_stop();
ads1255_standby();
return;
}
static void portd_int0_ca(void){
if (autogainswitch()==0){
//while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTE, 3)));
while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTD, 5)));
Michael DM Dryden
committed
if (g_gain == POT_GAIN_300)
Michael DM Dryden
committed
printf("%u, %ld00000\n\r", TCC1.CNT, ads1255_read());
Michael DM Dryden
committed
else if (g_gain == POT_GAIN_3k)
Michael DM Dryden
committed
printf("%u, %ld0000\n\r", TCC1.CNT, ads1255_read());
Michael DM Dryden
committed
else if (g_gain == POT_GAIN_30k)
Michael DM Dryden
committed
printf("%u, %ld000\n\r", TCC1.CNT, ads1255_read());
Michael DM Dryden
committed
else if (g_gain == POT_GAIN_300k)
Michael DM Dryden
committed
printf("%u, %ld00\n\r", TCC1.CNT, ads1255_read());
Michael DM Dryden
committed
else if (g_gain == POT_GAIN_3M)
Michael DM Dryden
committed
printf("%u, %ld0\n\r", TCC1.CNT, ads1255_read());
Michael DM Dryden
committed
else if (g_gain == POT_GAIN_30M)
Michael DM Dryden
committed
printf("%u, %ld\n\r", TCC1.CNT, ads1255_read());
else
printf("%u, %lu\n\r", TCC1.CNT, ads1255_read());
}
else{
//while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTE, 3)));
while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTD, 5)));
ads1255_read();
}
}
static void ca_cca_callback(void){
//PORTE.INTCTRL = PORT_INT0LVL_OFF_gc;
PORTD.INTCTRL = PORT_INT0LVL_OFF_gc;
up = 0;
return;
}
void swv_experiment(int16_t start, int16_t stop, uint16_t step, uint16_t pulse_height, uint16_t frequency){
Michael DM Dryden
committed
/**
* 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 frequency Frequency in Hz.
*/
Michael DM Dryden
committed
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
//check experiment limits
// if((start-pulse_height)<-1500 || (start+pulse_height)>(1500)|| start == stop || stop<-1500 || (stop+pulse_height)>1500 || step<1 || step>1500 || pulse_height > 1500 || pulse_height < 1)
// {
// printf("ERR: Experiment parameters outside limits\n\r");
// //return;
// }
int32_t forward = 0;
int32_t reverse = 0;
int32_t data_buffer;
uint8_t direction;
uint16_t dacindex_start = ceil((start)*(65535/(double)3000))+32767;
uint16_t dacindex_stop = ceil(stop*(65535/(double)3000))+32767;
uint16_t dacindex_step = ceil(step*(65535/(double)3000));
uint16_t dacindex_pulse_height = ceil(pulse_height*(65535/(double)3000));
uint16_t dacindex = dacindex_start;
uint32_t period;
int16_t fgain = -1;
int16_t rgain = -1;
if (start < stop)
direction = 1;
else
direction = 0;
tc_enable(&TCF0);
frequency *= 2; //compensate for half-period triggers
//calculate time to ADC trigger
period = ceil((1/(double)frequency)*F_CPU);
uint8_t temp_div = ceil((double)period/UINT16_MAX);
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);
period /= 2;
}
else if (temp_div <= 4){
tc_write_clock_source(&TCF0,TC_CLKSEL_DIV4_gc);
period /= 4;
}
else if (temp_div <= 8){
tc_write_clock_source(&TCF0,TC_CLKSEL_DIV8_gc);
period /= 8;
}
else if (temp_div <= 64){
tc_write_clock_source(&TCF0,TC_CLKSEL_DIV64_gc);
period /= 64;
}
else if (temp_div <= 256){
tc_write_clock_source(&TCF0,TC_CLKSEL_DIV256_gc);
period /= 256;
}
else if (temp_div <= 1024){
tc_write_clock_source(&TCF0,TC_CLKSEL_DIV1024_gc);
period /= 1024;
}
else{
printf("Frequency/ADC rate is too low\n\r");
return;
}
tc_write_period(&TCF0, (uint16_t)period);
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();
TCF0.CNT = 0;
while ((dacindex <= dacindex_stop && direction == 1) || (dacindex >= dacindex_stop && direction == 0)){
tc_clear_overflow(&TCF0);
if (fgain > -1)
//printf("%u, %li, %li\n\r", dacindex, forward*fgain, reverse*rgain);
printf("%u, %li%0*lu, %li%0*lu\n\r", dacindex, fgain, 0, forward, rgain, 0, reverse);
forward = 0;
reverse = 0;
while (!tc_is_overflow(&TCF0)){
autogainswitch();
Michael DM Dryden
committed
if (g_gain <= POT_GAIN_30M)
Michael DM Dryden
committed
fgain = 0;
else
Michael DM Dryden
committed
fgain = g_gain-1;
Michael DM Dryden
committed
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
while (ioport_pin_is_low(IOPORT_CREATE_PIN(PORTD, 5)));
while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTD, 5)));
// while (ioport_pin_is_low(IOPORT_CREATE_PIN(PORTE, 3)));
// while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTE, 3)));
// forward = ads1255_read_fast24();
forward = ads1255_read();
}
if (direction == 1)
max5443_set_voltage1(dacindex-dacindex_pulse_height);
else
max5443_set_voltage1(dacindex+dacindex_pulse_height);
tc_clear_overflow(&TCF0);
if (direction == 1)
dacindex += dacindex_step;
else
dacindex -= dacindex_step;
while (!tc_is_overflow(&TCF0)){
autogainswitch();
Michael DM Dryden
committed
if (g_gain <= POT_GAIN_30M)
Michael DM Dryden
committed
rgain = 0;
else
Michael DM Dryden
committed
rgain = g_gain-1;
Michael DM Dryden
committed
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
while (ioport_pin_is_low(IOPORT_CREATE_PIN(PORTD, 5)));
while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTD, 5)));
// while (ioport_pin_is_low(IOPORT_CREATE_PIN(PORTE, 3)));
// while (ioport_pin_is_high(IOPORT_CREATE_PIN(PORTE, 3)));
// reverse = ads1255_read_fast24();
reverse = ads1255_read();
}
if (direction == 1)
max5443_set_voltage1(dacindex+dacindex_pulse_height);
else
max5443_set_voltage1(dacindex-dacindex_pulse_height);
}
pot_exp_stop();
tc_write_clock_source(&TCF0, TC_CLKSEL_OFF_gc);
tc_disable(&TCF0);
tc_write_count(&TCF0,0);
ads1255_standby();
return;
}
ISR(PORTD_INT0_vect){
if (portd_int0_callback) {
portd_int0_callback();
}
}