Subversion Repositories FlightCtrl

Rev

Rev 1813 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1813 Rev 1819
1
/******************************************************************************************************************
1
/******************************************************************************************************************
2
V0.82b-Arthur-P 2010-12-18
2
V0.82b-Arthur-P 2010-12-18
3
------------------------------------------------------------------------------------------------------------------
3
------------------------------------------------------------------------------------------------------------------
4
Version includes only support for external HEF4017 for FC1.x hardware, NOT for Twi2Ppm converters for ESCs.
4
Version includes only support for external HEF4017 for FC1.x hardware, NOT for Twi2Ppm converters for ESCs.
5
 
5
 
-
 
6
2010-12-18 Transferred changes to v.0.82b-Arthur-P and chande the if(Platinenversion < 20) statement in the
6
2010-12-18 Transferred changes to v.0.82b-Arthur-P
7
new servocontrol calculating routine to correctly identify external HEF4017.
7
20100917: Transferred changes to v0.80g-Arthur-P.
8
20100917: Transferred changes to v0.80g-Arthur-P.
8
Arthur P. Modified to use several parameters for servo control:
9
Arthur P. Modified to use several parameters for servo control:
9
User_Parameter4:
10
User_Parameter4:
10
User_Parameter5:
11
User_Parameter5:
11
User_Parameter6:
12
User_Parameter6:
12
User_Parameter7:
13
User_Parameter7:
13
User_Parameter8: Use external HEF4017 if bit 8 is set (>127). The remaining 7 bits are used
14
User_Parameter8: Use external HEF4017 if bit 8 is set (>127). The remaining 7 bits are used
14
                 for the shutter cycle counter: the value is multiplied by 5 programmatically,
15
                 for the shutter cycle counter: the value is multiplied by 5 programmatically,
15
                                 resulting in steps of approx. 0.1sec. Minimum value to start using the
16
                                 resulting in steps of approx. 0.1sec. Minimum value to start using the
16
                                 interval timer is 10 (approx. 1 sec, or countervalue of 50). Note that this
17
                                 interval timer is 10 (approx. 1 sec, or countervalue of 50). Note that this
17
                                 was originally done through user para 6.
18
                                 was originally done through user para 6.
18
******************************************************************************************************************/
19
******************************************************************************************************************/
19
#include "main.h"
20
#include "main.h"
20
#define MULTIPLYER 4
21
#define MULTIPLYER 4
21
 
22
 
22
volatile unsigned int CountMilliseconds = 0;
23
volatile unsigned int CountMilliseconds = 0;
23
volatile static unsigned int tim_main;
24
volatile static unsigned int tim_main;
24
volatile unsigned char UpdateMotor = 0;
25
volatile unsigned char UpdateMotor = 0;
25
volatile unsigned int cntKompass = 0;
26
volatile unsigned int cntKompass = 0;
26
volatile unsigned int beeptime = 0;
27
volatile unsigned int beeptime = 0;
27
volatile unsigned char SendSPI = 0, ServoActive = 0, CalculateServoSignals = 1;
28
volatile unsigned char SendSPI = 0, ServoActive = 0, CalculateServoSignals = 1;
28
uint16_t RemainingPulse = 0;
29
uint16_t RemainingPulse = 0;
29
volatile int16_t ServoNickOffset = (255 / 2) * MULTIPLYER * 16; // initial value near center positon
30
volatile int16_t ServoNickOffset = (255 / 2) * MULTIPLYER * 16; // initial value near center positon
30
volatile int16_t ServoRollOffset = (255 / 2) * MULTIPLYER * 16; // initial value near center positon
31
volatile int16_t ServoRollOffset = (255 / 2) * MULTIPLYER * 16; // initial value near center positon
31
 
32
 
32
unsigned int BeepMuster = 0xffff;
33
unsigned int BeepMuster = 0xffff;
33
 
34
 
34
volatile int16_t        ServoNickValue = 0;
35
volatile int16_t        ServoNickValue = 0;
35
volatile int16_t        ServoRollValue = 0;
36
volatile int16_t        ServoRollValue = 0;
36
 
37
 
37
/******************************************************************************************************************
38
/******************************************************************************************************************
38
Arthur P: Added two variables for control of the shutter servo cycle.
39
Arthur P: Added two variables for control of the shutter servo cycle.
39
091114 Inserted same changes into v.0.76g code.
40
091114 Inserted same changes into v.0.76g code.
40
091114 Inactivated the following two lines as the shutter interval funtion is not
41
091114 Inactivated the following two lines as the shutter interval funtion is not
41
used at the moment.
42
used at the moment.
42
20100804 Reactivated to be able to choose slower shutter rate than normal for
43
20100804 Reactivated to be able to choose slower shutter rate than normal for
43
Panasonic FX150 in continuous mode.
44
Panasonic FX150 in continuous mode.
44
******************************************************************************************************************/
45
******************************************************************************************************************/
45
 
46
 
46
volatile static unsigned int CameraShutterCycleCounter = 0;
47
volatile static unsigned int CameraShutterCycleCounter = 0;
47
volatile static unsigned int CameraShutterCycle = 0;
48
volatile static unsigned int CameraShutterCycle = 0;
48
volatile static unsigned int CameraShutterCycleOnCount = 20;  // Leave the shutter on for at least
49
volatile static unsigned int CameraShutterCycleOnCount = 20;  // Leave the shutter on for at least
49
                                                                                                                          // 20 cycles or approx. 0.2 seconds.
50
                                                                                                                          // 20 cycles or approx. 0.2 seconds.
50
/******************************************************************************************************************
51
/******************************************************************************************************************
51
Arthur P: End of changes to variables section of timer0.c.
52
Arthur P: End of changes to variables section of timer0.c.
52
******************************************************************************************************************/
53
******************************************************************************************************************/
53
 
54
 
54
 
55
 
55
enum {
56
enum {
56
  STOP             = 0,
57
  STOP             = 0,
57
  CK               = 1,
58
  CK               = 1,
58
  CK8              = 2,
59
  CK8              = 2,
59
  CK64             = 3,
60
  CK64             = 3,
60
  CK256            = 4,
61
  CK256            = 4,
61
  CK1024           = 5,
62
  CK1024           = 5,
62
  T0_FALLING_EDGE  = 6,
63
  T0_FALLING_EDGE  = 6,
63
  T0_RISING_EDGE   = 7
64
  T0_RISING_EDGE   = 7
64
};
65
};
65
 
66
 
66
 
67
 
67
ISR(TIMER0_OVF_vect)    // 9,7kHz
68
ISR(TIMER0_OVF_vect)    // 9,7kHz
68
{
69
{
69
   static unsigned char cnt_1ms = 1,cnt = 0, compass_active = 0;
70
   static unsigned char cnt_1ms = 1,cnt = 0, compass_active = 0;
70
   unsigned char pieper_ein = 0;
71
   unsigned char pieper_ein = 0;
71
   if(SendSPI) SendSPI--;
72
   if(SendSPI) SendSPI--;
72
   if(SpektrumTimer) SpektrumTimer--;
73
   if(SpektrumTimer) SpektrumTimer--;
73
   if(!cnt--)
74
   if(!cnt--)
74
    {
75
    {
75
     cnt = 9;
76
     cnt = 9;
76
     CountMilliseconds++;
77
     CountMilliseconds++;
77
     cnt_1ms++;
78
     cnt_1ms++;
78
     cnt_1ms %= 2;
79
     cnt_1ms %= 2;
79
 
80
 
80
     if(!cnt_1ms) UpdateMotor = 1;
81
     if(!cnt_1ms) UpdateMotor = 1;
81
         if(!(PINC & 0x10)) compass_active = 1;
82
         if(!(PINC & 0x10)) compass_active = 1;
82
 
83
 
83
     if(beeptime)
84
     if(beeptime)
84
        {
85
        {
85
        if(beeptime > 10) beeptime -= 10; else beeptime = 0;
86
        if(beeptime > 10) beeptime -= 10; else beeptime = 0;
86
        if(beeptime & BeepMuster)
87
        if(beeptime & BeepMuster)
87
         {
88
         {
88
          pieper_ein = 1;
89
          pieper_ein = 1;
89
         }
90
         }
90
         else pieper_ein = 0;
91
         else pieper_ein = 0;
91
        }
92
        }
92
     else
93
     else
93
      {
94
      {
94
       pieper_ein = 0;
95
       pieper_ein = 0;
95
       BeepMuster = 0xffff;
96
       BeepMuster = 0xffff;
96
      }
97
      }
97
     if(pieper_ein)
98
     if(pieper_ein)
98
        {
99
        {
99
          if(PlatinenVersion == 10) PORTD |= (1<<2); // Speaker an PORTD.2
100
          if(PlatinenVersion == 10) PORTD |= (1<<2); // Speaker an PORTD.2
100
          else                      PORTC |= (1<<7); // Speaker an PORTC.7
101
          else                      PORTC |= (1<<7); // Speaker an PORTC.7
101
        }
102
        }
102
     else
103
     else
103
        {
104
        {
104
         if(PlatinenVersion == 10) PORTD &= ~(1<<2);
105
         if(PlatinenVersion == 10) PORTD &= ~(1<<2);
105
         else                      PORTC &= ~(1<<7);
106
         else                      PORTC &= ~(1<<7);
106
        }
107
        }
107
        }
108
        }
108
 if(compass_active && !NaviDataOkay && EE_Parameter.GlobalConfig & CFG_KOMPASS_AKTIV)
109
 if(compass_active && !NaviDataOkay && EE_Parameter.GlobalConfig & CFG_KOMPASS_AKTIV)
109
 {
110
 {
110
  if(PINC & 0x10)
111
  if(PINC & 0x10)
111
   {
112
   {
112
        if(++cntKompass > 1000) compass_active = 0;
113
        if(++cntKompass > 1000) compass_active = 0;
113
   }
114
   }
114
  else
115
  else
115
   {
116
   {
116
    if((cntKompass) && (cntKompass < 362))
117
    if((cntKompass) && (cntKompass < 362))
117
    {
118
    {
118
     cntKompass += cntKompass / 41;
119
     cntKompass += cntKompass / 41;
119
     if(cntKompass > 10) KompassValue = cntKompass - 10; else KompassValue = 0;
120
     if(cntKompass > 10) KompassValue = cntKompass - 10; else KompassValue = 0;
120
     KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
121
     KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
121
    }
122
    }
122
    cntKompass = 0;
123
    cntKompass = 0;
123
   }
124
   }
124
 }
125
 }
125
}
126
}
126
 
127
 
127
 
128
 
128
// -----------------------------------------------------------------------
129
// -----------------------------------------------------------------------
129
unsigned int SetDelay (unsigned int t)
130
unsigned int SetDelay (unsigned int t)
130
{
131
{
131
//  TIMSK0 &= ~_BV(TOIE0);
132
//  TIMSK0 &= ~_BV(TOIE0);
132
  return(CountMilliseconds + t + 1);
133
  return(CountMilliseconds + t + 1);
133
//  TIMSK0 |= _BV(TOIE0);
134
//  TIMSK0 |= _BV(TOIE0);
134
}
135
}
135
 
136
 
136
// -----------------------------------------------------------------------
137
// -----------------------------------------------------------------------
137
char CheckDelay(unsigned int t)
138
char CheckDelay(unsigned int t)
138
{
139
{
139
//  TIMSK0 &= ~_BV(TOIE0);
140
//  TIMSK0 &= ~_BV(TOIE0);
140
  return(((t - CountMilliseconds) & 0x8000) >> 9);
141
  return(((t - CountMilliseconds) & 0x8000) >> 9);
141
//  TIMSK0 |= _BV(TOIE0);
142
//  TIMSK0 |= _BV(TOIE0);
142
}
143
}
143
 
144
 
144
// -----------------------------------------------------------------------
145
// -----------------------------------------------------------------------
145
void Delay_ms(unsigned int w)
146
void Delay_ms(unsigned int w)
146
{
147
{
147
 unsigned int akt;
148
 unsigned int akt;
148
 akt = SetDelay(w);
149
 akt = SetDelay(w);
149
 while (!CheckDelay(akt));
150
 while (!CheckDelay(akt));
150
}
151
}
151
 
152
 
152
void Delay_ms_Mess(unsigned int w)
153
void Delay_ms_Mess(unsigned int w)
153
{
154
{
154
 unsigned int akt;
155
 unsigned int akt;
155
 akt = SetDelay(w);
156
 akt = SetDelay(w);
156
 while (!CheckDelay(akt)) if(AdReady) {AdReady = 0; ANALOG_ON;}
157
 while (!CheckDelay(akt)) if(AdReady) {AdReady = 0; ANALOG_ON;}
157
}
158
}
158
 
159
 
159
/*****************************************************/
160
/*****************************************************/
160
/*              Initialize Timer 2                   */
161
/*              Initialize Timer 2                   */
161
/*****************************************************/
162
/*****************************************************/
162
// The timer 2 is used to generate the PWM at PD7 (J7)
163
// The timer 2 is used to generate the PWM at PD7 (J7)
163
// to control a camera servo for nick compensation.
164
// to control a camera servo for nick compensation.
164
void TIMER2_Init(void)
165
void TIMER2_Init(void)
165
{
166
{
166
        uint8_t sreg = SREG;
167
        uint8_t sreg = SREG;
167
 
168
 
168
/******************************************************************************************************************
169
/******************************************************************************************************************
169
Arthur P: Added initialization of the CameraShutterCycle value here as this routine is only
170
Arthur P: Added initialization of the CameraShutterCycle value here as this routine is only
170
called once. This retains all code changes in timer0.c. If (parameter 8 & 127) > 0 then the user
171
called once. This retains all code changes in timer0.c. If (parameter 8 & 127) > 0 then the user
171
has set a value for the cycle. CameraShuytterCycle == 5x (Para8 & 127) to get approx 0.1sec increments.
172
has set a value for the cycle. CameraShuytterCycle == 5x (Para8 & 127) to get approx 0.1sec increments.
172
090807: Arthur P.: Removed the shutter cycle parts as they may be impacting timing loops.
173
090807: Arthur P.: Removed the shutter cycle parts as they may be impacting timing loops.
173
20100804 Arthur P.: Reactivate shutter cycle counters. Modified to use the lower 7 bits of
174
20100804 Arthur P.: Reactivate shutter cycle counters. Modified to use the lower 7 bits of
174
user parameter 8 (bit 8 is used for enabling the external HEF4017).
175
user parameter 8 (bit 8 is used for enabling the external HEF4017).
175
CameraShutterCycle = Parameter_UserParam6;
176
CameraShutterCycle = Parameter_UserParam6;
176
******************************************************************************************************************/
177
******************************************************************************************************************/
177
 
178
 
178
        CameraShutterCycle = 5 *  (Parameter_UserParam8 & 127);
179
        CameraShutterCycle = 5 *  (Parameter_UserParam8 & 127);
179
       
180
       
180
/******************************************************************************************************************
181
/******************************************************************************************************************
181
Arthur P: End of changes to Timer2 function.
182
Arthur P: End of changes to Timer2 function.
182
******************************************************************************************************************/
183
******************************************************************************************************************/
183
 
184
 
184
 
185
 
185
        // disable all interrupts before reconfiguration
186
        // disable all interrupts before reconfiguration
186
        cli();
187
        cli();
187
 
188
 
188
        PORTD &= ~(1<<PORTD7);  // set PD7 to low
189
        PORTD &= ~(1<<PORTD7);  // set PD7 to low
189
 
190
 
190
        DDRC  |= (1<<DDC6);     // set PC6 as output (Reset for HEF4017)
191
        DDRC  |= (1<<DDC6);     // set PC6 as output (Reset for HEF4017)
191
    HEF4017R_ON;
192
    HEF4017R_ON;
192
        // Timer/Counter 2 Control Register A
193
        // Timer/Counter 2 Control Register A
193
 
194
 
194
        // Timer Mode is FastPWM with timer reload at OCR2A (Bits: WGM22 = 1, WGM21 = 1, WGM20 = 1)
195
        // Timer Mode is FastPWM with timer reload at OCR2A (Bits: WGM22 = 1, WGM21 = 1, WGM20 = 1)
195
    // PD7: Normal port operation, OC2A disconnected, (Bits: COM2A1 = 0, COM2A0 = 0)
196
    // PD7: Normal port operation, OC2A disconnected, (Bits: COM2A1 = 0, COM2A0 = 0)
196
    // PD6: Normal port operation, OC2B disconnected, (Bits: COM2B1 = 0, COM2B0 = 0)
197
    // PD6: Normal port operation, OC2B disconnected, (Bits: COM2B1 = 0, COM2B0 = 0)
197
        TCCR2A &= ~((1<<COM2A1)|(1<<COM2A0)|(1<<COM2B1)|(1<<COM2B0));
198
        TCCR2A &= ~((1<<COM2A1)|(1<<COM2A0)|(1<<COM2B1)|(1<<COM2B0));
198
    TCCR2A |= (1<<WGM21)|(1<<WGM20);
199
    TCCR2A |= (1<<WGM21)|(1<<WGM20);
199
 
200
 
200
    // Timer/Counter 2 Control Register B
201
    // Timer/Counter 2 Control Register B
201
 
202
 
202
        // Set clock divider for timer 2 to SYSKLOCK/32 = 20MHz / 32 = 625 kHz
203
        // Set clock divider for timer 2 to SYSKLOCK/32 = 20MHz / 32 = 625 kHz
203
        // The timer increments from 0x00 to 0xFF with an update rate of 625 kHz or 1.6 us
204
        // The timer increments from 0x00 to 0xFF with an update rate of 625 kHz or 1.6 us
204
        // hence the timer overflow interrupt frequency is 625 kHz / 256 = 2.44 kHz or 0.4096 ms
205
        // hence the timer overflow interrupt frequency is 625 kHz / 256 = 2.44 kHz or 0.4096 ms
205
 
206
 
206
    // divider 32 (Bits: CS022 = 0, CS21 = 1, CS20 = 1)
207
    // divider 32 (Bits: CS022 = 0, CS21 = 1, CS20 = 1)
207
        TCCR2B &= ~((1<<FOC2A)|(1<<FOC2B)|(1<<CS22));
208
        TCCR2B &= ~((1<<FOC2A)|(1<<FOC2B)|(1<<CS22));
208
    TCCR2B |= (1<<CS21)|(1<<CS20)|(1<<WGM22);
209
    TCCR2B |= (1<<CS21)|(1<<CS20)|(1<<WGM22);
209
 
210
 
210
        // Initialize the Timer/Counter 2 Register
211
        // Initialize the Timer/Counter 2 Register
211
    TCNT2 = 0;
212
    TCNT2 = 0;
212
 
213
 
213
        // Initialize the Output Compare Register A used for PWM generation on port PD7.
214
        // Initialize the Output Compare Register A used for PWM generation on port PD7.
214
        OCR2A = 255;
215
        OCR2A = 255;
215
        TCCR2A |= (1<<COM2A1); // set or clear at compare match depends on value of COM2A0
216
        TCCR2A |= (1<<COM2A1); // set or clear at compare match depends on value of COM2A0
216
 
217
 
217
        // Timer/Counter 2 Interrupt Mask Register
218
        // Timer/Counter 2 Interrupt Mask Register
218
        // Enable timer output compare match A Interrupt only
219
        // Enable timer output compare match A Interrupt only
219
        TIMSK2 &= ~((1<<OCIE2B)|(1<<TOIE2));
220
        TIMSK2 &= ~((1<<OCIE2B)|(1<<TOIE2));
220
        TIMSK2 |= (1<<OCIE2A);
221
        TIMSK2 |= (1<<OCIE2A);
221
 
222
 
222
    SREG = sreg;
223
    SREG = sreg;
223
}
224
}
224
 
225
 
225
//----------------------------
226
//----------------------------
226
void Timer_Init(void)
227
void Timer_Init(void)
227
{
228
{
228
    tim_main = SetDelay(10);
229
    tim_main = SetDelay(10);
229
    TCCR0B = CK8;
230
    TCCR0B = CK8;
230
    TCCR0A = (1<<COM0A1)|(1<<COM0B1)|3;//fast PWM
231
    TCCR0A = (1<<COM0A1)|(1<<COM0B1)|3;//fast PWM
231
    OCR0A =  0;
232
    OCR0A =  0;
232
    OCR0B = 180;
233
    OCR0B = 180;
233
    TCNT0 = (unsigned char)-TIMER_RELOAD_VALUE;  // reload
234
    TCNT0 = (unsigned char)-TIMER_RELOAD_VALUE;  // reload
234
    //OCR1  = 0x00;
235
    //OCR1  = 0x00;
235
    TIMSK0 |= _BV(TOIE0);
236
    TIMSK0 |= _BV(TOIE0);
236
}
237
}
237
 
238
 
238
 
239
 
239
/*****************************************************/
240
/*****************************************************/
240
/*              Control Servo Position               */
241
/*              Control Servo Position               */
241
/*****************************************************/
242
/*****************************************************/
242
 
243
 
243
 
244
 
244
void CalculateServo(void)
245
void CalculateServo(void)
245
{
246
{
246
 signed char cosinus, sinus;
247
 signed char cosinus, sinus;
247
 signed long nick, roll;
248
 signed long nick, roll;
248
 
249
 
249
        cosinus = sintab[EE_Parameter.CamOrientation + 6];
250
        cosinus = sintab[EE_Parameter.CamOrientation + 6];
250
        sinus = sintab[EE_Parameter.CamOrientation];
251
        sinus = sintab[EE_Parameter.CamOrientation];
251
 
252
 
252
  if(CalculateServoSignals == 1)
253
  if(CalculateServoSignals == 1)
253
   {
254
   {
254
                nick = (cosinus * IntegralNick) / 128L - (sinus * IntegralRoll) / 128L;
255
                nick = (cosinus * IntegralNick) / 128L - (sinus * IntegralRoll) / 128L;
255
                nick = ((long)EE_Parameter.ServoNickComp * nick) / 512L;
256
                nick = ((long)EE_Parameter.ServoNickComp * nick) / 512L;
256
                ServoNickOffset += ((int16_t)Parameter_ServoNickControl * (MULTIPLYER*16) - ServoNickOffset) / EE_Parameter.ServoManualControlSpeed;
257
                ServoNickOffset += ((int16_t)Parameter_ServoNickControl * (MULTIPLYER*16) - ServoNickOffset) / EE_Parameter.ServoManualControlSpeed;
257
                ServoNickValue = ServoNickOffset / 16; // offset (Range from 0 to 255 * 3 = 765)
258
                ServoNickValue = ServoNickOffset / 16; // offset (Range from 0 to 255 * 3 = 765)
258
                if(EE_Parameter.ServoCompInvert & 0x01)
259
                if(EE_Parameter.ServoCompInvert & 0x01)
259
                {       // inverting movement of servo
260
                {       // inverting movement of servo
260
                        ServoNickValue += nick;//(int16_t)( ( (int32_t)EE_Parameter.ServoNickComp * nick) / (256L) );
261
                        ServoNickValue += nick;//(int16_t)( ( (int32_t)EE_Parameter.ServoNickComp * nick) / (256L) );
261
                }
262
                }
262
                else
263
                else
263
                {       // non inverting movement of servo
264
                {       // non inverting movement of servo
264
                        ServoNickValue -= nick;
265
                        ServoNickValue -= nick;
265
                }
266
                }
266
                // limit servo value to its parameter range definition
267
                // limit servo value to its parameter range definition
267
                if(ServoNickValue < ((int16_t)EE_Parameter.ServoNickMin * MULTIPLYER) )
268
                if(ServoNickValue < ((int16_t)EE_Parameter.ServoNickMin * MULTIPLYER) )
268
                {
269
                {
269
                        ServoNickValue = (int16_t)EE_Parameter.ServoNickMin * MULTIPLYER;
270
                        ServoNickValue = (int16_t)EE_Parameter.ServoNickMin * MULTIPLYER;
270
                }
271
                }
271
                else
272
                else
272
                if(ServoNickValue > ((int16_t)EE_Parameter.ServoNickMax * MULTIPLYER) )
273
                if(ServoNickValue > ((int16_t)EE_Parameter.ServoNickMax * MULTIPLYER) )
273
                {
274
                {
274
                        ServoNickValue = (int16_t)EE_Parameter.ServoNickMax * MULTIPLYER;
275
                        ServoNickValue = (int16_t)EE_Parameter.ServoNickMax * MULTIPLYER;
275
                }
276
                }
-
 
277
/******************************************************************************************************************
-
 
278
Arthur P: Modified the code to check the value of parameter 8. If 128 or higher then a HEF4017 is
-
 
279
expected and will be used. Else J7 and J9 are seen as separate normal outputs.
-
 
280
if((PlatinenVersion < 20)
-
 
281
20100802 Inserted changes into v.0.80d code. This function did not exist prior to v.082. Without
-
 
282
the changes the roll servo does not work, while shutter and nick servo output do work.
-
 
283
******************************************************************************************************************/    
-
 
284
 
-
 
285
//      if(PlatinenVersion < 20)
-
 
286
 
276
                if(PlatinenVersion < 20) CalculateServoSignals = 0; else CalculateServoSignals++;
287
        if((PlatinenVersion < 20) && (Parameter_UserParam8 < 128 ))
-
 
288
/******************************************************************************************************************
-
 
289
Arthur P: End of modification ot if statement. 
-
 
290
******************************************************************************************************************/    
-
 
291
                {
-
 
292
                        CalculateServoSignals = 0;
-
 
293
                }
-
 
294
                else
-
 
295
                {
-
 
296
                        CalculateServoSignals++;
-
 
297
                }
277
        }
298
        }
278
        else
299
        else
279
        {
300
        {
280
        roll = (cosinus * IntegralRoll) / 128L + (sinus * IntegralNick) / 128L;
301
        roll = (cosinus * IntegralRoll) / 128L + (sinus * IntegralNick) / 128L;
281
        roll = ((long)EE_Parameter.ServoRollComp * roll) / 512L;
302
        roll = ((long)EE_Parameter.ServoRollComp * roll) / 512L;
282
                ServoRollOffset += ((int16_t)Parameter_ServoRollControl * (MULTIPLYER*16) - ServoRollOffset) / EE_Parameter.ServoManualControlSpeed;
303
                ServoRollOffset += ((int16_t)Parameter_ServoRollControl * (MULTIPLYER*16) - ServoRollOffset) / EE_Parameter.ServoManualControlSpeed;
283
                ServoRollValue = ServoRollOffset/16; // offset (Range from 0 to 255 * 3 = 765)
304
                ServoRollValue = ServoRollOffset/16; // offset (Range from 0 to 255 * 3 = 765)
284
                if(EE_Parameter.ServoCompInvert & 0x02)
305
                if(EE_Parameter.ServoCompInvert & 0x02)
285
                {       // inverting movement of servo
306
                {       // inverting movement of servo
286
                        ServoRollValue += roll;
307
                        ServoRollValue += roll;
287
                }
308
                }
288
                else
309
                else
289
                {       // non inverting movement of servo
310
                {       // non inverting movement of servo
290
                        ServoRollValue -= roll;
311
                        ServoRollValue -= roll;
291
                }
312
                }
292
                // limit servo value to its parameter range definition
313
                // limit servo value to its parameter range definition
293
                if(ServoRollValue < ((int16_t)EE_Parameter.ServoRollMin * MULTIPLYER) )
314
                if(ServoRollValue < ((int16_t)EE_Parameter.ServoRollMin * MULTIPLYER) )
294
                {
315
                {
295
                        ServoRollValue = (int16_t)EE_Parameter.ServoRollMin * MULTIPLYER;
316
                        ServoRollValue = (int16_t)EE_Parameter.ServoRollMin * MULTIPLYER;
296
                }
317
                }
297
                else
318
                else
298
                if(ServoRollValue > ((int16_t)EE_Parameter.ServoRollMax * MULTIPLYER) )
319
                if(ServoRollValue > ((int16_t)EE_Parameter.ServoRollMax * MULTIPLYER) )
299
                {
320
                {
300
                        ServoRollValue = (int16_t)EE_Parameter.ServoRollMax * MULTIPLYER;
321
                        ServoRollValue = (int16_t)EE_Parameter.ServoRollMax * MULTIPLYER;
301
                }
322
                }
302
                CalculateServoSignals = 0;
323
                CalculateServoSignals = 0;
303
        }
324
        }
304
}
325
}
305
 
326
 
306
ISR(TIMER2_COMPA_vect)
327
ISR(TIMER2_COMPA_vect)
307
{
328
{
308
        // frame len 22.5 ms = 14063 * 1.6 us
329
        // frame len 22.5 ms = 14063 * 1.6 us
309
        // stop pulse: 0.3 ms = 188 * 1.6 us
330
        // stop pulse: 0.3 ms = 188 * 1.6 us
310
        // min servo pulse: 0.6 ms =  375 * 1.6 us
331
        // min servo pulse: 0.6 ms =  375 * 1.6 us
311
        // max servo pulse: 2.4 ms = 1500 * 1.6 us
332
        // max servo pulse: 2.4 ms = 1500 * 1.6 us
312
        // resolution: 1500 - 375 = 1125 steps
333
        // resolution: 1500 - 375 = 1125 steps
313
 
334
 
314
        #define IRS_RUNTIME 127
335
        #define IRS_RUNTIME 127
315
        #define PPM_STOPPULSE 188
336
        #define PPM_STOPPULSE 188
316
    #define PPM_FRAMELEN (1757 * EE_Parameter.ServoNickRefresh)
337
    #define PPM_FRAMELEN (1757 * EE_Parameter.ServoNickRefresh)
317
        #define MINSERVOPULSE 375
338
        #define MINSERVOPULSE 375
318
        #define MAXSERVOPULSE 1500
339
        #define MAXSERVOPULSE 1500
319
        #define SERVORANGE (MAXSERVOPULSE - MINSERVOPULSE)
340
        #define SERVORANGE (MAXSERVOPULSE - MINSERVOPULSE)
320
 
341
 
321
        static uint8_t  PulseOutput = 0;
342
        static uint8_t  PulseOutput = 0;
322
        static uint16_t ServoFrameTime = 0;
343
        static uint16_t ServoFrameTime = 0;
323
        static uint8_t  ServoIndex = 0;
344
        static uint8_t  ServoIndex = 0;
324
 
345
 
325
 
346
 
326
/******************************************************************************************************************
347
/******************************************************************************************************************
327
Arthur P: Modified the code to check the value of parameter 8. If 128 or higher then a HEF4017 is
348
Arthur P: Modified the code to check the value of parameter 8. If 128 or higher then a HEF4017 is
328
expected and will be used. Else J7 and J9 are seen as separate normal outputs.
349
expected and will be used. Else J7 and J9 are seen as separate normal outputs.
329
if((PlatinenVersion < 20)
350
if((PlatinenVersion < 20)
330
091114. Inserted same changes into v.0.76g code.
351
091114. Inserted same changes into v.0.76g code.
331
20100802 Inserted same changes into v.0.80d code.
352
20100802 Inserted same changes into v.0.80d code.
332
******************************************************************************************************************/    
353
******************************************************************************************************************/    
333
 
354
 
334
//      if(PlatinenVersion < 20)
355
//      if(PlatinenVersion < 20)
335
 
356
 
336
        if((PlatinenVersion < 20) && (Parameter_UserParam8 < 128 ))
357
        if((PlatinenVersion < 20) && (Parameter_UserParam8 < 128 ))
337
/******************************************************************************************************************
358
/******************************************************************************************************************
338
Arthur P: End of modification ot if statement. 
359
Arthur P: End of modification ot if statement. 
339
******************************************************************************************************************/    
360
******************************************************************************************************************/    
340
 
361
 
341
        {
362
        {
342
                //---------------------------
363
                //---------------------------
343
                // Nick servo state machine
364
                // Nick servo state machine
344
                //---------------------------
365
                //---------------------------
345
                if(!PulseOutput) // pulse output complete
366
                if(!PulseOutput) // pulse output complete
346
                {
367
                {
347
                        if(TCCR2A & (1<<COM2A0)) // we had a low pulse
368
                        if(TCCR2A & (1<<COM2A0)) // we had a low pulse
348
                        {
369
                        {
349
                                TCCR2A &= ~(1<<COM2A0);// make a high pulse
370
                                TCCR2A &= ~(1<<COM2A0);// make a high pulse
350
                                RemainingPulse  = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms
371
                                RemainingPulse  = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms
351
                                RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
372
                                RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
352
                                // range servo pulse width
373
                                // range servo pulse width
353
                                if(RemainingPulse > MAXSERVOPULSE )                     RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit
374
                                if(RemainingPulse > MAXSERVOPULSE )                     RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit
354
                                else if(RemainingPulse < MINSERVOPULSE )        RemainingPulse = MINSERVOPULSE; // lower servo pulse limit
375
                                else if(RemainingPulse < MINSERVOPULSE )        RemainingPulse = MINSERVOPULSE; // lower servo pulse limit
355
                                // accumulate time for correct update rate
376
                                // accumulate time for correct update rate
356
                                ServoFrameTime = RemainingPulse;
377
                                ServoFrameTime = RemainingPulse;
357
                        }
378
                        }
358
                        else // we had a high pulse
379
                        else // we had a high pulse
359
                        {
380
                        {
360
                                TCCR2A |= (1<<COM2A0); // make a low pulse
381
                                TCCR2A |= (1<<COM2A0); // make a low pulse
361
                                RemainingPulse = PPM_FRAMELEN - ServoFrameTime;
382
                                RemainingPulse = PPM_FRAMELEN - ServoFrameTime;
362
                                CalculateServoSignals = 1;
383
                                CalculateServoSignals = 1;
363
                        }
384
                        }
364
                        // set pulse output active
385
                        // set pulse output active
365
                        PulseOutput = 1;
386
                        PulseOutput = 1;
366
                }
387
                }
367
        } // EOF Nick servo state machine
388
        } // EOF Nick servo state machine
368
        else
389
        else
369
        {
390
        {
370
                //-----------------------------------------------------
391
                //-----------------------------------------------------
371
                // PPM state machine, onboard demultiplexed by HEF4017
392
                // PPM state machine, onboard demultiplexed by HEF4017
372
                //-----------------------------------------------------
393
                //-----------------------------------------------------
373
                if(!PulseOutput) // pulse output complete
394
                if(!PulseOutput) // pulse output complete
374
                {
395
                {
375
                        if(TCCR2A & (1<<COM2A0)) // we had a low pulse
396
                        if(TCCR2A & (1<<COM2A0)) // we had a low pulse
376
                        {
397
                        {
377
                                TCCR2A &= ~(1<<COM2A0);// make a high pulse
398
                                TCCR2A &= ~(1<<COM2A0);// make a high pulse
378
 
399
 
379
                                if(ServoIndex == 0) // if we are at the sync gap
400
                                if(ServoIndex == 0) // if we are at the sync gap
380
                                {
401
                                {
381
                                        RemainingPulse = PPM_FRAMELEN - ServoFrameTime; // generate sync gap by filling time to full frame time
402
                                        RemainingPulse = PPM_FRAMELEN - ServoFrameTime; // generate sync gap by filling time to full frame time
382
                                        ServoFrameTime = 0; // reset servo frame time
403
                                        ServoFrameTime = 0; // reset servo frame time
383
                                        HEF4017R_ON; // enable HEF4017 reset
404
                                        HEF4017R_ON; // enable HEF4017 reset
384
                                }
405
                                }
385
                                else // servo channels
406
                                else // servo channels
386
                                {
407
                                {
387
                                        RemainingPulse  = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms
408
                                        RemainingPulse  = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms
388
                                        switch(ServoIndex) // map servo channels
409
                                        switch(ServoIndex) // map servo channels
389
                                        {
410
                                        {
390
                                                case 1: // Nick Compensation Servo
411
                                                case 1: // Nick Compensation Servo
391
                                                        RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
412
                                                        RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
392
                                                        break;
413
                                                        break;
393
                                         case 2: // Roll Compensation Servo
414
                                            case 2: // Roll Compensation Servo
394
                                                        RemainingPulse += ServoRollValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
415
                                                        RemainingPulse += ServoRollValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position
395
                                                        break;
416
                                                        break;
396
/******************************************************************************************************************
417
/******************************************************************************************************************
397
Arthur P: Shutter Servo including interval control over parameter 5 and 6.
418
Arthur P: Shutter Servo including interval control over parameter 5 and 6.
398
091114 Inserted same modification into v.0.76g code, removing previously REM-ed out modified parts.
419
091114 Inserted same modification into v.0.76g code, removing previously REM-ed out modified parts.
399
20100802 Inserted same modification into v.0.76g code, removing previously REM-ed out modified parts.
420
20100802 Inserted same modification into v.0.76g code, removing previously REM-ed out modified parts.
400
Modified to use lower 7 bits of user parameter 7.
421
Modified to use lower 7 bits of user parameter 7.
401
******************************************************************************************************************/
422
******************************************************************************************************************/
402
                                         case 3:
423
                                         case 3:
403
//                                                      RemainingPulse += ((int16_t)Parameter_Servo3 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
424
//                                                      RemainingPulse += ((int16_t)Parameter_Servo3 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
404
//                                                      break;
425
//                                                      break;
405
 
426
 
406
                                                       
427
                                                       
407
                                                        if(PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] < -32)
428
                                                        if(PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] < -32)
408
                                                        {
429
                                                        {
409
                                                        // Set servo to null position, turning camera off.
430
                                                        // Set servo to null position, turning camera off.
410
                                                                RemainingPulse  = MINSERVOPULSE;
431
                                                                RemainingPulse  = MINSERVOPULSE;
411
                                                        }
432
                                                        }
412
                                                        else
433
                                                        else
413
                                                        {
434
                                                        {
414
                                                                // 090807: Arthur P.: Removed the shutter cycle parts as they may be impacting timing loops.
435
                                                                // 090807: Arthur P.: Removed the shutter cycle parts as they may be impacting timing loops.
415
                                                                // 20100804 Reactived shutter interval timer capability.
436
                                                                // 20100804 Reactived shutter interval timer capability.
416
                                                                if(PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] > 32)
437
                                                                if(PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] > 32)
417
                                                                // Top position on a 3 position switch which runs from -127 to +127
438
                                                                // Top position on a 3 position switch which runs from -127 to +127
418
                                                                {
439
                                                                {
419
       
440
       
420
                                                                        RemainingPulse  = MINSERVOPULSE + SERVORANGE;
441
                                                                        RemainingPulse  = MINSERVOPULSE + SERVORANGE;
421
                                                                }
442
                                                                }
422
                                                                else
443
                                                                else
423
                                                                {
444
                                                                {
424
                                                                        // Cycle shutter servo between 50% on and off depending upon CameraShutterCycleCounter
445
                                                                        // Cycle shutter servo between 50% on and off depending upon CameraShutterCycleCounter
425
                                                                        // If CameraShutterCylce < 50 then default to continuous shoot.
446
                                                                        // If CameraShutterCylce < 50 then default to continuous shoot.
426
                                                                        if(CameraShutterCycle < 50 )    // == 5x the minimum value of userpara8 lower 7 bits
447
                                                                        if(CameraShutterCycle < 50 )    // == 5x the minimum value of userpara8 lower 7 bits
427
                                                                        {
448
                                                                        {
428
                                                                                RemainingPulse  = MINSERVOPULSE + SERVORANGE/2;
449
                                                                                RemainingPulse  = MINSERVOPULSE + SERVORANGE/2;
429
                                                                        }
450
                                                                        }
430
                                                                        else
451
                                                                        else
431
                                                                        {      
452
                                                                        {      
432
                                                                                if(CameraShutterCycleCounter == CameraShutterCycle)
453
                                                                                if(CameraShutterCycleCounter == CameraShutterCycle)
433
                                                                                {
454
                                                                                {
434
                                                                                        // Shutter on
455
                                                                                        // Shutter on
435
                                                                                        CameraShutterCycleCounter = 0;
456
                                                                                        CameraShutterCycleCounter = 0;
436
                                                                                        RemainingPulse  = MINSERVOPULSE + SERVORANGE/2;
457
                                                                                        RemainingPulse  = MINSERVOPULSE + SERVORANGE/2;
437
                                                                                }
458
                                                                                }
438
                                                                                else
459
                                                                                else
439
                                                                                {
460
                                                                                {
440
                                                                                        // Leave on for at least 20 cycles or 0.2 seconds to allow 
461
                                                                                        // Leave on for at least 20 cycles or 0.2 seconds to allow 
441
                                                                                        // the camera to properly trigger, turn off if past 0.2 sec.
462
                                                                                        // the camera to properly trigger, turn off if past 0.2 sec.
442
                                                                                        // For now this is actually set via para5 to allow for a long enough
463
                                                                                        // For now this is actually set via para5 to allow for a long enough
443
                                                                                        // shutter pulse for different cameras. Once it is clear what value
464
                                                                                        // shutter pulse for different cameras. Once it is clear what value
444
                                                                                        // works, this can be changed to a hardcoded value.
465
                                                                                        // works, this can be changed to a hardcoded value.
445
                                                                                        CameraShutterCycleCounter++;
466
                                                                                        CameraShutterCycleCounter++;
446
                                                                                        if(CameraShutterCycleCounter == CameraShutterCycleOnCount)
467
                                                                                        if(CameraShutterCycleCounter == CameraShutterCycleOnCount)
447
                                                                                        {
468
                                                                                        {
448
                                                                                                // Shutter off
469
                                                                                                // Shutter off
449
                                                                                                RemainingPulse = MINSERVOPULSE;
470
                                                                                                RemainingPulse = MINSERVOPULSE;
450
                                                                                        }
471
                                                                                        }
451
                                                                                }
472
                                                                                }
452
                                                                        }
473
                                                                        }
453
                                                                }      
474
                                                                }      
454
                                                        }
475
                                                        }
455
                                                        break;
476
                                                        break;
456
/******************************************************************************************************************
477
/******************************************************************************************************************
457
Arthur P: End of modified shutter servo control (via HEF4017) and of modifications to timer0.c.
478
Arthur P: End of modified shutter servo control (via HEF4017) and of modifications to timer0.c.
458
******************************************************************************************************************/
479
******************************************************************************************************************/
459
 
480
 
460
                                         case 4:
481
                                         case 4:
461
                                                        RemainingPulse += ((int16_t)Parameter_Servo4 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
482
                                                        RemainingPulse += ((int16_t)Parameter_Servo4 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
462
                                                        break;
483
                                                        break;
463
                                         case 5:
484
                                         case 5:
464
                                                        RemainingPulse += ((int16_t)Parameter_Servo5 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
485
                                                        RemainingPulse += ((int16_t)Parameter_Servo5 * MULTIPLYER) - (256 / 2) * MULTIPLYER;
465
                                                        break;
486
                                                        break;
466
                                                default: // other servo channels
487
                                                default: // other servo channels
467
                                                        RemainingPulse += 2 * PPM_in[ServoIndex]; // add channel value, factor of 2 because timer 1 increments 3.2µs
488
                                                        RemainingPulse += 2 * PPM_in[ServoIndex]; // add channel value, factor of 2 because timer 1 increments 3.2µs
468
                                                        break;
489
                                                        break;
469
                                        }
490
                                        }
470
                                        // range servo pulse width
491
                                        // range servo pulse width
471
                                        if(RemainingPulse > MAXSERVOPULSE )                     RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit
492
                                        if(RemainingPulse > MAXSERVOPULSE )                     RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit
472
                                        else if(RemainingPulse < MINSERVOPULSE )        RemainingPulse = MINSERVOPULSE; // lower servo pulse limit
493
                                        else if(RemainingPulse < MINSERVOPULSE )        RemainingPulse = MINSERVOPULSE; // lower servo pulse limit
473
                                        // substract stop pulse width
494
                                        // substract stop pulse width
474
                                        RemainingPulse -= PPM_STOPPULSE;
495
                                        RemainingPulse -= PPM_STOPPULSE;
475
                                        // accumulate time for correct sync gap
496
                                        // accumulate time for correct sync gap
476
                                        ServoFrameTime += RemainingPulse;
497
                                        ServoFrameTime += RemainingPulse;
477
                                }
498
                                }
478
                        }
499
                        }
479
                        else // we had a high pulse
500
                        else // we had a high pulse
480
                        {
501
                        {
481
                                TCCR2A |= (1<<COM2A0); // make a low pulse
502
                                TCCR2A |= (1<<COM2A0); // make a low pulse
482
                                // set pulsewidth to stop pulse width
503
                                // set pulsewidth to stop pulse width
483
                                RemainingPulse = PPM_STOPPULSE;
504
                                RemainingPulse = PPM_STOPPULSE;
484
                                // accumulate time for correct sync gap
505
                                // accumulate time for correct sync gap
485
                                ServoFrameTime += RemainingPulse;
506
                                ServoFrameTime += RemainingPulse;
486
                                if((ServoActive && SenderOkay > 50) || ServoActive == 2) HEF4017R_OFF; // disable HEF4017 reset
507
                                if((ServoActive && SenderOkay > 50) || ServoActive == 2) HEF4017R_OFF; // disable HEF4017 reset
487
                                else HEF4017R_ON;
508
                                else HEF4017R_ON;
488
                                ServoIndex++; // change to next servo channel
509
                                ServoIndex++; // change to next servo channel
489
                                if(ServoIndex > EE_Parameter.ServoNickRefresh)
510
                                if(ServoIndex > EE_Parameter.ServoNickRefresh)
490
                                  {
511
                                  {
491
                                    CalculateServoSignals = 1;
512
                                    CalculateServoSignals = 1;
492
                                        ServoIndex = 0; // reset to the sync gap
513
                                        ServoIndex = 0; // reset to the sync gap
493
                                  }
514
                                  }
494
                        }
515
                        }
495
                        // set pulse output active
516
                        // set pulse output active
496
                        PulseOutput = 1;
517
                        PulseOutput = 1;
497
                }
518
                }
498
        } // EOF PPM state machine
519
        } // EOF PPM state machine
499
 
520
 
500
        // General pulse output generator
521
        // General pulse output generator
501
        if(RemainingPulse > (255 + IRS_RUNTIME))
522
        if(RemainingPulse > (255 + IRS_RUNTIME))
502
        {
523
        {
503
                OCR2A = 255;
524
                OCR2A = 255;
504
                RemainingPulse -= 255;
525
                RemainingPulse -= 255;
505
        }
526
        }
506
        else
527
        else
507
        {
528
        {
508
                if(RemainingPulse > 255) // this is the 2nd last part
529
                if(RemainingPulse > 255) // this is the 2nd last part
509
                {
530
                {
510
                        if((RemainingPulse - 255) < IRS_RUNTIME)
531
                        if((RemainingPulse - 255) < IRS_RUNTIME)
511
                        {
532
                        {
512
                                OCR2A = 255 - IRS_RUNTIME;
533
                                OCR2A = 255 - IRS_RUNTIME;
513
                                RemainingPulse -= 255 - IRS_RUNTIME;
534
                                RemainingPulse -= 255 - IRS_RUNTIME;
514
 
535
 
515
                        }
536
                        }
516
                        else // last part > ISR_RUNTIME
537
                        else // last part > ISR_RUNTIME
517
                        {
538
                        {
518
                                OCR2A = 255;
539
                                OCR2A = 255;
519
                                RemainingPulse -= 255;
540
                                RemainingPulse -= 255;
520
                        }
541
                        }
521
                }
542
                }
522
                else // this is the last part
543
                else // this is the last part
523
                {
544
                {
524
                        OCR2A = RemainingPulse;
545
                        OCR2A = RemainingPulse;
525
                        RemainingPulse = 0;
546
                        RemainingPulse = 0;
526
                        PulseOutput = 0; // trigger to stop pulse
547
                        PulseOutput = 0; // trigger to stop pulse
527
                }
548
                }
528
        } // EOF general pulse output generator
549
        } // EOF general pulse output generator
529
}
550
}
530
 
551