Firmware SDK
twr_servo.c
1 #include <twr_servo.h>
2 
3 #define _TWR_SERVO_PERIOD_CYCLES 50000
4 #define _TWR_SERVO_RESOLUTION 1
5 
7 {
8  self->_channel = channel;
9  self->_angle = TWR_SERVO_NO_ANGLE;
10  self->_min = TWR_SERVO_DEFAULT_MIN;
11  self->_max = TWR_SERVO_DEFAULT_MAX;
12 
13  twr_pwm_init(channel);
14 
15  if ((channel == TWR_PWM_P0) || (channel == TWR_PWM_P1) || (channel == TWR_PWM_P2) || (channel == TWR_PWM_P3))
16  {
17  twr_pwm_tim_configure(TWR_PWM_TIM2_P0_P1_P2_P3, _TWR_SERVO_RESOLUTION, _TWR_SERVO_PERIOD_CYCLES);
18  }
19  else if ((channel == TWR_PWM_P6) || (channel == TWR_PWM_P7) || (channel == TWR_PWM_P8))
20  {
21  twr_pwm_tim_configure(TWR_PWM_TIM3_P6_P7_P8, _TWR_SERVO_RESOLUTION, _TWR_SERVO_PERIOD_CYCLES);
22  }
23  else if ((channel == TWR_PWM_P12) || (channel == TWR_PWM_P14))
24  {
25  twr_pwm_tim_configure(TWR_PWM_TIM21_P12_P14, _TWR_SERVO_RESOLUTION, _TWR_SERVO_PERIOD_CYCLES);
26  }
27 }
28 
29 void twr_servo_set_angle(twr_servo_t *self, uint8_t angle)
30 {
31  if (angle > 180)
32  {
33  angle = 180;
34  }
35 
36  uint16_t pwm_value = ((self->_max - self->_min) * ((float) angle / 180.f)) + self->_min;
37 
38  twr_pwm_set(self->_channel, pwm_value);
39 
40  if (self->_angle == TWR_SERVO_NO_ANGLE)
41  {
42  twr_pwm_enable(self->_channel);
43  }
44 
45  self->_angle = angle;
46 }
47 
49 {
50  return self->_angle;
51 }
52 
53 void twr_servo_set_pulse_limits(twr_servo_t *self, uint16_t min_us, uint16_t max_us)
54 {
55  self->_min = min_us;
56 
57  self->_max = max_us;
58 }
59 
60 void twr_servo_set_microseconds(twr_servo_t *self, uint16_t us)
61 {
62  twr_pwm_set(self->_channel, us);
63 
64  if (self->_angle == TWR_SERVO_NO_ANGLE)
65  {
66  twr_pwm_enable(self->_channel);
67  }
68 
69  self->_angle = TWR_SERVO_UNKNOWN_ANGLE;
70 }
void twr_pwm_enable(twr_pwm_channel_t channel)
Enable PWM output on GPIO pin.
Definition: twr_pwm.c:174
void twr_pwm_set(twr_pwm_channel_t channel, uint16_t pwm_value)
Set PWM value for GPIO pin.
Definition: twr_pwm.c:193
void twr_pwm_tim_configure(twr_pwm_tim_t tim, uint32_t resolution_us, uint32_t period_cycles)
Reconfigure TIM3.
Definition: twr_pwm.c:115
void twr_pwm_init(twr_pwm_channel_t channel)
Initialize PWM timers based on GPIO pin.
Definition: twr_pwm.c:141
twr_pwm_channel_t
PWM channels.
Definition: twr_pwm.h:15
void twr_servo_set_angle(twr_servo_t *self, uint8_t angle)
Set angle.
Definition: twr_servo.c:29
void twr_servo_set_microseconds(twr_servo_t *self, uint16_t us)
Set Microseconds.
Definition: twr_servo.c:60
void twr_servo_set_pulse_limits(twr_servo_t *self, uint16_t min_us, uint16_t max_us)
Set pulse limits.
Definition: twr_servo.c:53
void twr_servo_init(twr_servo_t *self, twr_pwm_channel_t channel)
Initialize Servo.
Definition: twr_servo.c:6
uint8_t twr_servo_get_angle(twr_servo_t *self)
Get angle.
Definition: twr_servo.c:48
Servo instance.
Definition: twr_servo.h:18