Commit 6bcdbcde76972191ef8fb247cfcd630cb4ac4de0
- Diff rendering mode:
- inline
- side by side
Wand/main/accel.c
(80 / 0)
|   | |||
| 1 | |||
| 2 | #include <avr/io.h> | ||
| 3 | #include <avr/interrupt.h> | ||
| 4 | #include <inttypes.h> | ||
| 5 | #include "fantasia_packets.h" | ||
| 6 | #include "accel.h" | ||
| 7 | |||
| 8 | #define AVERAGE 16 | ||
| 9 | |||
| 10 | volatile uint16_t x, y, z; | ||
| 11 | |||
| 12 | //volatile static void (*tiggerAccel)(); | ||
| 13 | |||
| 14 | //ADC sampling complete interrupt | ||
| 15 | ISR(ADC_vect){ | ||
| 16 | |||
| 17 | //disable interrupts (keeps interrupts from nesting) | ||
| 18 | cli(); | ||
| 19 | |||
| 20 | // When we try to change the ADC Channel (by setting ADMUX) the next capture has already started | ||
| 21 | // And so the channel change won't take effect until one cycle later. | ||
| 22 | // When the next ADC_vect is triggered then it will have the value from the old channel but ADMUX | ||
| 23 | // will point to the new channel | ||
| 24 | // Since this code changes the channel on every cycle it means ADMUX is always one step ahead of us | ||
| 25 | // so the reading for y (ADMUX&0x0F==4) is actually the value of x, etc. | ||
| 26 | // That is why the cases do not match | ||
| 27 | |||
| 28 | //Mask the ADC mux to see what channel we just read from (give or take) | ||
| 29 | uint8_t test = (ADMUX&0x0F); | ||
| 30 | |||
| 31 | switch(test){ | ||
| 32 | case 4: //X-axis | ||
| 33 | x= ((AVERAGE-1)*x+ADCW)/AVERAGE; | ||
| 34 | ADMUX = 0x45; | ||
| 35 | break; | ||
| 36 | case 5: //Y-axis | ||
| 37 | y= ((AVERAGE-1)*y+ADCW)/AVERAGE; | ||
| 38 | ADMUX = 0x43; | ||
| 39 | break; | ||
| 40 | case 3: //Z-axis | ||
| 41 | z= ((AVERAGE-1)*z+ADCW)/AVERAGE; | ||
| 42 | ADMUX = 0x44; | ||
| 43 | break; | ||
| 44 | } | ||
| 45 | |||
| 46 | //re-enable global interrupts | ||
| 47 | sei(); | ||
| 48 | |||
| 49 | } | ||
| 50 | |||
| 51 | |||
| 52 | //Initilizes all ADC stuff | ||
| 53 | //Sets up the trigger function pointer | ||
| 54 | void initAccel(){//void(*tiggerFunc)(void)){ | ||
| 55 | |||
| 56 | //setup ADC in free running mode (see datasheet) | ||
| 57 | ADMUX = 0x44; // 8b 01 0 x 0100 (aVCC RightAdjust x Channel 4) | ||
| 58 | ADCSRB = 0x0; // 8b x 0 xxx 000 (x ACME xxx FreeRunningMode) | ||
| 59 | ADCSRA = 0xE8; // 8b 1 1 1 x 1 000 (EnableADC Start EnableTrigger x EnableInt clk/2) | ||
| 60 | x=0; | ||
| 61 | y=0; | ||
| 62 | z=0; | ||
| 63 | //tiggerAccel=triggerFunc; | ||
| 64 | |||
| 65 | } | ||
| 66 | |||
| 67 | |||
| 68 | //returns ADC values (not averaged yet) | ||
| 69 | //Called during poll or by timer | ||
| 70 | void pollAccel(accel_data_t *data){ | ||
| 71 | |||
| 72 | //this is a pirimitive form of mutexing | ||
| 73 | cli(); | ||
| 74 | //perform the 45 degree transformation: | ||
| 75 | data->x=(((0xFF-(y>>2))*181)>>8)+(((0xFF-(x>>2))*181)>>8); | ||
| 76 | data->y=(((y>>2)*181)>>8)+(((0xFF-(x>>2))*181)>>8); | ||
| 77 | data->z=0xFF-(z>>2); | ||
| 78 | sei(); | ||
| 79 | |||
| 80 | } |
Wand/main/accel.h
(10 / 0)
|   | |||
| 1 | |||
| 2 | #ifndef ACCEL_H | ||
| 3 | #define ACCEL_H | ||
| 4 | |||
| 5 | #include "fantasia_packets.h" | ||
| 6 | |||
| 7 | void initAccel(); | ||
| 8 | void pollAccel(accel_data_t *data); | ||
| 9 | |||
| 10 | #endif |

