31
31
#define SERVO_MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
32
32
#define SERVO_INVALID_INDEX (255 )
33
33
// Lower the timer ticks for finer resolution.
34
- #define SERVO_TIMER_TICK_US (100 )
35
34
#define SERVO_US_PER_CYCLE (20000 )
36
35
#define SERVO_IO_PORT_ADDR (pn ) &((R_PORT0 + ((uint32_t ) (R_PORT1 - R_PORT0) * (pn)))->PCNTR3)
37
- #define MIN_CYCLE_OFF_US 50
36
+ #define SERVO_MIN_CYCLE_OFF_US 50
38
37
39
38
// Internal Servo sturct to keep track of RA configuration.
40
39
typedef struct {
@@ -65,28 +64,25 @@ static uint32_t active_servos_mask = 0;
65
64
static uint32_t active_servos_mask_refresh = 0 ;
66
65
67
66
68
- static uint32_t usToticks (uint32_t time_us) {
69
- return (float (servo_ticks_per_cycle) / float (SERVO_US_PER_CYCLE) ) * time_us;
67
+ static uint32_t us_to_ticks (uint32_t time_us) {
68
+ return (( float ) servo_ticks_per_cycle / ( float ) SERVO_US_PER_CYCLE ) * time_us;
70
69
}
71
70
72
-
73
71
static int servo_timer_config (uint32_t period_us)
74
72
{
75
73
static bool configured = false ;
76
74
if (configured == false ) {
77
- // Configure and enable the servo timer, for full 20ms
75
+ // Configure and enable the servo timer.
78
76
uint8_t type = 0 ;
79
77
int8_t channel = FspTimer::get_available_timer (type);
80
78
if (channel != -1 ) {
81
- // lets initially configure the servo to 50ms
82
79
servo_timer.begin (TIMER_MODE_PERIODIC, type, channel,
83
80
1000000 .0f /period_us, 50 .0f , servo_timer_callback, nullptr );
84
81
servo_timer.set_period_buffer (false ); // disable period buffering
85
82
servo_timer.setup_overflow_irq (10 );
86
83
servo_timer.open ();
87
84
servo_timer.stop ();
88
-
89
- // Now lets see what the period;
85
+ // Read the timer's period count.
90
86
servo_ticks_per_cycle = servo_timer.get_period_raw ();
91
87
min_servo_cycle_low = usToticks (MIN_CYCLE_OFF_US);
92
88
@@ -118,11 +114,10 @@ static int servo_timer_stop()
118
114
return 0 ;
119
115
}
120
116
121
- inline static void updateClockPeriod (uint32_t period) {
117
+ inline static void servo_timer_set_period (uint32_t period) {
122
118
servo_timer.set_period (period);
123
119
}
124
120
125
-
126
121
void servo_timer_callback (timer_callback_args_t *args)
127
122
{
128
123
(void )args; // remove warning
@@ -132,28 +127,32 @@ void servo_timer_callback(timer_callback_args_t *args)
132
127
133
128
// See if we need to set a servo back low
134
129
if (channel_pin_set_high != 0xff ) {
135
- *ra_servos[channel_pin_set_high].io_port = ( uint32_t )( ra_servos[channel_pin_set_high].io_mask << 16 ) ;
130
+ *ra_servos[channel_pin_set_high].io_port = ra_servos[channel_pin_set_high].io_mask << 16 ;
136
131
}
137
132
138
133
// Find the next servo to set high
139
134
while (active_servos_mask_refresh) {
140
135
channel = __builtin_ctz (active_servos_mask_refresh);
141
136
if (ra_servos[channel].period_us ) {
142
- *ra_servos[channel].io_port = ( uint32_t ) ra_servos[channel].io_mask ;
143
- updateClockPeriod (ra_servos[channel].period_ticks );
137
+ *ra_servos[channel].io_port = ra_servos[channel].io_mask ;
138
+ servo_timer_set_period (ra_servos[channel].period_ticks );
144
139
channel_pin_set_high = channel;
145
- ticks_accum += ra_servos[channel_pin_set_high ].period_ticks ;
140
+ ticks_accum += ra_servos[channel ].period_ticks ;
146
141
active_servos_mask_refresh &= ~(1 << channel);
147
142
return ;
148
143
}
149
144
active_servos_mask_refresh &= ~(1 << channel);
150
145
}
151
-
152
- // Got to hear we finished processing all servos, now delay to start of next pass.
146
+ // Finished processing all servos, now delay to start of next pass.
153
147
ticks_accum += min_servo_cycle_low;
154
- uint32_t time_to_next_cycle = (servo_ticks_per_cycle > ticks_accum)? servo_ticks_per_cycle - ticks_accum : min_servo_cycle_low;
148
+ uint32_t time_to_next_cycle;
149
+ if (servo_ticks_per_cycle > ticks_accum) {
150
+ time_to_next_cycle = servo_ticks_per_cycle - ticks_accum;
151
+ } else {
152
+ time_to_next_cycle = min_servo_cycle_low;
153
+ }
155
154
ticks_accum = 0 ;
156
- updateClockPeriod (time_to_next_cycle);
155
+ servo_timer_set_period (time_to_next_cycle);
157
156
channel_pin_set_high = 0xff ;
158
157
active_servos_mask_refresh = active_servos_mask;
159
158
}
@@ -180,7 +179,7 @@ uint8_t Servo::attach(int pin, int min, int max)
180
179
return 0 ;
181
180
}
182
181
183
- // Configure and the timer
182
+ // Configure the servo timer.
184
183
if (servo_timer_config (SERVO_US_PER_CYCLE) != 0 ) {
185
184
return 0 ;
186
185
}
@@ -211,7 +210,7 @@ uint8_t Servo::attach(int pin, int min, int max)
211
210
R_IOPORT_PinCfg (&g_ioport_ctrl, io_pin,
212
211
IOPORT_CFG_PORT_DIRECTION_OUTPUT | IOPORT_CFG_PORT_OUTPUT_HIGH);
213
212
214
- // start the timer if it's not started.
213
+ // Start the timer if it's not started.
215
214
if (servo_timer_start () != 0 ) {
216
215
return 0 ;
217
216
}
@@ -255,8 +254,7 @@ void Servo::writeMicroseconds(int us)
255
254
{
256
255
if (servoIndex != SERVO_INVALID_INDEX) {
257
256
ra_servo_t *servo = &ra_servos[servoIndex];
258
- // servo->period_count = 0;
259
- servo->period_us = constrain (us, (int )servo->period_min , (int )servo->period_max );
257
+ servo->period_us = constrain (us, servo->period_min , servo->period_max );
260
258
servo->period_ticks = usToticks (servo->period_us );
261
259
}
262
260
}
0 commit comments