示例#1
0
//------------------------------------------------------------------------------
int __attribute__((OS_main)) main(void)
{
	dnaUsbInit();
	enableLed();
	usbCommand = ceCommandIdle;
	usbRNAPacketExpected = 1;
	
	TCCR0B = 1<<CS01 | 1<<CS00; // set 8-bit timer prescaler to div/64
	TIMSK0 = 1<<TOIE0; // enable the interrupt
	
	rnaInit();

	sei();

	setLedOff();

	for(;;)
	{
		rnaPoll();
		
		if ( rnaPacketAvail )
		{
			setLedOn();
			rnaPacketAvail = 0;
			_delay_ms( 50 );
			while ( !rnaSend(usbRNATo, usbRNAPacket, usbRNAPacketExpected) )
			{
				_delay_ms(1);
			}
			setLedOff();
		}

		/*
		if ( usbRNAPacketPos == usbRNAPacketExpected )
		{
			usbRNAPacketPos = 0;
			if ( *usbRNAPacket == RNATypeDebugString )
			{
				usbRNAPacket[usbRNAPacketExpected] = 0;
				usbprint( (char *)usbRNAPacket + 1, usbRNAPacketExpected );
			}
		}
		*/
	}
}
示例#2
0
//------------------------------------------------------------------------------
int __attribute__((OS_main)) main(void)
{
	setupA();
	setupB();
	setupVariables();

	dnaUsbInit();

	INSTALL_MORLOCK_DEFAULTS;
	saveEEPROMConstants();

	loadEEPROMConstants();

	// 12000000 / (64 * 94) = 1994.680 interrupts per second
	// accomplished by using timer0 in waveform generation mode 2
	TCCR0B = 1<<CS01 | 1<<CS00; // set 8-bit timer prescaler to div/64
	OCR0A = 94;
	TCCR0A = 1<<WGM01; 
	TIMSK0 = 1<<OCIE0A; // mode 2, reset counter when it reaches OCROA

	TCCR1B = 1<<WGM12 | 1<<CS12;// CTC for OCR1A, clock select

	// set up A2D
	ADMUX = 1<<MUX0; // A1, Vcc ref
	ADCSRA = 1<<ADEN | 1<<ADPS2; // enable A2D, x16
	DIDR0 = ADC1D; // disable all digital function on A1
	ADCSRB = 1<<ADLAR; // knock off lower two bits, implementation is not that accurate

	PRR = 1<<PRUSI; // not using USI (yet)
	
	rnaInit();

	sei();


	_delay_ms(2); // let state settle, and make sure housekeeping ISR runs

	if( !triggerState && !consts.locked )
	{
		timesToBlinkLight = 1;
		inProgramMode = true;
	}

	for(;;)
	{
		PRR |= 1<<PRTIM1; // power down timer, don't waste power

		// spin until a fire condition is triggered from the ISR
		while( !startFireCycle )
		{
			sampleEye = false;

			if ( rnaRequestsConfigData )
			{
				usbRNAPacket[0] = RNATypeSetConfigData;
				for( unsigned char c=0; c<sizeof(consts); c++ )
				{
					usbRNAPacket[c+1] = ((unsigned char *)&consts)[c];
				}
				rnaSend( rnaRequestsConfigData, usbRNAPacket, sizeof(consts) + 1 );
				rnaRequestsConfigData = 0;
			}

			if ( !millisecondCountBox && consts.eyeEnabled )
			{
				millisecondCountBox--;
				digitizeEye();
				isLedOn = eyeBlocked ? true : false;
			}

			if ( eepromConstantsDirty )
			{
				isLedOn = true;
				setLedOn();
				eepromConstantsDirty = false;
				saveEEPROMConstants();
				isLedOn = false;
			}

			if ( rnaPacketAvail )
			{
				isLedOn = true;
				setLedOn();
				rnaPacketAvail = false;
				_delay_ms( 50 );
				rnaSend( usbRNATo, usbRNAPacket, usbRNAPacketExpected );
				isLedOn = false;
			}
		}

		sampleEye = true;

		// set up the timer
		PRR &= ~(1<<PRTIM1); // timer back on
		TCNT1 = 0; // reset the timer
		TIFR1 |= 1<<OCF1A; // reset compare match

		if ( shotsInString < consts.rampEnableCount )
		{
			shotsInString++;
		}

		// setup complete, cycle the marker
		if ( consts.singleSolenoid )
		{
			cycleSingleSolenoid();
		}
		else
		{
			cycleDoubleSolenoid();
		}

		// bursting? if so count it down
		if ( burstCount && --burstCount )
		{
			startFireCycle = true;
		}
		else if ( currentFireMode != ceFullAuto )
		{
			startFireCycle = false;
		}

		isLedOn = false;

		// make sure at least this much time elapses at the end of a fire cycle
		millisecondCountBox = consts.shortCyclePreventionInterval;
		while( millisecondCountBox );

		while( !(TIFR1 & 1<<OCF1A) ); // wait for end of fire cycle

		if ( currentFireMode == ceRamp && startFireCycle && (consts.rampTopMode != ceSemi) ) // officially hit top rate, blow guts out
		{
			// a shot was scheduled at the maximum rate it could be, go
			// ahead and shift up to whatever top mode the user wanted
			currentFireMode = consts.rampTopMode;
			scheduleShotBox = 0;
			scheduleShotRate = 0;
		}
	}
}
示例#3
0
//------------------------------------------------------------------------------
int __attribute__((OS_main)) main()
{
	// B0 top button (1)
	// B1 bottom button (3)
	// B2 RNA int0
	// B3 middle button
	// B4 power toggle
	DDRB = 0b00010000; // one output, the power toggle, everything else is an input
	PORTB = 0b00011011; // initial state: turn on pullups and keep the power on!

	rnaInit(); // interrupt driven, if we have the space it's the most convenient

	// configure the a2d to sample the middle button, which reads
	// nearly 1.1v for 'pressed' and about .8v for "not pressed" as a
	// result of the power-control circuitry design
	ADMUX = 1<<REFS1 | 1<<MUX0 | 1<<MUX1 | 1<<ADLAR; // B3, 1.1v ref, knock off lower two bits
	ADCSRA = 1<<ADEN; // enable A2D, x16
	DIDR0 = 1<<ADC3D; // disable all digital function on B3

	sei();

	_delay_ms(1); // let values settle
	
	a2dStartConversion();
	a2dWaitForConversionComplete(); // throw out first reading

//	unsigned char high = 0xF0;
//	unsigned char low = 0xD0;

/*	
	unsigned char pos = 0;
	_delay_ms( 500 ); // wait for everyone to boot before probing (the OLED in particular takes a few 100ms)
	unsigned int deltaTargets[0xE]; // when a button is pressed, everyone gets a notice
	for( unsigned char probe=1; probe<0x10; probe++ )
	{
		if ( rnaProbe(probe) )
		{
			deltaTargets[pos++] = probe;
		}
	}
	deltaTargets[pos] = 0;
*/

	unsigned char oldStatus = 0;
	unsigned char status;

	unsigned char rnaPacket[3];
	rnaPacket[0] = RNATypeButtonStatus;
	rnaPacket[1] = 0;

	unsigned int cyclesOn = 0;
	unsigned int doubleClickStateCountdown[3] = { 0, 0, 0 };
	unsigned char doubleClickStateSent[3] = { 1, 1, 1 };
	unsigned char generateRelease = 0;

	for(;;)
	{
		if ( generateRelease )
		{
			generateRelease = 0;
			_delay_ms( 20 );
			rnaPacket[1] = 0;
			rnaSend( RNADeviceOLED, rnaPacket, 2 );
			_delay_ms( 20 );
		}

		status = 0;

		a2dStartConversion();
		a2dWaitForConversionComplete();

		// did we find a calibration?
		if ( ADCH < 0xE0 )
		{
			cyclesOn = 0; // power button not pressed, reset 'power off' logic and set state
			status |= ButtonBitMiddle;
		}
		if ( PINB & 0x1 )
		{
			status |= ButtonBitBottom;
		}

		if ( PINB & 0x2 )
		{
			status |= ButtonBitTop;
		}

		// the buttons are 'active low' but keep things
		// straightforward with a '1' meaning the button has been
		// pressed
		status ^= 0x7;

		for( unsigned char c = 0; c<3; c++ )
		{
			if( (status & (1<<c)) && !(oldStatus & (1<<c)) )
			{
				// just pressed
				if ( c == 1 )
				{
					if ( doubleClickStateCountdown[c] ) // and it's a double-click
					{
						doubleClickStateSent[c] = 1;
						rnaPacket[1] = (1<<c) | ButtonBitDouble;
						generateRelease = 1;
					}
					
					doubleClickStateCountdown[c] = 0;
				}
				else
				{
					rnaPacket[1] = (1<<c);
				}
			}
			else if ( !(status & (1<<c)) && (oldStatus & (1<<c)) )
			{
				// just released
				if ( c == 1 )
				{
					if ( doubleClickStateSent[c] )
					{
						doubleClickStateSent[c] = 0;
					}
					else
					{
						doubleClickStateCountdown[c] = DOUBLE_CLICK_INTERVAL;
					}
				}
				else
				{
					generateRelease = 1;
				}
			}
			else if ( doubleClickStateCountdown[c] )
			{
				if ( !--doubleClickStateCountdown[c] )
				{
					rnaPacket[1] = (1<<c);
					generateRelease = 1;
				}
			}
			
			// event generated? send it
			if ( rnaPacket[1] && rnaSend(RNADeviceOLED, rnaPacket, 2) == -1 )
			{
				_delay_ms(2);
				rnaSend( RNADeviceOLED, rnaPacket, 2 );
			}

			rnaPacket[1] = 0;
		}

		if ( oldStatus != status ) // debounce transitions
		{
//			rnaPacket[1] = status;
//			rnaSend( RNADeviceOLED, rnaPacket, 2 );
			oldStatus = status;
			_delay_ms( 20 );
		}
		else
		{
			_delay_ms( 1 );
		}
		
		if ( cyclesOn++ > POWER_OFF_INTERVAL )
		{
			rnaPacket[1] = ButtonBitPowerOff;
			rnaSend( RNADeviceOLED, rnaPacket, 2 );

			PORTB &= 0b11101111; // turn off the power pin (power won't actually die until the power button is released)
			for(;;);
		}
	}
}