예제 #1
0
파일: code.c 프로젝트: eSenpai/atmega
//Sends a clock pulse on ST_CP line
void HC595Latch(void){
    //Pulse the Store Clock
    HC595_PORT |= (1 << HC595_ST_CP_POS);//HIGH
    _delay_loop_1(1);
    HC595_PORT &= (~(1 << HC595_ST_CP_POS));//LOW
    _delay_loop_1(1);
}
예제 #2
0
int tw_recv_byte(uint8_t ack)
{
	uint8_t i, data;

	RELEASE_SDA();
	data = 0;
	for (i = 0; i <= 7; i++) {
		SCL_1(); 
		_delay_loop_1(TWI_SW_DELAY);
		data <<= 1;
		if (bit_is_set (TWI_PIN_SDA, bSDA))
			data++;
		SCL_0(); 
		_delay_loop_1(TWI_SW_DELAY);
	}
	if (!ack) {	
		SDA_1();	/*Set NO ACK*/
	} else {		
		SDA_0(); 	/*Set ACK*/
	}
	SCL_1();
	_delay_loop_1(TWI_SW_DELAY);
	SCL_0(); 
	_delay_loop_1(TWI_SW_DELAY);
	return data;
}
예제 #3
0
uint8_t tw_send_byte(uint8_t data)
{
	register uint8_t i;
	
	
	for (i = 0; i <= 7; i++) {
		if (data & 0x80) {
			SDA_1();
		} else {
			SDA_0(); 
		}
		SCL_1(); 
		_delay_loop_1(TWI_SW_DELAY);
		SCL_0(); 
		_delay_loop_1(TWI_SW_DELAY);
		data = data << 1;
	}
	RELEASE_SDA();
	SCL_1(); 
	_delay_loop_1(TWI_SW_DELAY);
	if(bit_is_set(TWI_PIN_SDA, bSDA)) {
		SCL_0();
		_delay_loop_1(TWI_SW_DELAY);
		return 0;		//Acknowledge NOT received
	}
	SCL_0();
	_delay_loop_1(TWI_SW_DELAY);
	return 1;
}
예제 #4
0
파일: main.c 프로젝트: nixphix/Tron
void HC595Latch()
{
	HC595_PORT|=(1<<HC595_ST_CP_POS);
	_delay_loop_1(1);
	HC595_PORT&=(~(1<<HC595_ST_CP_POS));
	_delay_loop_1(1);
}
예제 #5
0
void EthernetInit()
{
    _delay_loop_1(50); // 12ms

    /* enable PD4, as input */
    DDRD&= ~(1<<DDRD4);

    /*initialize enc28j60*/
    enc28j60Init(mymac);
    enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
    _delay_loop_1(50); // 12ms
        
    /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
    // LEDB=yellow LEDA=green
    //
    // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
    // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
    enc28j60PhyWrite(PHLCON,0x476);
    _delay_loop_1(50); // 12ms
        
    /* set output to GND, red LED on */
    //PORTB &= ~(1<<PORTB1);
    //i=1;
//
    //init the ethernet/ip layer:
    init_ip_arp_udp_tcp(mymac,myip,80);

}
int main(void){
        uint16_t dat_p;
        
        // set the clock speed to 8MHz
        // set the clock prescaler. First write CLKPCE to enable setting of clock the
        // next four instructions.
        CLKPR=(1<<CLKPCE);
        CLKPR=0; // 8 MHZ
        _delay_loop_1(0); // 60us
        
        //initialize the hardware driver for the enc28j60
        enc28j60Init(mymac);
        //enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
        _delay_loop_1(0); // 60us
        enc28j60PhyWrite(PHLCON,0x476);
        
        PORTB = 0xff;
        DDRB = 0xff;
        uart_init();
        sei();

        xfunc_out = (void (*)(char))uart_put;
        xputs(PSTR("AVR-Ethernet test monitor\n"));
        xprintf(PSTR("ENC28J60 Rev.%d\n"), enc28j60getrev());

        //init the ethernet/ip layer:
        init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);

        while(1){
                // read packet, handle ping and wait for a tcp packet:
                dat_p=packetloop_icmp_tcp(buf,enc28j60PacketReceive(BUFFER_SIZE, buf));

                /* dat_p will be unequal to zero if there is a valid 
                 * http get */
                if(dat_p==0){
                        // no http request
                        continue;
                }
                // tcp port 80 begin
                if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
                        // head, post and other methods:
                        dat_p=http200ok();
                        dat_p=fill_tcp_data_p(buf,dat_p,PSTR("<h1>200 OK</h1>"));
                        goto SENDTCP;
                }
                // just one web page in the "root directory" of the web server
                if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
                        dat_p=print_webpage(buf);
                        goto SENDTCP;
                }else{
                        dat_p=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
                        goto SENDTCP;
                }
SENDTCP:
                www_server_reply(buf,dat_p); // send web page data
                // tcp port 80 end
        }
        return (0);
}
예제 #7
0
파일: main.c 프로젝트: lukeyyang/475
void 
shift_latch()
{
        PORTB |=   (1 << PB1);
        _delay_loop_1(1);
        PORTB &= (~(1 << PB1));
        _delay_loop_1(1);
}
예제 #8
0
파일: LCD1602.c 프로젝트: gnimnet/libm8
/********************内部函数********************/
void LCD_Write_half_byte(uchar HalfByte){
  	LCD_DATA_PORT&=LCD_DATA_MASK;//mask PORT with 0xF0
   	LCD_DATA_PORT|=HalfByte;//send high 4bit
	SET_EN();
	_delay_loop_1(1);
	CLR_EN(); 
	_delay_loop_1(1);
}
예제 #9
0
파일: spisw.c 프로젝트: bechu/hexapod
static void writeMany(const SPI_ABSTRACT_DEVICE* device,const void* dta, size_t size){
	SPI_SW* spi = (SPI_SW*)(device->bus);
	uint8_t delay = spi->_bus_.clock / 3;		// delay loop is approx 3 cycles
	uint8_t* src = (uint8_t*)dta;

	// Get MOSI pin data
	const IOPin*  io = spi->MOSI;
	const IOPort* mosiPortDef = (const IOPort*)pgm_read_word(&io->port);
	PORT mosiPort  = pgm_read_word(&mosiPortDef->port);
	PIN  mosiMask = pgm_read_byte(&io->pin);

	// Get SCLK data
	io = spi->SCLK;
	const IOPort* sclkPortDef = (const IOPort*)pgm_read_word(&io->port);
	PORT sclkPort = pgm_read_word(&sclkPortDef->port);
	PIN sclkMask = pgm_read_byte(&io->pin);

	uint8_t cpha = spi->_bus_.mode & 1;


	if(spi->_bus_.order == SPI_DATA_ORDER_MSB){
		// MSB is sent first
		while(size--){
			uint8_t rtn = *src++;
			for(int i=0; i<8; i++){						/* for each bit			*/
				if(cpha) _SFR_MEM8(sclkPort) ^= sclkMask;/* toggle clock (high) 	*/
				if(rtn & 0x80){
					_SFR_MEM8(mosiPort) |= mosiMask;	/* set high 			*/
				}else{
					_SFR_MEM8(mosiPort) &= ~mosiMask;	/* set low 				*/
				}
				rtn<<=1;
				if(!cpha) _SFR_MEM8(sclkPort) ^= sclkMask;/* toggle clock (high) 	*/
				if(delay) _delay_loop_1(delay);			/* delay			  	*/
				_SFR_MEM8(sclkPort) ^= sclkMask;		/* toggle clock (low) 	*/
			}											/* next bit				*/
		}
	}else{
		// LSB is sent first
		while(size--){
			uint8_t rtn = *src++;
			for(int i=0; i<8; i++){						/* for each bit			*/
				if(cpha) _SFR_MEM8(sclkPort) ^= sclkMask;/* toggle clock (high) 	*/
				if(rtn & 1){
					_SFR_MEM8(mosiPort) |= mosiMask;	/* set high 			*/
				}else{
					_SFR_MEM8(mosiPort) &= ~mosiMask;	/* set low 				*/
				}
				rtn>>=1;
				if(!cpha) _SFR_MEM8(sclkPort) ^= sclkMask;/* toggle clock (high) 	*/
				if(delay) _delay_loop_1(delay);			/* delay			  	*/
				_SFR_MEM8(sclkPort) ^= sclkMask;		/* toggle clock (low) 	*/
			}											/* next bit				*/
		}
	}
	__spiWriteMOSI(spi,device->fillerByte);			/* Set the output pin 	     */
													/* using first bit of filler */
}
예제 #10
0
파일: delay.c 프로젝트: ushakov/sleep-well
void delay_us(uint16_t us)
{
    int16_t loops = 8 * us / 3;
    while (loops > 256) {
	_delay_loop_1 (0);
	loops -= 256;
    }
    _delay_loop_1 ((uint8_t) loops);
}
void buzz()
{
	while(!(PINB & (_BV(PB4))))  {
	// alternately write 1 and 0 to PB5
		PORTB = _BV(PB5);
		_delay_loop_1(128);
		PORTB = 0;
		_delay_loop_1(128);
	}
	return;
}
예제 #12
0
파일: servos.c 프로젝트: bgomberg/TapeBot
void writeServoOutput(u08 servoOutput)
{	
	PORTC = servoOutput;

	_delay_loop_1(1);
	//clock in the servo output
	sbi(PORTD,5);
	_delay_loop_1(1);
	//clock in the servo output
	cbi(PORTD,5);
	_delay_loop_1(1);
}
예제 #13
0
//returns the value of a digital input
u08 digital(u08 num) {
    u08 value;

    cli(); // disable interrupts
    DDRC = 0;
    cbi(PORTD,4); //enable digital input latch
    _delay_loop_1(1); // delay roughly 1uS
    value = PINC;
    _delay_loop_1(1); // delay roughly 1uS
    sbi(PORTD,4); //disable digital input latch
    sei(); // enable interrupts

    return ((value & _BV(num)) != 0);
}
uint8_t getmode()	// get initial state --- foil or epee
{
	uint8_t test, foil;

	test = PINB & _BV(INPIN);
	_delay_loop_1(255);	// debounce input
	foil =  PINB & _BV(INPIN);
	while (foil != test) {
		_delay_loop_1(255);
		test = foil;
		foil = PINB & _BV(INPIN);
	}
return (foil);
}
예제 #15
0
void tw_stop(void)
{
	SDA_0(); 
	SCL_1();
	_delay_loop_1(TWI_SW_DELAY);
	SDA_1(); 
	_delay_loop_1(TWI_SW_DELAY);
	SCL_0(); 
	_delay_loop_1(TWI_SW_DELAY);
	//we need to free the bus
	RELEASE_SDA();
	SCL_1();
	_delay_loop_1(TWI_SW_DELAY);
}
예제 #16
0
uint8_t tw_start(void)
{
	RELEASE_SDA();
	SCL_1();
	_delay_loop_1(TWI_SW_DELAY);
	if(bit_is_clear(TWI_PIN_SDA,bSDA)) {
		return RC_FAIL;
	}
	SDA_0(); 
	_delay_loop_1(TWI_SW_DELAY);
	SCL_0(); 
	_delay_loop_1(TWI_SW_DELAY);
	return RC_SUCCESS;
}
예제 #17
0
파일: nRF24L01.c 프로젝트: csaleman/yavrha
void nrf_send(uint8_t * value) 
// Sends a data package to the default address. Be sure to send the correct
// amount of bytes as configured as payload on the receiver.
{
    CE_LOW

    TX_POWERUP                     // Power up NRF
    
    nrf_config_register(STATUS,(1<<TX_DS)|(1<<MAX_RT)); // clear status register, write 1 to clear bit.
	
	
	CSN_LOW                    // Pull down chip select
    spi_fast_shift( FLUSH_TX );     // Write cmd to flush tx fifo
    CSN_HIGH                    // Pull up chip select
    
    CSN_LOW                    // Pull down chip select
    spi_fast_shift( W_TX_PAYLOAD ); // Write cmd to write payload
    spi_transmit_sync(value,PAYLOAD_WIDTH);   // Write payload
    CSN_HIGH                    // Pull up chip select
    
    CE_HIGH                     // Start transmission
	_delay_loop_1(4);			// Short Delay to make sure CE is High for at least 10us
	CE_LOW
										// Wait until data is sent or MAX_RT flag
	while(!(nrf_send_completed()));		// This function return 1 if data was transmitted or after MAX_RT.
										
}
예제 #18
0
INLINE void keypad__run(void) {
    uint8_t scanMask = COL0_SCAN_MASK;
    for (uint8_t column = 0; column < 4; column++)
    {
        outputScanValue (scanMask);	// always pull up lower 4 lines (inputs)
        scanMask = ((uint8_t)(scanMask << 1)) | ((uint8_t)1);
       _delay_loop_1(KEYBOARD_SCAN_DELAY);

//DDRB=0; // all inputs (temporary - will avoid collisions?)
//PORTB=scanMask;
//DDRB=(~scanMask)&0xF0; // lower bits always 0 (input)
        uint8_t scanValue = inputScanValue ();
        uint8_t tempScanValue = scanValue;
        uint8_t changedLines = (uint8_t) (scanValue ^ keyboardState[column]);
        for (uint8_t row = 0; row < 4; row++)
        {
            if ((changedLines & 1) == 1)
            {
//                print('~');
//                print(96+column);
//                print(96+row);
//                print(96+(scanMask>>4));
                // if lower bit of tempScanValue=1 => now key released; 0 => pressed
                uint8_t scancode =
                    (uint8_t) ((tempScanValue & 1) | ROW(row) | COL(column));
                keypad__on_event(scancode);
            }
            tempScanValue >>= 1;
            changedLines >>= 1;
        }
        keyboardState[column] = scanValue;        
    }
}
예제 #19
0
파일: 18S20.c 프로젝트: thomasstrand/AVRpsu
char rd_tsens(void) {
/* Reads a byte from the temperature sensor */
	char a, data=0;
	for(a=0;a<8;a++) {
		_delay_loop_1(18);
		clr_tsens;
		dirt_out;
		_delay_loop_1(18);
		dirt_in;
		_delay_loop_1(18);
		data=data>>1;
		if(tsens)
			data|=0x80;
		_delay_loop_2(275);
	}
	return data;
}
예제 #20
0
static void pause(uint8_t delay){
	#if !defined(_WINDOWS_)
	uint8_t r;
	for(r=timeFactor; r>0; r--){
		_delay_loop_1(delay);
	}
	#endif

}
int main(void)
{
    while(1)
    {
        //TODO:: Please write your application code 
		
		_delay_loop_1(100);
    }
}
예제 #22
0
float ReadADCSensors(void) // Read ADC Sensor for Thermal LM335z
{
	// Variables for the analogue conversion on ADC Sensors

    uint32_t samples = 0;               		// holds the summated samples for decimation
    uint16_t i = (uint16_t) _BV(2 * ADC_SAMPLES); // 4 ^ ADC_SAMPLES

	if( xADCSemaphore != NULL )
	{
		// See if we can obtain the semaphore.  If the semaphore is not available
		// wait 5 ticks to see if it becomes free.

		if( xSemaphoreTake( xADCSemaphore, ( TickType_t ) 5 ) == pdTRUE )
		{
			// We were able to obtain the semaphore and can now access the shared resource.
			// We want to have the ADC for us alone, as it takes some time to sample,
			// so we don't want it getting stolen during the middle of a conversion.

		    setAnalogMode(MODE_10_BIT);	// 10-bit analogue-to-digital conversions
		    DIDR0 = _BV(ADC0D);			// Disable the digital IO circuit on the ADC0 pin, used for the temperature sensor.

			do
			{
				startAnalogConversion(0, EXTERNAL_REF);   // start next conversion
				do _delay_loop_1(F_CPU / 5e5);     // wait until conversion read. This is about 6 uS, which should be enough.
				while( analogIsConverting() );

				samples += analogConversionResult();	// sum the results

			} while (--i);

			xSemaphoreGive( xADCSemaphore );

			samples >>= ADC_SAMPLES; 		// Decimate the samples (to get better accuracy), see AVR8003.doc

			/*
			For the LM335Z we want to calculate the resistance R1 required to ensure that we have 500 uA minimum at the maximum
			temperature we intend to measure.
			Assume maximum 60C this is 273K + 60 = 333K or will be measured at 3330mV

			If Vcc is 4.9V (USB) then the R = V/I calculation gives (4.9 - 3.3)/ 0.0005 = 3200 Ohm

			This leads to using a 3200 Ohm resistor, or there about being 3300 Ohm.

			Testing gives us 0.58mA with the resistor actual at 3250 Ohm.

			Analogue testing gives with this set up: 2.952V at 20C actual... or 22C indicated

			Lets see what the Arduino ADC gives us...
			*/

			// The 497 is the Power Supply Voltage in mV / 10. _BV(10 + ADC_SAMPLES) is the number of ADC values.
			// 271.15 is the adjustment from Kelvin (273.15) and the offset relating to the Temp Sensor error correction.
		} else {
			return 0; // no sample taken so return 0.
예제 #23
0
// Returns the knob value (0-255)
u08 knob(void) {
  cbi(PORTA,7);
  cbi(PORTA,6);
  cbi(PORTA,5);
  _delay_loop_1(2);
  ADMUX &= 0xE0; //clear the lower 5 bits
  
  ADCSRA |= _BV(ADSC);  //start conversion
  loop_until_bit_is_clear(ADCSRA, ADSC);
  
  return ADCH;
}
예제 #24
0
파일: 18S20.c 프로젝트: thomasstrand/AVRpsu
void wr_tsens(char data) {
/* Sends a data byte to the temperature sensor */
	char a;
	for(a=0;a<8;a++) {
		_delay_loop_1(18);			// Delay 5us
		if(data&0x01) {			// Send one
			clr_tsens;
			dirt_out;				// Direction for sensor pin is output :)
			_delay_loop_1(18);		// Short pulse = '1'
			dirt_in;
			_delay_loop_2(275);		// Delay 100us
		}
		else {						// Send zero
			clr_tsens;
			dirt_out;
			_delay_loop_2(275);		// Long pulse = '0'
			dirt_in;
			_delay_loop_1(18);
		}
		data=data>>1;
	}
}
예제 #25
0
//PORT = one of the four phase shifter to have LE pulse applied
//DPS_cmd = desired phase shift
//bit_sh = number of bit shift (left) to the DPS_cmd
void SPI_TX(uint8_t PORT, uint8_t DPS_cmd, uint8_t bit_sh){	
	DPS_cmd = DPS_cmd << bit_sh;	//shift bit according to the phase shifter datasheet
	
	SPDR = DPS_cmd;	//place data to SPI data buffer to start sending the data
	//SPIF bit is set when a SPI transfer is complete; p158
	//SPIF bit is cleared by reading SPSR register with SPIF set, then accessing SPDR; page 172
	while(!(SPSR & (1<<SPIF))){
		;
	}
	data_dump = SPDR;	//clear SPIF bit
	//selectively apply LE pulse after data is transmitted	
	/* delay is required by the phase shifter, but the hardware cannot create a pulse that is as short as 1 cpu cycle
	   assuming the clk is running at 16MHz because of the parasitic capacitance; consider adding an amp as a buffer
	   to remove the charges faster;
	   _delay_loop_1(count) time = 1/CPU_clk*3*count; or 3 CPU_clk time per loop  */	
	if(PORT == PORT1){	//LE1
		PINB |= 1<<PINB6;	//toggle high
		_delay_loop_1(LE_t);
		//_NOP();	//delay by 1 cpu cycle
		PINB |= 1<<PINB6;	//toggle low
		LE1_led = 1;
	} else if (PORT == PORT2){	//LE2
		PINB |= 1<<PINB5;	//toggle high
		_delay_loop_1(LE_t);
		PINB |= 1<<PINB5;	//toggle low
		LE2_led = 1;
	} else if (PORT == PORT3){	//LE3
		PINB |= 1<<PINB4;	//toggle high		
		_delay_loop_1(LE_t);
		PINB |= 1<<PINB4;	//toggle low
		LE3_led = 1;
	} else if (PORT == PORT4){	//LE4
		PINB |= 1<<PINB7;	//toggle high		
		_delay_loop_1(LE_t);
		PINB |= 1<<PINB7;	//toggle low
		LE4_led = 1;
	}	
}
예제 #26
0
파일: spisw.c 프로젝트: bechu/hexapod
// only tested with modes 0 and 2 (cpha = 0)
static uint8_t __spiSWSendByte(SPI_ABSTRACT_BUS* _spi, uint8_t data){
	SPI_SW* spi = (SPI_SW*)_spi;
	uint8_t rtn=0;
	uint8_t delay = _spi->clock / 3;	// delay loop is approx 3 cycles
	uint8_t cpha = _spi->mode & 1;

	for(int i=0; i<8; i++){						/* for each bit			*/
		if(!cpha){ // Mode 0 or 2
			data = __spiWriteMOSI(spi,data);		/* Set the output pin 	*/
			rtn  = __spiReadMISO(spi,rtn);			/* read input for modes 0 and 2	*/
			pin_toggle(spi->SCLK);					/* toggle clock (high) 	*/
			if(delay) _delay_loop_1(delay);			/* delay			  	*/
			pin_toggle(spi->SCLK);					/* toggle clock (low)	*/
		}else{		// Mode 1 or 3
			pin_toggle(spi->SCLK);					/* toggle clock (high) 	*/
			data = __spiWriteMOSI(spi,data);		/* Set the output pin 	*/
			if(delay) _delay_loop_1(delay);			/* delay			  	*/
			pin_toggle(spi->SCLK);					/* toggle clock (low)	*/
			rtn  = __spiReadMISO(spi,rtn);			/* read input for modes 1 and 3	*/
		}
	}											/* next bit				*/
	pin_high(spi->MOSI);						/* make MOSI high		*/
	return rtn;									/* return read byte		*/
}
//-------------------------------------------------------------------------
void sendData(unsigned char data)
  {
  if (column == 128)
    {
    column = 0;
    line++;
    if (line == 8)
      line = 0;
    }
  gLCDgotoXY(line, column);
  _delay_loop_1(1);
  setMode(WriteData);
  data_port = data;
  eStrobe();
  column++; // increase column (maximum 128).
  }
예제 #28
0
// Returns the reading from analog sensor number <sensor>.
// <sensor> ranges from 0 to 9. 
// Each conversion takes 26us = 62.5ns * 13 cycles * 32 prescalar
u08 analog(u08 num) {
  ADMUX &= 0xE0; //clear the lower 5 bits

  //if the input is less than 7, then it is an input connected to the CD4051
  if (num < 7) {
    cbi(PORTA,7);
    cbi(PORTA,6);
    cbi(PORTA,5);
    PORTA |= ((num+1) << 5);
    _delay_loop_1(100); //wait for the voltage to stabilize
  } else {
    ADMUX |= (num-6); 
  }

  ADCSRA |= _BV(ADSC);  //start conversion
  loop_until_bit_is_clear(ADCSRA, ADSC);

  return ADCH;
}
예제 #29
0
파일: main.c 프로젝트: Tell1/ml-impl
void main(void)
{
    DDRB = 0x09;
    PORTB |= (1<<3);
    
    //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    //sleep_enable();
    
    while(1) {
        //for (uint16_t i=0; i<12; i++);
//        _delay_ms(1000);
        PORTB ^= (1<<0);
//        for (uint16_t i=0; i<6; i++);
        //PORTB |= (1<<0);
        //for (uint16_t i=0; i<24; i++);
//        PORTB &= ~(1<<3);
        _delay_loop_1(100);
    }
}
예제 #30
0
파일: sense.c 프로젝트: samjacoby/avr
void sense_measure(uint8_t txchan, uint8_t rxchan, uint8_t n) {

    uint8_t phase = 0;
    uint8_t count = 0;
    uint8_t done = 0;
    
    // This needs to be signed
    int16_t samp;

    measurement[0] = 0;
    measurement[1] = 0;
    measurement[2] = 0;
    measurement[3] = 0;
    
    transmit_select(txchan);
    transmit_start();
    sense_start();
    
    ADMUX |= rxchan;
    _delay_us(290);
    _delay_loop_1(3);
    NOP;

    ADCSRA |= (1<<ADEN);
    ADCSRA |= (1<<ADSC);

    while(!done) {
        while(!adc_done);
        samp = ADC - 512;
        adc_done = 0;
        if(phase & 2) {
            measurement[phase & 1] += samp;
        } else {
            measurement[phase & 1] -= samp;
        }
        if(phase == 3) count++;
        phase = (phase + 1) & 3;
        if(count == n) done = 1;
    }

    sense_finish();
}