Subversion Repositories FlightCtrl

Rev

Rev 2125 | Rev 2135 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2125 Rev 2132
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 53... Line 56...
53
  RCQuality = 0;
56
  RCQuality = 0;
Line 54... Line 57...
54
 
57
 
55
  SREG = sreg;
58
  SREG = sreg;
Line -... Line 59...
-
 
59
}
-
 
60
 
-
 
61
/*
-
 
62
 * This new and much faster interrupt handler should reduce servo jolts.
-
 
63
 */
-
 
64
ISR(TIMER1_CAPT_vect) {
-
 
65
  static uint16_t oldICR1 = 0;
-
 
66
  uint16_t signal = (uint16_t)ICR1 - oldICR1;
-
 
67
  oldICR1 = ICR1;
-
 
68
  //sync gap? (3.5 ms < signal < 25.6 ms)
-
 
69
  if (signal > TIME(3.5)) {
-
 
70
        inBfrPnt = 0;
-
 
71
  } else if (inBfrPnt<MAX_CHANNELS) {
-
 
72
        RC_buffer[inBfrPnt++] = signal;
-
 
73
  }
56
}
74
}
57
 
75
 
58
/********************************************************************/
76
/********************************************************************/
59
/*         Every time a positive edge is detected at PD6            */
77
/*         Every time a positive edge is detected at PD6            */
60
/********************************************************************/
78
/********************************************************************/
Line 74... Line 92...
74
 The minimum duration of all channels at minimum value is  8 * 1 ms = 8 ms.
92
 The minimum duration of all channels at minimum value is  8 * 1 ms = 8 ms.
75
 The maximum duration of all channels at maximum value is  8 * 2 ms = 16 ms.
93
 The maximum duration of all channels at maximum value is  8 * 2 ms = 16 ms.
76
 The remaining time of (22.5 - 8 ms) ms = 14.5 ms  to (22.5 - 16 ms) ms = 6.5 ms is
94
 The remaining time of (22.5 - 8 ms) ms = 14.5 ms  to (22.5 - 16 ms) ms = 6.5 ms is
77
 the syncronization gap.
95
 the syncronization gap.
78
 */
96
 */
79
ISR(TIMER1_CAPT_vect) { // typical rate of 1 ms to 2 ms
-
 
80
  int16_t signal, tmp;
97
void RC_process(void) {
81
  static int16_t index;
98
        if (RCQuality) RCQuality--;
82
  static uint16_t oldICR1 = 0;
-
 
83
 
-
 
84
  // 16bit Input Capture Register ICR1 contains the timer value TCNT1
-
 
85
  // at the time the edge was detected
-
 
86
 
-
 
87
  // calculate the time delay to the previous event time which is stored in oldICR1
-
 
88
  // calculatiing the difference of the two uint16_t and converting the result to an int16_t
-
 
89
  // implicit handles a timer overflow 65535 -> 0 the right way.
99
  for (uint8_t channel=0; channel<MAX_CHANNELS; channel++) {
90
  signal = (uint16_t) ICR1 - oldICR1;
100
        uint16_t signal = RC_buffer[channel];
91
  oldICR1 = ICR1;
-
 
92
 
-
 
93
  //sync gap? (3.5 ms < signal < 25.6 ms)
-
 
94
  if (signal > TIME(3.5)) {
101
        if (signal != 0) {
95
    index = 0;
-
 
96
  } else { // within the PPM frame
-
 
97
    if (index < MAX_CHANNELS) { // PPM24 supports 12 channels
-
 
98
      // check for valid signal length (0.8 ms < signal < 2.2 ms)
102
          RC_buffer[channel] = 0; // reset to flag value already used.
99
      if ((signal >= TIME(0.8)) && (signal < TIME(2.2))) {
103
      if ((signal >= TIME(0.8)) && (signal < TIME(2.2))) {
100
        // shift signal to zero symmetric range  -154 to 159
-
 
101
        //signal -= 3750; // theoretical value
-
 
102
        signal -= (TIME(1.5) - 128 + channelMap.trim-128); // best value with my Futaba in zero trim.
104
        signal -= (TIME(1.5) - 128 + channelMap.HWTrim);
103
        // check for stable signal
-
 
104
        if (abs(signal - PPM_in[index]) < TIME(0.05)) {
105
        if (abs(signal - PPM_in[channel]) < TIME(0.05)) {
-
 
106
                // With 7 channels and 50 frames/sec, we get 350 channel values/sec.
105
          if (RCQuality < 200)
107
          if (RCQuality < 200)
106
            RCQuality += 10;
108
            RCQuality += 2;
107
          else
-
 
108
            RCQuality = 200;
-
 
109
        }
109
        }
110
        // If signal is the same as before +/- 1, just keep it there. Naah lets get rid of this slimy sticy stuff.
-
 
111
        // if (signal >= PPM_in[index] - 1 && signal <= PPM_in[index] + 1) {
-
 
112
          // In addition, if the signal is very close to 0, just set it to 0.
-
 
113
        if (signal >= -1 && signal <= 1) {
-
 
114
          tmp = 0;
-
 
115
        //} else {
-
 
116
        //  tmp = PPM_in[index];
-
 
117
        //  }
-
 
118
        } else
-
 
119
          tmp = signal;
110
        PPM_in[channel] = signal;
120
        PPM_in[index] = tmp; // update channel value
-
 
121
      }
111
      }
122
      index++; // next channel
-
 
123
      // demux sum signal for channels 5 to 7 to J3, J4, J5
-
 
124
      // TODO: General configurability of this R/C channel forwarding. Or remove it completely - the
-
 
125
      // channels are usually available at the receiver anyway.
-
 
126
      // if(index == 5) J3HIGH; else J3LOW;
-
 
127
      // if(index == 6) J4HIGH; else J4LOW;
-
 
128
      // if(CPUType != ATMEGA644P) // not used as TXD1
-
 
129
      //  {
-
 
130
      //    if(index == 7) J5HIGH; else J5LOW;
-
 
131
      //  }
-
 
132
    }
112
    }
133
  }
113
  }
134
}
114
}
Line 135... Line 115...
135
 
115
 
136
#define RCChannel(dimension) PPM_in[channelMap.channels[dimension]]
-
 
137
#define COMMAND_CHANNEL_VERTICAL CH_THROTTLE
-
 
Line 138... Line 116...
138
#define COMMAND_CHANNEL_HORIZONTAL CH_YAW
116
#define RCChannel(dimension) PPM_in[channelMap.channels[dimension]]
139
 
117
 
140
uint8_t getControlModeSwitch(void) {
118
uint8_t getControlModeSwitch(void) {
141
        int16_t channel = RCChannel(CH_MODESWITCH);
119
        int16_t channel = RCChannel(CH_MODESWITCH);
Line 158... Line 136...
158
        }
136
        }
Line 159... Line 137...
159
 
137
 
Line 160... Line 138...
160
        int16_t channel = RCChannel(CH_THROTTLE);
138
        int16_t channel = RCChannel(CH_THROTTLE);
-
 
139
 
-
 
140
        if (channel <= -TIME(0.55)) {
161
 
141
          int16_t aux = RCChannel(COMMAND_CHANNEL_HORIZONTAL);
-
 
142
          if (abs(aux) >= TIME(0.3)) // If we pull on the stick, it is gyrocal. Else it is RC cal.
162
        if (channel <= -TIME(0.55)) {
143
                lastRCCommand = COMMAND_GYROCAL;
163
          lastRCCommand = COMMAND_GYROCAL;
144
          else
164
          debugOut.analog[17] = 1;
145
                lastRCCommand = COMMAND_RCCAL;
165
        } else {
-
 
166
          lastRCCommand = COMMAND_NONE;
146
        } else {
167
          debugOut.analog[17] = 0;
147
          lastRCCommand = COMMAND_NONE;
168
        }
148
        }
Line 169... Line 149...
169
        return lastRCCommand;
149
        return lastRCCommand;
Line 175... Line 155...
175
 
155
 
176
/*
156
/*
177
 * Get Pitch, Roll, Throttle, Yaw values
157
 * Get Pitch, Roll, Throttle, Yaw values
178
 */
158
 */
179
void RC_periodicTaskAndPRYT(int16_t* PRYT) {
-
 
180
  if (RCQuality) {
159
void RC_periodicTaskAndPRYT(int16_t* PRYT) {
-
 
160
  RC_process();
181
    RCQuality--;
161
 
182
    PRYT[CONTROL_ELEVATOR]   = RCChannel(CH_ELEVATOR);
162
  PRYT[CONTROL_ELEVATOR]   = RCChannel(CH_ELEVATOR)   - rcTrim.trim[CH_ELEVATOR];
183
    PRYT[CONTROL_AILERONS]   = RCChannel(CH_AILERONS);
163
  PRYT[CONTROL_AILERONS]   = RCChannel(CH_AILERONS)   - rcTrim.trim[CH_AILERONS];
184
    PRYT[CONTROL_RUDDER]     = RCChannel(CH_RUDDER);
164
  PRYT[CONTROL_RUDDER]     = RCChannel(CH_RUDDER)     - rcTrim.trim[CH_RUDDER];
185
    PRYT[CONTROL_THROTTLE]   = RCChannel(CH_THROTTLE);
-
 
186
  } // if RCQuality is no good, we just do nothing.
165
  PRYT[CONTROL_THROTTLE]   = RCChannel(CH_THROTTLE);  // no trim on throttle!
Line 187... Line 166...
187
}
166
}
188
 
167
 
189
/*
168
/*
190
 * Get other channel value
169
 * Get other channel value
191
 */
170
 */
192
int16_t RC_getVariable(uint8_t varNum) {
171
int16_t RC_getVariable(uint8_t varNum) {
193
  if (varNum < 4)
172
  if (varNum < 4)
194
    // 0th variable is 5th channel (1-based) etc.
173
    // 0th variable is 5th channel (1-based) etc.
195
    return (RCChannel(varNum + CH_POTS) >> 2) + channelMap.variableOffset;
174
    return (RCChannel(varNum + CH_POTS) >> 3) + channelMap.variableOffset;
196
  /*
175
  /*
197
   * Let's just say:
176
   * Let's just say:
198
   * The RC variable i is hardwired to channel i, i>=4
177
   * The RC variable i is hardwired to channel i, i>=4
199
   */
178
   */
Line 200... Line 179...
200
  return (PPM_in[varNum] >> 2) + channelMap.variableOffset;
179
  return (PPM_in[varNum] >> 3) + channelMap.variableOffset;
201
}
180
}
202
 
181
 
Line 209... Line 188...
209
    return SIGNAL_BAD;
188
    return SIGNAL_BAD;
210
  return SIGNAL_LOST;
189
  return SIGNAL_LOST;
211
}
190
}
Line 212... Line 191...
212
 
191
 
-
 
192
void RC_calibrate(void) {
-
 
193
  rcTrim.trim[CH_ELEVATOR] = RCChannel(CH_ELEVATOR);
-
 
194
  rcTrim.trim[CH_AILERONS] = RCChannel(CH_AILERONS);
213
void RC_calibrate(void) {
195
  rcTrim.trim[CH_RUDDER]   = RCChannel(CH_RUDDER);
214
  // Do nothing.
196
  rcTrim.trim[CH_THROTTLE] = 0;
Line 215... Line 197...
215
}
197
}
216
 
198
 
217
int16_t RC_getZeroThrottle() {
199
int16_t RC_getZeroThrottle(void) {
-
 
200
        return TIME (-0.5);
-
 
201
}
-
 
202
 
-
 
203
void RC_setZeroTrim(void) {
-
 
204
  for (uint8_t i=0; i<MAX_CHANNELS; i++) {
-
 
205
    rcTrim.trim[i] = 0;