Commit 494fe8623641c783fae30badddcfc3afb2a4a4df

  • avatar
  • dcoberii
  • Fri Apr 24 06:06:52 CEST 2009
Fixed accel files, ready for final testing
  
1// accel.h
2//
3// Disney Fantasia Project
4//
5//
16
27#ifndef ACCEL_H
38#define ACCEL_H
49
5 void initAccel();
6 void pollAccel(accel_data_t *data);
10#include "fantasia_packets.h"
11
12 void initAccel(); //call with other inits
13 void updateAccel(); //call with other updates
14 void configAccel(fantasia_pkt_t *pkt); //give this all valid config packets, sets up triggers and timing, if it gets a mode==POLL then it sends a data packet to the xBee
15 //void pollAccel(); //depreciated, gave direct access to the data, instead it is just called internally and the packet is sent in accel.pde
716
817#endif
  
1#define AVERAGE 16
1// accel.pde
2//
3// Disney Fantasia Project
4//
5//
26
3volatile uint16_t x, y, z;
7#include "accel.h"
8#include "fantasia_packets.h"
9#include <XBeeReader.h>
410
5//volatile static void (*tiggerAccel)();
11//Exponential running average 2^N
12#define AVERAGE 2
613
7//ADC sampling complete interrupt
8SIGNAL(ADC_vect){
14//modes
15uint8_t mode;
16#define OFF 0
17#define POLL 1
18#define TIMER 2
19#define TRIGGER 3
920
10 //disable interrupts (keeps interrupts from nesting)
11 cli();
21//gloabl storage
22volatile uint16_t x, y, z;
23volatile uint32_t trigger;
24volatile uint8_t timer_period;
25volatile uint32_t timer_target;
1226
13 // When we try to change the ADC Channel (by setting ADMUX) the next capture has already started
14 // And so the channel change won't take effect until one cycle later.
15 // When the next ADC_vect is triggered then it will have the value from the old channel but ADMUX
16 // will point to the new channel
17 // Since this code changes the channel on every cycle it means ADMUX is always one step ahead of us
18 // so the reading for y (ADMUX&0x0F==4) is actually the value of x, etc.
19 // That is why the cases do not match
27//externs
28extern uint8_t cur_app;
29extern XBeeReader xbee;
2030
21 //Mask the ADC mux to see what channel we just read from (give or take)
22 uint8_t test = (ADMUX&0x0F);
31//MACROS
32#define SQUARE(x) (x>512)?((x-512)*(x-512)):((512-x)*(512-x))
2333
24 switch(test){
25 case 4: //X-axis
26 x= ((AVERAGE-1)*x+ADCW)/AVERAGE;
27 ADMUX = 0x45;
28 break;
29 case 5: //Y-axis
30 y= ((AVERAGE-1)*y+ADCW)/AVERAGE;
31 ADMUX = 0x43;
32 break;
33 case 3: //Z-axis
34 z= ((AVERAGE-1)*z+ADCW)/AVERAGE;
35 ADMUX = 0x44;
36 break;
37 }
34//Acceleromter Packet Type:
35//TODO: check if this is proper, then put it into the fantasia_packets
36typedef struct {
37 uint8_t type;
38 uint8_t app_uuid;
39 uint8_t x;
40 uint8_t y;
41 uint8_t z;
42} accel_data_pkt_t;
3843
39 //re-enable global interrupts
40 sei();
4144
45//Sets up the trigger function pointer and intializes the vars
46void initAccel(){//void(*tiggerFunc)(void)){
47
48 //No ADC setup done here, not sure if this is correct
49 //No interrupt setup done here, we'll do it without instead
50 //initialize everything to 0:
51 x=512;
52 y=512;
53 z=512;
54 mode=OFF;
55
4256}
4357
4458
45//Initilizes all ADC stuff
46//Sets up the trigger function pointer
47void initAccel(){//void(*tiggerFunc)(void)){
59//returns averaged ADC values
60//Called during poll or by timer
61//Sends a packets
62void pollAccel(){
63
64 accel_data_pkt_t pkt;
65
66 //setup the packet data
67 pkt.type = ACCEL_DATA;
68 pkt.app_uuid = cur_app;
69
70 //perform the 45 degree transformation:
71 pkt.x=((0x1FE - (y>>2) - (x>>2)) * 181)>>8;
72 pkt.y=(((y>>2) + 0xFF - (x>>2)) * 181)>>8;
73 pkt.z=0xFF-(z>>2);
74
75 //check for overflow in x/y:
76 if((x+y)<600){pkt.x=0xFF;}
77 if((y-y)>420){pkt.y=0xFF;}
78
79 //send out the packet:
80 xbee.sendZ( (*uint8_t)&pkt, sizeof(accel_data_pkt_t) );
4881
49 //setup ADC in free running mode (see datasheet)
50 ADMUX = 0x44; // 8b 01 0 x 0100 (aVCC RightAdjust x Channel 4)
51 ADCSRB = 0x0; // 8b x 0 xxx 000 (x ACME xxx FreeRunningMode)
52 ADCSRA = 0xE8; // 8b 1 1 1 x 1 000 (EnableADC Start EnableTrigger x EnableInt clk/2)
53 x=0;
54 y=0;
55 z=0;
56 //tiggerAccel=triggerFunc;
57
5882}
5983
84//Called during the update loop
85//Handles trigger and timer
86//actually reads acceleromter
87void updateAccel(){
88
89 //check if we need the accelerometer
90 if(mode!=OFF){
91 //Update the acceleromter globals using the EMA
92 x = ((1<<AVERAGE-1)*x+analogRead(accel_x))>>AVERAGE;
93 y = ((1<<AVERAGE-1)*y+analogRead(accel_y))>>AVERAGE;
94 z = ((1<<AVERAGE-1)*z+analogRead(accel_z))>>AVERAGE;
95
96 //If we are in trigger mode, check to see if we've triggered
97 if(mode==TRIGGER){
98 if(trigger<SQUARE(x)+SQUARE(y)+SQUARE(z)){
99 //send a packet
100 pollAccel();
101 }
102 }
103
104 if(mode==TIMER){
105 if(millis()>timer_target){
106 //send a packet
107 timer_target += timer_period;
108 pollAccel();
109 }
110 }
111 }
60112
61//returns ADC values (not averaged yet)
62//Called during poll or by timer
63void pollAccel(accel_data_t *data){
113}
64114
65 //this is a pirimitive form of mutexing
66 cli();
67 //perform the 45 degree transformation:
68 data->x=(((0xFF-(y>>2))*181)>>8)+(((0xFF-(x>>2))*181)>>8);
69 data->y=(((y>>2)*181)>>8)+(((0xFF-(x>>2))*181)>>8);
70 data->z=0xFF-(z>>2);
71 sei();
115//Accelerometer config
116//ARGS: just pass us the packet address:
117void configAccel(fantasia_pkt_t *pkt){
118
119 mode = pkt->accel_config.mode;
120
121 switch( pkt->accel_config.mode){
122 case TRIGGER:
123 trigger = (pkt->accel_config.data)<<12;
124 break;
125 case TIMER:
126 timer_period = pkt->accel_config.data;
127 timer_target = millis() + timer_period;
128 break;
129 case POLL:
130 pollAccel();
131 break;
132 }
72133
73134}