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;
1516uint min ;
1617uint max ;
1718
18- static uint slice_map [30 ];
19+ static int slice_map [30 ];
1920static uint slice_active [8 ];
2021static void (* pwm_cb [8 ])(void );
2122static uint servo_pos [32 ];
2223static 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
8543int 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
10560int 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
13491int 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