12
12
13
13
#define US_TO_TICK (x ) ((uint16_t)x / 5)
14
14
#define TICK_TO_US (x ) (x * 5)
15
- #define TICKS_BETWEEN_EDGES US_TO_TICK(125)
15
+ #define TICKS_BETWEEN_EDGES US_TO_TICK(US_BETWEEN_EDGES)
16
+ #define NUM_SERVOS_EXTRA (NUM_SERVO_PHASES * SERVOS_PER_PHASE)
16
17
static void calculate_phase_steps (uint8_t phase );
17
18
18
19
static const uint8_t servo_bit_mapping [] = {15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 0 , 1 , 2 , 3 };
@@ -26,7 +27,7 @@ typedef struct {
26
27
uint16_t pulse ; // in timer ticks
27
28
} servo_t ;
28
29
29
- static servo_t servo_state [NUM_SERVOS ] = {};
30
+ static servo_t servo_state [NUM_SERVOS_EXTRA ] = {};
30
31
static servo_step_t servo_steps [NUM_SERVO_PHASES ][SERVO_STEPS_PER_PHASE ] = { 0 };
31
32
32
33
// loaded from servo_steps at the start of each phase
@@ -56,7 +57,7 @@ static void init_timer(void) {
56
57
57
58
void servo_init (void ) {
58
59
// initialise servo state indexes
59
- for (uint8_t i = 0 ; i < NUM_SERVOS ; i ++ ) {
60
+ for (uint8_t i = 0 ; i < NUM_SERVOS_EXTRA ; i ++ ) {
60
61
servo_state [i ].idx = i ;
61
62
servo_state [i ].enabled = false;
62
63
servo_state [i ].pulse = US_TO_TICK (MIN_SERVO_PULSE );
@@ -184,7 +185,7 @@ static void calculate_phase_steps(uint8_t phase) {
184
185
sorted_servo_steps [step ].rising = true;
185
186
if (step == (SERVOS_PER_PHASE - 1 )) {
186
187
// this gap is the remaining delay before the first falling edge
187
- sorted_servo_steps [step ].next_steps = sorted_servo_states [0 ].pulse - (TICKS_BETWEEN_EDGES * 3 );
188
+ sorted_servo_steps [step ].next_steps = sorted_servo_states [0 ].pulse - (TICKS_BETWEEN_EDGES * ( SERVOS_PER_PHASE - 1 ) );
188
189
} else {
189
190
sorted_servo_steps [step ].next_steps = TICKS_BETWEEN_EDGES ;
190
191
}
@@ -222,9 +223,15 @@ static void set_expander_output(uint16_t val) {
222
223
223
224
// setup transaction to GPIO register
224
225
i2c_start_message (I2C_EXPANDER_ADDR );
226
+ #if NUM_SERVOS > 8
225
227
i2c_send_byte (EXT_GPIOA );
226
228
i2c_send_byte ((uint8_t )(val & 0xff )); // A-reg first
227
229
i2c_send_byte ((uint8_t )((val >> 8 ) & 0xff ));
230
+ #else
231
+ // The first 8 servos are all in the upper byte
232
+ i2c_send_byte (EXT_GPIOA + 1 );
233
+ i2c_send_byte ((uint8_t )((val >> 8 ) & 0xff )); // B-reg only
234
+ #endif
228
235
i2c_stop_message ();
229
236
}
230
237
@@ -283,7 +290,7 @@ void tim1_cc_isr(void) {
283
290
}
284
291
}
285
292
286
- if (current_servo_step == (SERVO_STEPS_PER_PHASE - 1 )) {
293
+ if (current_servo_step == (SERVO_STEPS_PER_PHASE - 1 )) {
287
294
// this phase is complete, stop interrupts until the next phase
288
295
timer_disable_irq (TIM1 , TIM_DIER_CC1IE );
289
296
}
0 commit comments