Subversion Repositories FlightCtrl

Rev

Rev 2073 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2073 Rev 2160
1
#include <stdlib.h>
1
#include <stdlib.h>
2
#include <avr/io.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
3
#include <avr/interrupt.h>
4
 
4
 
5
#include "rc.h"
5
#include "rc.h"
6
#include "controlMixer.h"
6
#include "controlMixer.h"
7
#include "configuration.h"
7
#include "configuration.h"
8
#include "commands.h"
8
#include "commands.h"
9
#include "output.h"
9
#include "output.h"
10
 
10
 
11
// The channel array is 0-based!
11
// The channel array is 0-based!
12
volatile int16_t PPM_in[MAX_CHANNELS];
12
volatile int16_t PPM_in[MAX_CHANNELS];
13
volatile int16_t PPM_diff[MAX_CHANNELS];
13
volatile int16_t PPM_diff[MAX_CHANNELS];
-
 
14
volatile uint16_t RC_buffer[MAX_CHANNELS];
-
 
15
volatile uint8_t inBfrPnt = 0;
-
 
16
 
14
volatile uint8_t RCQuality;
17
volatile uint8_t RCQuality;
15
uint8_t lastRCCommand = COMMAND_NONE;
18
uint8_t lastRCCommand = COMMAND_NONE;
16
uint8_t commandTimer = 0;
19
uint8_t commandTimer = 0;
-
 
20
 
-
 
21
#define TIME(s) ((int16_t)(((long)F_CPU/(long)64000)*(float)s + 0.5f))
17
 
22
 
18
/***************************************************************
23
/***************************************************************
19
 *  16bit timer 1 is used to decode the PPM-Signal            
24
 *  16bit timer 1 is used to decode the PPM-Signal            
20
 ***************************************************************/
25
 ***************************************************************/
21
void RC_Init(void) {
26
void RC_Init(void) {
22
  uint8_t sreg = SREG;
27
  uint8_t sreg = SREG;
23
 
28
 
24
  // disable all interrupts before reconfiguration
29
  // disable all interrupts before reconfiguration
25
  cli();
30
  cli();
26
 
31
 
27
  // PPM-signal is connected to the Input Capture Pin (PD6) of timer 1
32
  // PPM-signal is connected to the Input Capture Pin (PD6) of timer 1
28
  DDRD &= ~(1<<6);
33
  DDRD &= ~(1<<6);
29
  PORTD |= (1<<PORTD6);
34
  PORTD |= (1<<PORTD6);
30
 
35
 
31
  // Channel 5,6,7 is decoded to servo signals at pin PD5 (J3), PD4(J4), PD3(J5)
36
  // Channel 5,6,7 is decoded to servo signals at pin PD5 (J3), PD4(J4), PD3(J5)
32
  // set as output
37
  // set as output
33
  DDRD |= (1<<DDD5) | (1<<DDD4) | (1<<DDD3);
38
  DDRD |= (1<<DDD5) | (1<<DDD4) | (1<<DDD3);
34
  // low level
39
  // low level
35
  PORTD &= ~((1<<PORTD5) | (1<<PORTD4) | (1<<PORTD3));
40
  PORTD &= ~((1<<PORTD5) | (1<<PORTD4) | (1<<PORTD3));
36
 
41
 
37
  // PD3 can't be used if 2nd UART is activated
42
  // PD3 can't be used if 2nd UART is activated
38
  // because TXD1 is at that port
43
  // because TXD1 is at that port
39
  if (CPUType != ATMEGA644P) {
44
  if (CPUType != ATMEGA644P) {
40
    DDRD |= (1<<PORTD3);
45
    DDRD |= (1<<PORTD3);
41
    PORTD &= ~(1<<PORTD3);
46
    PORTD &= ~(1<<PORTD3);
42
  }
47
  }
43
 
-
 
44
  // Timer/Counter1 Control Register A, B, C
-
 
45
 
48
 
46
  // Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0)
49
  // Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0)
47
  // Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0)
50
  // Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0)
48
  // Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1)
51
  // Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1)
49
  // Enable input capture noise cancler (bit: ICNC1=1)
52
  // Enable input capture noise cancler (bit: ICNC1=1)
50
  // Trigger on positive edge of the input capture pin (bit: ICES1=1),
-
 
51
  // Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2�s
53
  // Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2�s
52
  // The longest period is 0xFFFF / 312.5 kHz = 0.209712 s.
54
  // The longest period is 0xFFFF / 312.5 kHz = 0.209712 s.
53
  TCCR1A &= ~((1 << COM1A1) | (1 << COM1A0) | (1 << COM1B1) | (1 << COM1B0) | (1 << WGM11) | (1 << WGM10));
55
  TCCR1A &= ~((1<<COM1A1)| (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11) | (1<<WGM10));
54
  TCCR1B &= ~((1 << WGM13) | (1 << WGM12) | (1 << CS12));
56
  TCCR1B &= ~((1<<WGM13) | (1<<WGM12)  | (1<<CS12));
55
  TCCR1B |= (1 << CS11) | (1 << CS10) | (1 << ICES1) | (1 << ICNC1);
57
  TCCR1B |= (1<<CS11) | (1<<CS10) | (1<<ICNC1);
-
 
58
  TCCR1C &= ~((1<<FOC1A) | (1<<FOC1B));
-
 
59
 
-
 
60
  if (channelMap.RCPolarity) {
-
 
61
    TCCR1B |= (1<<ICES1);
-
 
62
  } else {
-
 
63
    TCCR1B &= ~(1<<ICES1);
-
 
64
  }
-
 
65
 
56
  TCCR1C &= ~((1 << FOC1A) | (1 << FOC1B));
66
  TCCR1C &= ~((1 << FOC1A) | (1 << FOC1B));
57
 
67
 
58
  // Timer/Counter1 Interrupt Mask Register
68
  // Timer/Counter1 Interrupt Mask Register
59
  // Enable Input Capture Interrupt (bit: ICIE1=1)
69
  // Enable Input Capture Interrupt (bit: ICIE1=1)
60
  // Disable Output Compare A & B Match Interrupts (bit: OCIE1B=0, OICIE1A=0)
70
  // Disable Output Compare A & B Match Interrupts (bit: OCIE1B=0, OICIE1A=0)
61
  // Enable Overflow Interrupt (bit: TOIE1=0)
71
  // Enable Overflow Interrupt (bit: TOIE1=0)
62
  TIMSK1 &= ~((1<<OCIE1B) | (1<<OCIE1A) | (1<<TOIE1));
72
  TIMSK1 &= ~((1<<OCIE1B) | (1<<OCIE1A) | (1<<TOIE1));
63
  TIMSK1 |= (1<<ICIE1);
73
  TIMSK1 |= (1<<ICIE1);
64
 
74
 
65
  RCQuality = 0;
75
  RCQuality = 0;
66
 
76
 
67
  SREG = sreg;
77
  SREG = sreg;
68
}
78
}
-
 
79
 
-
 
80
/*
-
 
81
 * This new and much faster interrupt handler should reduce servo jolts.
-
 
82
 */
-
 
83
ISR(TIMER1_CAPT_vect) {
-
 
84
  static uint16_t oldICR1 = 0;
-
 
85
  uint16_t signal = (uint16_t)ICR1 - oldICR1;
-
 
86
  oldICR1 = ICR1;
-
 
87
  //sync gap? (3.5 ms < signal < 25.6 ms)
-
 
88
  if (signal > TIME(3.5)) {
-
 
89
        inBfrPnt = 0;
-
 
90
  } else if (inBfrPnt<MAX_CHANNELS) {
-
 
91
        RC_buffer[inBfrPnt++] = signal;
-
 
92
        if (RCQuality <= 200-4) RCQuality+=4; else RCQuality = 200;
-
 
93
  }
-
 
94
}
69
 
95
 
70
/********************************************************************/
96
/********************************************************************/
71
/*         Every time a positive edge is detected at PD6            */
97
/*         Every time a positive edge is detected at PD6            */
72
/********************************************************************/
98
/********************************************************************/
73
/*                               t-Frame
99
/*                               t-Frame
74
    <----------------------------------------------------------------------->
100
    <----------------------------------------------------------------------->
75
     ____   ______   _____   ________                ______    sync gap      ____
101
     ____   ______   _____   ________                ______    sync gap      ____
76
    |    | |      | |     | |        |              |      |                |
102
    |    | |      | |     | |        |              |      |                |
77
    |    | |      | |     | |        |              |      |                |
103
    |    | |      | |     | |        |              |      |                |
78
 ___|    |_|      |_|     |_|        |_.............|      |________________|
104
 ___|    |_|      |_|     |_|        |_.............|      |________________|
79
    <-----><-------><------><-----------            <------>                <---
105
    <-----><-------><------><-----------            <------>                <---
80
 t0       t1      t2       t4                     tn                     t0
106
 t0       t1      t2       t4                     tn                     t0
81
 
107
 
82
 The PPM-Frame length is 22.5 ms.
108
 The PPM-Frame length is 22.5 ms.
83
 Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse.
109
 Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse.
84
 The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms.
110
 The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms.
85
 The maximum time delay of two events coding a channel is ( 1.7 + 0.3) ms = 2 ms.
111
 The maximum time delay of two events coding a channel is ( 1.7 + 0.3) ms = 2 ms.
86
 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.
87
 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.
88
 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
89
 the syncronization gap.
115
 the syncronization gap.
90
 */
116
 */
91
ISR(TIMER1_CAPT_vect) { // typical rate of 1 ms to 2 ms
-
 
92
  int16_t signal = 0, tmp;
-
 
93
  static int16_t index;
-
 
94
  static uint16_t oldICR1 = 0;
-
 
95
 
-
 
96
  // 16bit Input Capture Register ICR1 contains the timer value TCNT1
117
 
97
  // at the time the edge was detected
-
 
98
 
-
 
99
  // calculate the time delay to the previous event time which is stored in oldICR1
-
 
100
  // calculatiing the difference of the two uint16_t and converting the result to an int16_t
-
 
101
  // implicit handles a timer overflow 65535 -> 0 the right way.
118
void RC_process(void) {
102
  signal = (uint16_t) ICR1 - oldICR1;
-
 
103
  oldICR1 = ICR1;
-
 
104
 
119
  if (RCQuality) RCQuality--;
105
  //sync gap? (3.52 ms < signal < 25.6 ms)
120
  for (uint8_t channel=0; channel<MAX_CHANNELS; channel++) {
106
  if ((signal > 1100) && (signal < 8000)) {
121
        uint16_t signal = RC_buffer[channel];
107
    index = 0;
-
 
108
  } else { // within the PPM frame
-
 
109
    if (index < MAX_CHANNELS) { // PPM24 supports 12 channels
122
        if (signal != 0) {
110
      // check for valid signal length (0.8 ms < signal < 2.1984 ms)
-
 
111
      // signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
123
          RC_buffer[channel] = 0; // reset to flag value already used.
112
      if ((signal > 250) && (signal < 687)) {
-
 
113
        // shift signal to zero symmetric range  -154 to 159
-
 
114
        signal -= 475; // offset of 1.4912 ms ??? (469 * 3.2us = 1.5008 ms)
-
 
115
        // check for stable signal
-
 
116
        if (abs(signal - PPM_in[index]) < 6) {
-
 
117
          if (RCQuality < 200)
-
 
118
            RCQuality += 10;
-
 
119
          else
124
      if ((signal >= TIME(0.8)) && (signal < TIME(2.2))) {
120
            RCQuality = 200;
-
 
121
        }
-
 
122
        // If signal is the same as before +/- 1, just keep it there. Naah lets get rid of this slimy sticy stuff.
-
 
123
        // if (signal >= PPM_in[index] - 1 && signal <= PPM_in[index] + 1) {
-
 
124
          // In addition, if the signal is very close to 0, just set it to 0.
-
 
125
        if (signal >= -1 && signal <= 1) {
-
 
126
          tmp = 0;
-
 
127
        //} else {
125
        signal -= TIME(1.5);
128
        //  tmp = PPM_in[index];
-
 
129
        //  }
-
 
130
        } else
-
 
131
          tmp = signal;
-
 
132
        // calculate signal difference on good signal level
-
 
133
        if (RCQuality >= 195)
-
 
134
          PPM_diff[index] = signal - PPM_in[index]; //((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
-
 
135
        else
126
        PPM_diff[channel] = signal - PPM_in[channel];
136
          PPM_diff[index] = 0;
-
 
137
        PPM_in[index] = tmp; // update channel value
127
        PPM_in[channel] = signal;
138
      }
-
 
139
      index++; // next channel
-
 
140
      // demux sum signal for channels 5 to 7 to J3, J4, J5
-
 
141
      // TODO: General configurability of this R/C channel forwarding. Or remove it completely - the
-
 
142
      // channels are usually available at the receiver anyway.
-
 
143
      // if(index == 5) J3HIGH; else J3LOW;
-
 
144
      // if(index == 6) J4HIGH; else J4LOW;
-
 
145
      // if(CPUType != ATMEGA644P) // not used as TXD1
-
 
146
      //  {
-
 
147
      //    if(index == 7) J5HIGH; else J5LOW;
-
 
148
      //  }
128
      }
149
    }
129
    }
150
  }
130
  }
151
}
131
}
152
 
132
 
153
#define RCChannel(dimension) PPM_in[channelMap.channels[dimension]]
133
#define RCChannel(dimension) PPM_in[channelMap.channels[dimension]]
154
#define RCDiff(dimension) PPM_diff[channelMap.channels[dimension]]
134
#define RCDiff(dimension) PPM_diff[channelMap.channels[dimension]]
155
#define COMMAND_THRESHOLD 85
135
#define COMMAND_THRESHOLD 85
156
#define COMMAND_CHANNEL_VERTICAL CH_THROTTLE
136
#define COMMAND_CHANNEL_VERTICAL CH_THROTTLE
157
#define COMMAND_CHANNEL_HORIZONTAL CH_YAW
137
#define COMMAND_CHANNEL_HORIZONTAL CH_YAW
158
 
138
 
159
// Internal.
139
// Internal.
160
uint8_t RC_getStickCommand(void) {
140
uint8_t RC_getStickCommand(void) {
161
  if (RCChannel(COMMAND_CHANNEL_VERTICAL) > COMMAND_THRESHOLD) {
141
  if (RCChannel(COMMAND_CHANNEL_VERTICAL) > COMMAND_THRESHOLD) {
162
    // vertical is up
142
    // vertical is up
163
    if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) > COMMAND_THRESHOLD)
143
    if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) > COMMAND_THRESHOLD)
164
      return COMMAND_GYROCAL;
144
      return COMMAND_GYROCAL;
165
    if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) < -COMMAND_THRESHOLD)
145
    if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) < -COMMAND_THRESHOLD)
166
      return COMMAND_ACCCAL;
146
      return COMMAND_ACCCAL;
167
    return COMMAND_NONE;
147
    return COMMAND_NONE;
168
  } else if (RCChannel(COMMAND_CHANNEL_VERTICAL) < -COMMAND_THRESHOLD) {
148
  } else if (RCChannel(COMMAND_CHANNEL_VERTICAL) < -COMMAND_THRESHOLD) {
169
    // vertical is down
149
    // vertical is down
170
    if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) > COMMAND_THRESHOLD)
150
    if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) > COMMAND_THRESHOLD)
171
      return COMMAND_STOP;
151
      return COMMAND_STOP;
172
    if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) < -COMMAND_THRESHOLD)
152
    if (RCChannel(COMMAND_CHANNEL_HORIZONTAL) < -COMMAND_THRESHOLD)
173
      return COMMAND_START;
153
      return COMMAND_START;
174
    return COMMAND_NONE;
154
    return COMMAND_NONE;
175
  }
155
  }
176
  // vertical is around center
156
  // vertical is around center
177
  return COMMAND_NONE;
157
  return COMMAND_NONE;
178
}
158
}
179
 
159
 
180
/*
160
/*
181
 * Get Pitch, Roll, Throttle, Yaw values
161
 * Get Pitch, Roll, Throttle, Yaw values
182
 */
162
 */
183
void RC_periodicTaskAndPRTY(int16_t* PRTY) {
163
void RC_periodicTaskAndPRTY(int16_t* PRTY) {
184
  int16_t tmp1, tmp2;
164
  int16_t tmp1, tmp2;
-
 
165
  RC_process();
185
  if (RCQuality) {
166
  if (RCQuality) {
186
    RCQuality--;
167
    RCQuality--;
187
    PRTY[CONTROL_PITCH]     = RCChannel(CH_PITCH) * staticParams.stickP + RCDiff(CH_PITCH) * staticParams.stickD;
168
    PRTY[CONTROL_PITCH]     = RCChannel(CH_PITCH) * staticParams.stickP + RCDiff(CH_PITCH) * staticParams.stickD;
188
    PRTY[CONTROL_ROLL]      = RCChannel(CH_ROLL) * staticParams.stickP + RCDiff(CH_ROLL) * staticParams.stickD;
169
    PRTY[CONTROL_ROLL]      = RCChannel(CH_ROLL) * staticParams.stickP + RCDiff(CH_ROLL) * staticParams.stickD;
189
    int16_t throttle = RCChannel(CH_THROTTLE) + RCDiff(CH_THROTTLE) * staticParams.stickThrottleD + 120;
170
    int16_t throttle = RCChannel(CH_THROTTLE) + RCDiff(CH_THROTTLE) * staticParams.stickThrottleD + 120;
190
    // Negative throttle values are taken as zero.
171
    // Negative throttle values are taken as zero.
191
    if (throttle > 0)
172
    if (throttle > 0)
192
      PRTY[CONTROL_THROTTLE]  = throttle;
173
      PRTY[CONTROL_THROTTLE]  = throttle;
193
    tmp1 = -RCChannel(CH_YAW) - RCDiff(CH_YAW);
174
    tmp1 = -RCChannel(CH_YAW) - RCDiff(CH_YAW);
194
    // exponential stick sensitivity in yawing rate
175
    // exponential stick sensitivity in yawing rate
195
    tmp2 = (int32_t)staticParams.stickYawP * ((int32_t)tmp1 * abs(tmp1)) >> 9; // expo  y = ax + bx^2
176
    tmp2 = (int32_t)staticParams.stickYawP * ((int32_t)tmp1 * abs(tmp1)) >> 9; // expo  y = ax + bx^2
196
    tmp2 += (staticParams.stickYawP * tmp1) >> 2;
177
    tmp2 += (staticParams.stickYawP * tmp1) >> 2;
197
    PRTY[CONTROL_YAW] = tmp2;
178
    PRTY[CONTROL_YAW] = tmp2;
198
 
179
 
199
    uint8_t command = RC_getStickCommand();
180
    uint8_t command = RC_getStickCommand();
200
    if (lastRCCommand == command) {
181
    if (lastRCCommand == command) {
201
      // Keep timer from overrunning.
182
      // Keep timer from overrunning.
202
      if (commandTimer < COMMAND_TIMER)
183
      if (commandTimer < COMMAND_TIMER)
203
        commandTimer++;
184
        commandTimer++;
204
    } else {
185
    } else {
205
      // There was a change.
186
      // There was a change.
206
      lastRCCommand = command;
187
      lastRCCommand = command;
207
      commandTimer = 0;
188
      commandTimer = 0;
208
    }
189
    }
209
  } // if RCQuality is no good, we just do nothing.
190
  } // if RCQuality is no good, we just do nothing.
210
}
191
}
211
 
192
 
212
/*
193
/*
213
 * Get other channel value
194
 * Get other channel value
214
 */
195
 */
215
int16_t RC_getVariable(uint8_t varNum) {
196
int16_t RC_getVariable(uint8_t varNum) {
216
  if (varNum < 4)
197
  if (varNum < 4)
217
    // 0th variable is 5th channel (1-based) etc.
198
    // 0th variable is 5th channel (1-based) etc.
218
    return RCChannel(varNum + CH_POTS) + POT_OFFSET;
199
    return RCChannel(varNum + CH_POTS) + POT_OFFSET;
219
  /*
200
  /*
220
   * Let's just say:
201
   * Let's just say:
221
   * The RC variable i is hardwired to channel i, i>=4
202
   * The RC variable i is hardwired to channel i, i>=4
222
   */
203
   */
223
  return PPM_in[varNum] + POT_OFFSET;
204
  return PPM_in[varNum] + POT_OFFSET;
224
}
205
}
225
 
206
 
226
uint8_t RC_getSignalQuality(void) {
207
uint8_t RC_getSignalQuality(void) {
227
  if (RCQuality >= 160)
208
  if (RCQuality >= 160)
228
    return SIGNAL_GOOD;
209
    return SIGNAL_GOOD;
229
  if (RCQuality >= 140)
210
  if (RCQuality >= 140)
230
    return SIGNAL_OK;
211
    return SIGNAL_OK;
231
  if (RCQuality >= 120)
212
  if (RCQuality >= 120)
232
    return SIGNAL_BAD;
213
    return SIGNAL_BAD;
233
  return SIGNAL_LOST;
214
  return SIGNAL_LOST;
234
}
215
}
235
 
216
 
236
/*
217
/*
237
 * To should fired only when the right stick is in the center position.
218
 * To should fired only when the right stick is in the center position.
238
 * This will cause the value of pitch and roll stick to be adjusted
219
 * This will cause the value of pitch and roll stick to be adjusted
239
 * to zero (not just to near zero, as per the assumption in rc.c
220
 * to zero (not just to near zero, as per the assumption in rc.c
240
 * about the rc signal. I had values about 50..70 with a Futaba
221
 * about the rc signal. I had values about 50..70 with a Futaba
241
 * R617 receiver.) This calibration is not strictly necessary, but
222
 * R617 receiver.) This calibration is not strictly necessary, but
242
 * for control logic that depends on the exact (non)center position
223
 * for control logic that depends on the exact (non)center position
243
 * of a stick, it may be useful.
224
 * of a stick, it may be useful.
244
 */
225
 */
245
void RC_calibrate(void) {
226
void RC_calibrate(void) {
246
  // Do nothing.
227
  // Do nothing.
247
}
228
}
248
 
229
 
249
/*
230
/*
250
 if (staticParams.GlobalConfig & CFG_HEADING_HOLD) {
231
 if (staticParams.GlobalConfig & CFG_HEADING_HOLD) {
251
 // In HH, it s OK to trim the R/C. The effect should not be conteracted here.
232
 // In HH, it s OK to trim the R/C. The effect should not be conteracted here.
252
 stickOffsetPitch = stickOffsetRoll = 0;
233
 stickOffsetPitch = stickOffsetRoll = 0;
253
 } else {
234
 } else {
254
 stickOffsetPitch = RCChannel(CH_PITCH) * staticParams.StickP;
235
 stickOffsetPitch = RCChannel(CH_PITCH) * staticParams.StickP;
255
 stickOffsetRoll = RCChannel(CH_ROLL)   * staticParams.StickP;
236
 stickOffsetRoll = RCChannel(CH_ROLL)   * staticParams.StickP;
256
 }
237
 }
257
 }
238
 }
258
 */
239
 */
259
 
240
 
260
uint8_t RC_getCommand(void) {
241
uint8_t RC_getCommand(void) {
261
  if (commandTimer == COMMAND_TIMER) {
242
  if (commandTimer == COMMAND_TIMER) {
262
    // Stick has been held long enough; command committed.
243
    // Stick has been held long enough; command committed.
263
    return lastRCCommand;
244
    return lastRCCommand;
264
  }
245
  }
265
  // Not yet sure what the command is.
246
  // Not yet sure what the command is.
266
  return COMMAND_NONE;
247
  return COMMAND_NONE;
267
}
248
}
268
 
249
 
269
/*
250
/*
270
 * Command arguments on R/C:
251
 * Command arguments on R/C:
271
 * 2--3--4
252
 * 2--3--4
272
 * |     |  +
253
 * |     |  +
273
 * 1  0  5  ^ 0
254
 * 1  0  5  ^ 0
274
 * |     |  |  
255
 * |     |  |  
275
 * 8--7--6
256
 * 8--7--6
276
 *    
257
 *    
277
 * + <--
258
 * + <--
278
 *    0
259
 *    0
279
 *
260
 *
280
 * Not in any of these positions: 0
261
 * Not in any of these positions: 0
281
 */
262
 */
282
 
263
 
283
#define ARGUMENT_THRESHOLD 70
264
#define ARGUMENT_THRESHOLD 70
284
#define ARGUMENT_CHANNEL_VERTICAL CH_PITCH
265
#define ARGUMENT_CHANNEL_VERTICAL CH_PITCH
285
#define ARGUMENT_CHANNEL_HORIZONTAL CH_ROLL
266
#define ARGUMENT_CHANNEL_HORIZONTAL CH_ROLL
286
 
267
 
287
uint8_t RC_getArgument(void) {
268
uint8_t RC_getArgument(void) {
288
  if (RCChannel(ARGUMENT_CHANNEL_VERTICAL) > ARGUMENT_THRESHOLD) {
269
  if (RCChannel(ARGUMENT_CHANNEL_VERTICAL) > ARGUMENT_THRESHOLD) {
289
    // vertical is up
270
    // vertical is up
290
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
271
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
291
      return 2;
272
      return 2;
292
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
273
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
293
      return 4;
274
      return 4;
294
    return 3;
275
    return 3;
295
  } else if (RCChannel(ARGUMENT_CHANNEL_VERTICAL) < -ARGUMENT_THRESHOLD) {
276
  } else if (RCChannel(ARGUMENT_CHANNEL_VERTICAL) < -ARGUMENT_THRESHOLD) {
296
    // vertical is down
277
    // vertical is down
297
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
278
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
298
      return 8;
279
      return 8;
299
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
280
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
300
      return 6;
281
      return 6;
301
    return 7;
282
    return 7;
302
  } else {
283
  } else {
303
    // vertical is around center
284
    // vertical is around center
304
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
285
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
305
      return 1;
286
      return 1;
306
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
287
    if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
307
      return 5;
288
      return 5;
308
    return 0;
289
    return 0;
309
  }
290
  }
310
}
291
}
311
 
292
 
312
#ifdef USE_MK3MAG
293
#ifdef USE_MK3MAG
313
/*
294
/*
314
 * For each time the stick is pulled, returns true.
295
 * For each time the stick is pulled, returns true.
315
 */
296
 */
316
uint8_t RC_testCompassCalState(void) {
297
uint8_t RC_testCompassCalState(void) {
317
  static uint8_t stickPulled = 1;
298
  static uint8_t stickPulled = 1;
318
  // if pitch is centered or top set stick to zero
299
  // if pitch is centered or top set stick to zero
319
  if (RCChannel(CH_PITCH) > -20)
300
  if (RCChannel(CH_PITCH) > -20)
320
    stickPulled = 0;
301
    stickPulled = 0;
321
  // if pitch is down trigger to next cal state
302
  // if pitch is down trigger to next cal state
322
  if ((RCChannel(CH_PITCH) < -70) && !stickPulled) {
303
  if ((RCChannel(CH_PITCH) < -70) && !stickPulled) {
323
    stickPulled = 1;
304
    stickPulled = 1;
324
    return 1;
305
    return 1;
325
  }
306
  }
326
  return 0;
307
  return 0;
327
}
308
}
328
#endif
309
#endif
329
 
310
 
330
/*
311
/*
331
 * Abstract controls are not used at the moment.
312
 * Abstract controls are not used at the moment.
332
 t_control rc_control = {
313
 t_control rc_control = {
333
 RC_getPitch,
314
 RC_getPitch,
334
 RC_getRoll,
315
 RC_getRoll,
335
 RC_getYaw,
316
 RC_getYaw,
336
 RC_getThrottle,
317
 RC_getThrottle,
337
 RC_getSignalQuality,
318
 RC_getSignalQuality,
338
 RC_calibrate
319
 RC_calibrate
339
 };
320
 };
340
 */
321
 */
341
 
322