Skip to content
experiment.c 26.9 KiB
Newer Older
/*
 * experiment.c
 *
 * Created: 01/10/2012 10:59:48 PM
 *  Author: mdryden
 */ 
/**
 * @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.
 */
//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 precond_rtc_callback(uint32_t time);
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);
static void lsv_dma_callback(void);
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);

static port_callback_t portd_int0_callback;
static port_callback_t portd_int1_callback;

void send_data_uint16(uint16_t data){
	/**
	 * Sends uint16 data over USB in order in memory (should be LSB first for AVR - little endian)
	 *
	 * @param data 16-bit data
	 * @return Nothing.
	 */
	udi_cdc_putc(((unsigned char *)(&data))[0]);
	udi_cdc_putc(((unsigned char *)(&data))[1]);
}
void send_data_int32(int32_t data){
	/**
	 * Sends int32 data over USB in order in memory (should be LSB first for AVR - little endian)
	 *
	 * @param data 32-bit data
	 * @return Nothing.
	 */
	udi_cdc_putc(((unsigned char *)(&data))[0]);
	udi_cdc_putc(((unsigned char *)(&data))[1]);
	udi_cdc_putc(((unsigned char *)(&data))[2]);
	udi_cdc_putc(((unsigned char *)(&data))[3]);
}

	/**
	 * Initializes AVR port directions and levels
	 *
	 * @return Nothing.
	 */
Michael DM Dryden's avatar
Michael DM Dryden committed
	#if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR == 1
		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);
	#endif
	#if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR == 2
		arch_ioport_set_port_dir(IOPORT_PORTB, PIN2_bm|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, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm|PIN6_bm|PIN7_bm, PIN3_bm|PIN6_bm|PIN7_bm);
		arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, PIN4_bm);
	#endif
	/**
	 * Sets iV gain according to current g_gain value
	 *
	 * @return Nothing.
	 */
	switch (g_gain){
Michael DM Dryden's avatar
Michael DM Dryden committed
		#if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR == 1
			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's avatar
Michael DM Dryden committed
				printf("#INFO: 500M\n\r");
				break;
Michael DM Dryden's avatar
Michael DM Dryden committed
			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);
				printf("#INFO: 30M\n\r");
				break;
Michael DM Dryden's avatar
Michael DM Dryden committed
			case POT_GAIN_3M:	
				arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN7_bm);
				arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, 0);
				printf("#INFO: 3M\n\r");
				break;
Michael DM Dryden's avatar
Michael DM Dryden committed
			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);
				printf("#INFO: 300k\n\r");
				break;
Michael DM Dryden's avatar
Michael DM Dryden committed
			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);
				printf("#INFO: 30k\n\r");
				break;
Michael DM Dryden's avatar
Michael DM Dryden committed
			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);
				printf("#INFO: 3k\n\r");
				break;
Michael DM Dryden's avatar
Michael DM Dryden committed
			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);
				printf("#INFO: 300\n\r");
				break;
Michael DM Dryden's avatar
Michael DM Dryden committed
			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);
				printf("#INFO: 100\n\r");
				break;
		#endif
		
		#if BOARD_VER_MAJOR == 1 && BOARD_VER_MINOR == 2
			case POT_GAIN_100M:
				arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, 0);
				arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, 0);
				printf("#INFO: 100M\n\r");
				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);
				printf("#INFO: 30M\n\r");
				break;
				
			case POT_GAIN_3M:
				arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN7_bm);
				arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, 0);
				printf("#INFO: 3M\n\r");
				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);
				printf("#INFO: 300k\n\r");
				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);
				printf("#INFO: 30k\n\r");
				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);
				printf("#INFO: 3k\n\r");
				break;
				
			case POT_GAIN_0:
				arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN7_bm);
				arch_ioport_set_port_level(IOPORT_PORTD, PIN4_bm, PIN4_bm);
				printf("#INFO: 0\n\r");
				break;
				
			case POT_GAIN_100:
				arch_ioport_set_port_level(IOPORT_PORTB, PIN6_bm|PIN7_bm, PIN6_bm|PIN7_bm);
Loading full blame...