forked from sim-/kk
-
Notifications
You must be signed in to change notification settings - Fork 17
/
gyros.c
139 lines (114 loc) · 3.2 KB
/
gyros.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "gyros.h"
#include "receiver.h"
#include "settings.h"
uint16_t GainInADC[3]; // ADC result
int16_t gyroADC[3]; // Holds Gyro ADC's
int16_t gyroZero[3]; // used for calibrating Gyros on ground
void init_adc()
{
DIDR0 = 0b00111111; // Digital Input Disable Register - ADC5..0 Digital Input Disable
ADCSRB = 0b00000000; // ADC Control and Status Register B - ADTS2:0
}
void gyrosSetup()
{
GYRO_YAW_DIR = INPUT;
GYRO_PITCH_DIR = INPUT;
GYRO_ROLL_DIR = INPUT;
GAIN_YAW_DIR = INPUT;
GAIN_PITCH_DIR = INPUT;
GAIN_ROLL_DIR = INPUT;
init_adc();
}
void read_adc(uint8_t channel)
{
ADMUX = channel; // set channel
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADPS1) | _BV(ADPS2); // 0b11000110
while(ADCSRA & _BV(ADSC))
; // wait to complete
}
/*
* ADC reads 10-bit results (0-1023), so we cannot just multiply Gyro ADC
* by Gain ADC, or we can wrap results. Full ADC range in a 16 bit value
* is ADC shifted left by 6, so we scale the gain to 6-bit by shifting
* right by 10 - 6 = 4 bits.
*/
void ReadGainPots()
{
read_adc(3); // read roll gain ADC3
GainInADC[ROLL] = GAIN_POT_REVERSE ADCW;
read_adc(4); // read pitch gain ADC4
GainInADC[PITCH] = GAIN_POT_REVERSE ADCW;
read_adc(5); // read yaw gain ADC5
GainInADC[YAW] = GAIN_POT_REVERSE ADCW;
}
void ReadGyros()
{
read_adc(2); // read roll gyro ADC2
gyroADC[ROLL] = ADCW;
read_adc(1); // read pitch gyro ADC1
gyroADC[PITCH] = ADCW;
#ifdef EXTERNAL_YAW_GYRO
gyroADC[YAW] = 0;
#else
read_adc(0); // read yaw gyro ADC0
gyroADC[YAW] = ADCW;
#endif
}
void CalibrateGyros()
{
uint8_t i;
ReadGainPots(); // about time we did this !
// get/set gyro zero value (average of 16 readings)
gyroZero[ROLL] = 0;
gyroZero[PITCH] = 0;
gyroZero[YAW] = 0;
for(i = 0;i < 16;i++) {
ReadGyros();
gyroZero[ROLL]+= gyroADC[ROLL];
gyroZero[PITCH]+= gyroADC[PITCH];
gyroZero[YAW]+= gyroADC[YAW];
}
gyroZero[ROLL] = (gyroZero[ROLL] + 8) >> 4;
gyroZero[PITCH] = (gyroZero[PITCH] + 8) >> 4;
gyroZero[YAW] = (gyroZero[YAW] + 8) >> 4;
}
void gyrosReverse()
{
// flash LED 3 times
for(uint8_t i = 0;i < 3;i++) {
LED = 1;
_delay_ms(25);
LED = 0;
_delay_ms(25);
}
while(1) {
RxGetChannels();
if(RxInRoll < -STICK_THROW) { // normal(left)
Config.RollGyroDirection = GYRO_NORMAL;
Save_Config_to_EEPROM();
LED = 1;
} if(RxInRoll > STICK_THROW) { // reverse(right)
Config.RollGyroDirection = GYRO_REVERSED;
Save_Config_to_EEPROM();
LED = 1;
} else if(RxInPitch < -STICK_THROW) { // normal(up)
Config.PitchGyroDirection = GYRO_NORMAL;
Save_Config_to_EEPROM();
LED = 1;
} else if(RxInPitch > STICK_THROW) { // reverse(down)
Config.PitchGyroDirection = GYRO_REVERSED;
Save_Config_to_EEPROM();
LED = 1;
} else if(RxInYaw < -STICK_THROW) { // normal(left)
Config.YawGyroDirection = GYRO_NORMAL;
Save_Config_to_EEPROM();
LED = 1;
} else if(RxInYaw > STICK_THROW) { // reverse(right)
Config.YawGyroDirection = GYRO_REVERSED;
Save_Config_to_EEPROM();
LED = 1;
}
_delay_ms(50);
LED = 0;
}
}