Rev 2122 | Rev 2135 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2122 | Rev 2124 | ||
---|---|---|---|
Line 8... | Line 8... | ||
8 | #include "commands.h" |
8 | #include "commands.h" |
9 | #include "output.h" |
9 | #include "output.h" |
Line 10... | Line 10... | ||
10 | 10 | ||
11 | // The channel array is 0-based! |
11 | // The channel array is 0-based! |
- | 12 | volatile int16_t PPM_in[MAX_CHANNELS]; |
|
- | 13 | volatile uint16_t RC_buffer[MAX_CHANNELS]; |
|
- | 14 | volatile uint8_t inBfrPnt = 0; |
|
12 | volatile int16_t PPM_in[MAX_CHANNELS]; |
15 | |
Line 13... | Line 16... | ||
13 | volatile uint8_t RCQuality; |
16 | volatile uint8_t RCQuality; |
14 | 17 | ||
Line 73... | Line 76... | ||
73 | RCQuality = 0; |
76 | RCQuality = 0; |
Line 74... | Line 77... | ||
74 | 77 | ||
75 | SREG = sreg; |
78 | SREG = sreg; |
Line -... | Line 79... | ||
- | 79 | } |
|
- | 80 | ||
- | 81 | /* |
|
- | 82 | * This new and much faster interrupt handler should reduce servo jolts. |
|
- | 83 | */ |
|
- | 84 | ISR(TIMER1_CAPT_vect) { |
|
- | 85 | static uint16_t oldICR1 = 0; |
|
- | 86 | uint16_t signal = (uint16_t)ICR1 - oldICR1; |
|
- | 87 | oldICR1 = ICR1; |
|
- | 88 | //sync gap? (3.5 ms < signal < 25.6 ms) |
|
- | 89 | if (signal > TIME(3.5)) { |
|
- | 90 | inBfrPnt = 0; |
|
- | 91 | } else if (inBfrPnt<MAX_CHANNELS) { |
|
- | 92 | RC_buffer[inBfrPnt++] = signal; |
|
- | 93 | } |
|
76 | } |
94 | } |
77 | 95 | ||
78 | /********************************************************************/ |
96 | /********************************************************************/ |
79 | /* Every time a positive edge is detected at PD6 */ |
97 | /* Every time a positive edge is detected at PD6 */ |
80 | /********************************************************************/ |
98 | /********************************************************************/ |
Line 94... | Line 112... | ||
94 | The minimum duration of all channels at minimum value is 8 * 1 ms = 8 ms. |
112 | The minimum duration of all channels at minimum value is 8 * 1 ms = 8 ms. |
95 | The maximum duration of all channels at maximum value is 8 * 2 ms = 16 ms. |
113 | The maximum duration of all channels at maximum value is 8 * 2 ms = 16 ms. |
96 | The remaining time of (22.5 - 8 ms) ms = 14.5 ms to (22.5 - 16 ms) ms = 6.5 ms is |
114 | The remaining time of (22.5 - 8 ms) ms = 14.5 ms to (22.5 - 16 ms) ms = 6.5 ms is |
97 | the syncronization gap. |
115 | the syncronization gap. |
98 | */ |
116 | */ |
99 | ISR(TIMER1_CAPT_vect) { // typical rate of 1 ms to 2 ms |
- | |
100 | int16_t signal, tmp; |
117 | void RC_process(void) { |
101 | static int16_t index; |
118 | if (RCQuality) RCQuality--; |
102 | static uint16_t oldICR1 = 0; |
- | |
103 | - | ||
104 | // 16bit Input Capture Register ICR1 contains the timer value TCNT1 |
- | |
105 | // at the time the edge was detected |
- | |
106 | - | ||
107 | // calculate the time delay to the previous event time which is stored in oldICR1 |
- | |
108 | // calculatiing the difference of the two uint16_t and converting the result to an int16_t |
- | |
109 | // implicit handles a timer overflow 65535 -> 0 the right way. |
119 | for (uint8_t channel=0; channel<MAX_CHANNELS; channel++) { |
110 | signal = (uint16_t) ICR1 - oldICR1; |
120 | uint16_t signal = RC_buffer[channel]; |
111 | oldICR1 = ICR1; |
- | |
112 | - | ||
113 | //sync gap? (3.5 ms < signal < 25.6 ms) |
- | |
114 | if (signal > TIME(3.5)) { |
121 | if (signal != 0) { |
115 | index = 0; |
- | |
116 | } else { // within the PPM frame |
- | |
117 | if (index < MAX_CHANNELS) { // PPM24 supports 12 channels |
- | |
118 | // check for valid signal length (0.8 ms < signal < 2.2 ms) |
122 | RC_buffer[channel] = 0; // reset to flag value already used. |
119 | if ((signal >= TIME(0.8)) && (signal < TIME(2.2))) { |
123 | if ((signal >= TIME(0.8)) && (signal < TIME(2.2))) { |
120 | // shift signal to zero symmetric range -154 to 159 |
- | |
121 | //signal -= 3750; // theoretical value |
- | |
122 | signal -= (TIME(1.5) - 128 + channelMap.HWTrim); |
124 | signal -= (TIME(1.5) - 128 + channelMap.HWTrim); |
123 | // check for stable signal |
- | |
124 | if (abs(signal - PPM_in[index]) < TIME(0.05)) { |
125 | if (abs(signal - PPM_in[channel]) < TIME(0.05)) { |
- | 126 | // With 7 channels and 50 frames/sec, we get 350 channel values/sec. |
|
125 | if (RCQuality < 200) |
127 | if (RCQuality < 200) |
126 | RCQuality += 10; |
128 | RCQuality += 2; |
127 | else |
- | |
128 | RCQuality = 200; |
- | |
129 | } |
129 | } |
130 | // If signal is the same as before +/- 1, just keep it there. Naah lets get rid of this slimy sticy stuff. |
- | |
131 | // if (signal >= PPM_in[index] - 1 && signal <= PPM_in[index] + 1) { |
- | |
132 | // In addition, if the signal is very close to 0, just set it to 0. |
- | |
133 | if (signal >= -1 && signal <= 1) { |
- | |
134 | tmp = 0; |
- | |
135 | //} else { |
- | |
136 | // tmp = PPM_in[index]; |
- | |
137 | // } |
- | |
138 | } else |
- | |
139 | tmp = signal; |
130 | PPM_in[channel] = signal; |
140 | PPM_in[index] = tmp; // update channel value |
- | |
141 | } |
131 | } |
142 | index++; // next channel |
- | |
143 | // demux sum signal for channels 5 to 7 to J3, J4, J5 |
- | |
144 | // TODO: General configurability of this R/C channel forwarding. Or remove it completely - the |
- | |
145 | // channels are usually available at the receiver anyway. |
- | |
146 | // if(index == 5) J3HIGH; else J3LOW; |
- | |
147 | // if(index == 6) J4HIGH; else J4LOW; |
- | |
148 | // if(CPUType != ATMEGA644P) // not used as TXD1 |
- | |
149 | // { |
- | |
150 | // if(index == 7) J5HIGH; else J5LOW; |
- | |
151 | // } |
- | |
152 | } |
132 | } |
153 | } |
133 | } |
- | 134 | debugOut.analog[31] = RCQuality; |
|
154 | } |
135 | } |
Line 155... | Line 136... | ||
155 | 136 | ||
156 | #define RCChannel(dimension) PPM_in[channelMap.channels[dimension]] |
- | |
157 | #define COMMAND_CHANNEL_VERTICAL CH_THROTTLE |
- | |
Line 158... | Line 137... | ||
158 | #define COMMAND_CHANNEL_HORIZONTAL CH_YAW |
137 | #define RCChannel(dimension) PPM_in[channelMap.channels[dimension]] |
159 | 138 | ||
160 | uint8_t getControlModeSwitch(void) { |
139 | uint8_t getControlModeSwitch(void) { |
161 | int16_t channel = RCChannel(CH_MODESWITCH); |
140 | int16_t channel = RCChannel(CH_MODESWITCH); |
Line 178... | Line 157... | ||
178 | } |
157 | } |
Line 179... | Line 158... | ||
179 | 158 | ||
Line 180... | Line 159... | ||
180 | int16_t channel = RCChannel(CH_THROTTLE); |
159 | int16_t channel = RCChannel(CH_THROTTLE); |
- | 160 | ||
- | 161 | if (channel <= -TIME(0.55)) { |
|
181 | 162 | int16_t aux = RCChannel(COMMAND_CHANNEL_HORIZONTAL); |
|
- | 163 | if (abs(aux) >= TIME(0.3)) // If we pull on the stick, it is gyrocal. Else it is RC cal. |
|
- | 164 | lastRCCommand = COMMAND_GYROCAL; |
|
182 | if (channel <= -TIME(0.55)) { |
165 | else |
183 | lastRCCommand = COMMAND_GYROCAL; |
166 | lastRCCommand = COMMAND_RCCAL; |
184 | } else { |
167 | } else { |
185 | lastRCCommand = COMMAND_NONE; |
168 | lastRCCommand = COMMAND_NONE; |
186 | } |
169 | } |
Line 193... | Line 176... | ||
193 | 176 | ||
194 | /* |
177 | /* |
195 | * Get Pitch, Roll, Throttle, Yaw values |
178 | * Get Pitch, Roll, Throttle, Yaw values |
196 | */ |
179 | */ |
197 | void RC_periodicTaskAndPRYT(int16_t* PRYT) { |
- | |
198 | if (RCQuality) { |
180 | void RC_periodicTaskAndPRYT(int16_t* PRYT) { |
Line 199... | Line 181... | ||
199 | RCQuality--; |
181 | RC_process(); |
200 | 182 | ||
201 | PRYT[CONTROL_ELEVATOR] = RCChannel(CH_ELEVATOR) - rcTrim.trim[CH_ELEVATOR]; |
183 | PRYT[CONTROL_ELEVATOR] = RCChannel(CH_ELEVATOR) - rcTrim.trim[CH_ELEVATOR]; |
202 | PRYT[CONTROL_AILERONS] = RCChannel(CH_AILERONS) - rcTrim.trim[CH_AILERONS]; |
184 | PRYT[CONTROL_AILERONS] = RCChannel(CH_AILERONS) - rcTrim.trim[CH_AILERONS]; |
203 | PRYT[CONTROL_RUDDER] = RCChannel(CH_RUDDER) - rcTrim.trim[CH_RUDDER]; |
185 | PRYT[CONTROL_RUDDER] = RCChannel(CH_RUDDER) - rcTrim.trim[CH_RUDDER]; |
204 | PRYT[CONTROL_THROTTLE] = RCChannel(CH_THROTTLE); // no trim on throttle! |
186 | PRYT[CONTROL_THROTTLE] = RCChannel(CH_THROTTLE); // no trim on throttle! |
205 | 187 | ||
206 | debugOut.analog[20] = PRYT[CONTROL_ELEVATOR]; |
188 | debugOut.analog[20] = PRYT[CONTROL_ELEVATOR]; |
207 | debugOut.analog[21] = PRYT[CONTROL_AILERONS]; |
189 | debugOut.analog[21] = PRYT[CONTROL_AILERONS]; |
208 | debugOut.analog[22] = PRYT[CONTROL_RUDDER]; |
- | |
209 | debugOut.analog[23] = PRYT[CONTROL_THROTTLE]; |
190 | debugOut.analog[22] = PRYT[CONTROL_RUDDER]; |
Line 210... | Line 191... | ||
210 | } // if RCQuality is no good, we just do nothing. |
191 | debugOut.analog[23] = PRYT[CONTROL_THROTTLE]; |
211 | } |
192 | } |
212 | 193 |