Skip to content

Commit 118e55f

Browse files
committed
multiple servos now work
1 parent 897387e commit 118e55f

File tree

4 files changed

+45
-78
lines changed

4 files changed

+45
-78
lines changed

examples/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ pico_add_extra_outputs(simple)
88

99
target_include_directories(simple PRIVATE ../include)
1010
target_link_directories(simple PRIVATE ../build)
11-
target_link_libraries(simple PRIVATE pico_stdlib hardware_pwm pico-servo.a)
11+
target_link_libraries(simple PRIVATE pico_stdlib hardware_pwm pico-servo)

examples/simple.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
#include "pico/stdlib.h"
22
#include "pico_servo.h"
3+
#include <stdio.h>
4+
5+
#define A 2
6+
#define B 12
37

48
int main()
59
{
610
stdio_init_all();
7-
11+
812
servo_init();
9-
servo_attach(2);
10-
servo_attach(3);
13+
servo_attach(A);
14+
servo_attach(B);
1115

1216
while (1)
1317
{
14-
servo_move_to(2, 0);
15-
servo_move_to(15, 0);
18+
servo_move_to(A, 0);
19+
servo_move_to(B, 0);
1620
sleep_ms(1000);
17-
servo_move_to(2, 180);
18-
servo_move_to(15, 90);
21+
servo_move_to(A, 180);
22+
servo_move_to(B, 90);
1923
sleep_ms(1000);
2024
}
2125
return 0;

include/pico_servo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
int servo_init();
77
int servo_attach(uint);
8+
int servo_enable();
89
int servo_move_to(uint, uint);
910

1011
#endif /* PICO_SERVO_H */

src/pico_servo.c

Lines changed: 32 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "hardware/clocks.h"
77
#include "hardware/structs/pll.h"
88
#include "hardware/structs/clocks.h"
9+
#include <string.h>
910

1011

1112
#define WRAP 10000
@@ -15,91 +16,45 @@ float clkdiv;
1516
uint min;
1617
uint max;
1718

18-
static uint slice_map[30];
19+
static int slice_map[30];
1920
static uint slice_active[8];
2021
static void (*pwm_cb[8])(void);
2122
static uint servo_pos[32];
2223
static uint servo_pos_buf[16];
24+
static pwm_config slice_cfg[8];
2325

24-
static pwm_generic_cb(uint slice)
26+
static void wrap_cb()
2527
{
26-
pwm_clear_irq(slice);
27-
2828
uint offset;
2929

30-
offset = 16 * ((servo_pos_buf[slice + 0] + 1) % 2);
31-
pwm_set_chan_level(slice, 0, servo_pos[offset + slice + 0]);
32-
//servo_pos_buf[slice + 0] = (servo_pos_buf[slice + 0] + 16) % 32; // flip buffer
33-
34-
offset = 16 * ((servo_pos_buf[slice + 1] + 1) % 2);
35-
pwm_set_chan_level(slice, 1, servo_pos[offset + slice + 1]);
36-
//servo_pos_buf[slice + 1] = (servo_pos_buf[slice + 1] + 16) % 32; // flip buffer
37-
}
38-
39-
static void pwm0_cb()
40-
{
41-
pwm_generic_cb(0);
42-
}
43-
44-
static void pwm1_cb()
45-
{
46-
pwm_generic_cb(1);
47-
}
48-
49-
50-
static void pwm2_cb()
51-
{
52-
pwm_generic_cb(2);
53-
}
54-
55-
56-
static void pwm3_cb()
57-
{
58-
pwm_generic_cb(3);
59-
}
60-
61-
62-
static void pwm4_cb()
63-
{
64-
pwm_generic_cb(4);
65-
}
66-
67-
68-
static void pwm5_cb()
69-
{
70-
pwm_generic_cb(5);
71-
}
72-
73-
74-
static void pwm6_cb()
75-
{
76-
pwm_generic_cb(6);
77-
}
30+
for (int i = 0; i < 8; ++i)
31+
{
32+
if (slice_active[i] == 0) continue;
7833

34+
pwm_clear_irq(i);
35+
offset = 16 * ((servo_pos_buf[i + 0] + 1) % 2);
36+
pwm_set_chan_level(i, 0, servo_pos[offset + i + 0]);
7937

80-
static void pwm7_cb()
81-
{
82-
pwm_generic_cb(7);
38+
offset = 16 * ((servo_pos_buf[i + 1] + 1) % 2);
39+
pwm_set_chan_level(i, 1, servo_pos[offset + i + 1]);
40+
}
8341
}
8442

8543
int servo_init()
8644
{
87-
memset(slice_map, 0xFF, 30 * sizeof(uint));
45+
for (int i = 0; i < 30; ++i)
46+
{
47+
slice_map[i] = -1;
48+
}
8849
memset(slice_active, 0, 8 * sizeof(uint));
8950
memset(servo_pos, 0, 32 * sizeof(uint));
9051
memset(servo_pos_buf, 0, 16 * sizeof(uint));
91-
pwm_cb[0] = pwm0_cb;
92-
pwm_cb[1] = pwm1_cb;
93-
pwm_cb[2] = pwm2_cb;
94-
pwm_cb[3] = pwm3_cb;
95-
pwm_cb[4] = pwm4_cb;
96-
pwm_cb[5] = pwm5_cb;
97-
pwm_cb[6] = pwm6_cb;
98-
pwm_cb[7] = pwm7_cb;
9952

10053
clkdiv = (float)frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY) * 1000.f / (FREQ * WRAP);
10154
min = 0.025f * WRAP;
10255
max = 0.125f * WRAP;
56+
57+
irq_set_exclusive_handler(PWM_IRQ_WRAP, wrap_cb);
10358
}
10459

10560
int servo_attach(uint pin)
@@ -110,29 +65,36 @@ int servo_attach(uint pin)
11065
return 1;
11166
}
11267

68+
printf("slice: %d\n", slice);
69+
11370
gpio_set_function(pin, GPIO_FUNC_PWM);
11471
slice_map[pin] = slice;
11572

11673
if (slice_active[slice] == 0)
11774
{
11875
pwm_clear_irq(slice);
11976
pwm_set_irq_enabled(slice, true);
120-
irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_cb[slice]);
121-
irq_set_enabled(PWM_IRQ_WRAP, true);
12277

123-
pwm_config cfg = pwm_get_default_config();
124-
pwm_config_set_wrap(&cfg, WRAP);
125-
pwm_config_set_clkdiv(&cfg, clkdiv);
126-
pwm_init(slice, &cfg, true);
78+
slice_cfg[slice] = pwm_get_default_config();
79+
pwm_config_set_wrap(&slice_cfg[slice], WRAP);
80+
pwm_config_set_clkdiv(&slice_cfg[slice], clkdiv);
81+
pwm_init(slice, &slice_cfg[slice], true);
12782
}
12883

12984
++slice_active[slice];
13085

86+
irq_set_enabled(PWM_IRQ_WRAP, true);
87+
13188
return 0;
13289
}
13390

13491
int servo_move_to(uint pin, uint angle)
13592
{
93+
if (slice_map[pin] < 0)
94+
{
95+
return 1;
96+
}
97+
13698
uint val = (float)angle / 180.f * (max - min) + min;
13799
uint pos = slice_map[pin] + (pin % 2);
138100
servo_pos[16 * servo_pos_buf[pos] + pos] = val;

0 commit comments

Comments
 (0)