/** * == Xbox 360 Controller RAPID FIRE Mod == * works with ALL hardware versions of the controller * binds the rapidfire function directly to the RT button * * @author Andi Dittrich * @version 1,0 * @target Attiny 25 - 8Mhz * @license MIT Style X11 License * @copyright 2011 Andi Dittrich * * == HARDWARE SETUP == * PB0: Trigger OUT * PB2: Trigger IN * PB3: LED0 * PB4: Enable Switch * * == Controller Trigger Behaviour == * ~ 1.32V released * ~ 0.2V pressed */ #include #include #include #include #include #include #include // trigger state values #define TRIGGER_RELEASE_OUTPUT_VALUE 254 #define TRIGGER_PRESS_OUTPUT_VALUE 5 #define TRIGGER_SENSITIVITY 450 // switch observer volatile unsigned char switchState = 2; volatile unsigned char switchStateChange = 0; // system state volatile unsigned char rapidFireOn = 0; // status led inline void showStatusLed(unsigned char enabled){ if (enabled == 1){ PORTB |= (1<> 11; for (unsigned char i=0;i KEY PRESSED if (switchState<5){ switchState++; }else{ // FALLING EDGE DETECTED if (switchStateChange==0){ switchStateChange = 1; } } }else{ // decrement -> KEY RELEASED if (switchState>0){ switchState--; }else{ // RISING EDGE DETECTED if (switchStateChange==1){ switchStateChange = 2; } } } }; // MAIN int main(){ // == INIT == // Port - LED0, TriggerOut => Out DDRB = 0b00001011; // Switch Pullup ON PORTB = 0b00010000; // ADC - TriggerIN ADC1, PB2 // 7:1 REFS1 - 2.56V Internal Ref // 6:0 REFS0 - 2.56V Internal Ref // 5:0 ADLAR - ADC Value Right Adjusted // 4:1 REFS2 - 2.56V Internal Ref // 3:0 MUX3 - ADC1 PB2 IN // 2:0 MUX3 - ADC1 PB2 IN // 1:0 MUX3 - ADC1 PB2 IN // 0:1 MUX3 - ADC1 PB2 IN ADMUX = 0b10010001; // 7:0 BIN - Unipolar Mode // 6:0 ACME - Analog Multiplexer // 5:0 IPR - No Input Polarity Reversal // 4:0 - RESERVED // 3:0 - RESERVED // 2:0 ADTS2 Free Running mode // 1:0 ADTS1 Free Running mode // 0:0 ADTS0 Free Running mode ADCSRB = 0b00000000; // 7:1 ADEN - Enable ADC // 6:1 ADSC - Start ADC // 5:0 ADATE - Disbale AutoTrigger // 4:0 ADIF - Reset ISR Flag // 3:0 ADIE - Disbale ISR // 2:1 ADPS2 - Prescaler 64 - 125KHz ADC SamplingRate // 1:1 ADPS1 - Prescaler 64 - 125KHz ADC SamplingRate // 0:0 ADPS0 - Prescaler 64 - 125KHz ADC SamplingRate ADCSRA = 0b11000110; GTCCR = 0b0; // TIMER 0 - DAC PWM // 7:1 COM0A1 - Non Inverting PWM, Clear On Compare Math // 6:0 COM0A0 - Non Inverting PWM, Clear On Compare Math // 5:0 COM0B1 - Normal Operation // 4:0 COM0B0 - Normal Operation // 3:0 RESERVED // 2:0 RESERVED // 1:1 WGM01: Fast PWM // 0:1 WGM00: Fast PWM TCCR0A = 0b10000011; // 7:0 FOC0A // 6:0 FOC0B // 5:0 RESERVED // 4:0 RESERVED // 3:0 WGM02 - Fast PWM // 2:0 CS02 - No Clock Prescaling // 2:0 CS01 - No Clock Prescaling // 2:1 CS00 - No Clock Prescaling TCCR0B = 0b00000001; // TIMER 1 - State Observer // 7:0 CTC1 - Continious counting // 6:0 PWM1A - Disbale Pulse Modulator A // 5:0 COM1A - Comparator disconnected // 4:0 COM0A - Comparator disconnected // 3:1 CS13 - Prescaler 256 -> 122 Hz Timebase // 2:0 CS12 - Prescaler 256 -> 122 Hz Timebase // 1:0 CS11 - Prescaler 256 -> 122 Hz Timebase // 0:1 CS10 - Prescaler 256 -> 122 Hz Timebase TCCR1 = 0b00001001; // 7:0 RESERVED // 6:0 OCIE1A - Disabled // 5:0 OCIE1B - Disabled // 4:0 OCIE0A - Disbaled // 3:0 OCIE0B - Disabled // 2:1 TOIE1 - Timer 1 OVF ISR Enabled // 1:0 TOIE0 - Timer 0 OVF ISR Enabled // 0:0 RESERVED TIMSK = 0b00000100; // 7:0 LSM - LowPeedMode // 6:0 RESERVED // 5:0 RESERVED // 4:0 RESERVED // 3:0 RESERVED // 2:0 PCKE - Synchronous clock mode // 1:0 PLLE - PLL Disabled // 0:0 PLOCK PLLCSR = 0b00000000; // watchdog enable wdt_enable(WDTO_2S); // initialize random srand(0b1011100101101001); // enable ISR sei(); // ADC Value unsigned int TriggerValue = 0; // release trigger on default OCR0A = TRIGGER_RELEASE_OUTPUT_VALUE; // == MAIN LOOP == while (1==1){ // Read ADC Value TriggerValue = readADC(); // RapidFire on ? if (rapidFireOn == 1){ // show led showStatusLed(1); // send trigger event if trigger pressed => 500 ~ 1.25V if (TriggerValue < TRIGGER_SENSITIVITY){ fireTrigger(); }else{ // release trigger OCR0A = TRIGGER_RELEASE_OUTPUT_VALUE; } }else{ // hide led showStatusLed(0); // ADC passthrogh -> normalizing values ! max 540 ~ 1.36V // normalizing 9bit => TriggerValue = TriggerValue*15/32; // limit ranges if (TriggerValue > 255){ TriggerValue = 255; } // assign output value OCR0A = (unsigned char)TriggerValue; } // switch state change ? if (switchStateChange==2){ // toggle rf mode rapidFireOn = rapidFireOn^1; // 20ms security delay _delay_ms(20); // reset flag switchStateChange = 0; } // watchdog reset wdt_reset(); } return 1; }