2929#include "hardware/clocks.h"
3030#include "hardware/structs/pll.h"
3131#include "hardware/structs/clocks.h"
32+
33+ #include "fixmath.h"
34+
3235#include <string.h>
3336
3437#define KILO 1e3
3538#define MICRO 1e-6
3639#define WRAP 10000
37- #define FREQ 50 // PWM frequency in hertz
40+ #define PWM_FREQ 50 // PWM frequency in hertz
3841
3942static float clkdiv ;
4043static uint min ;
@@ -48,7 +51,7 @@ static pwm_config slice_cfg[8];
4851
4952static uint min_us = 500 ;
5053static uint max_us = 2500 ;
51- static float us_per_unit = 0.f ;
54+ static fix16_t us_per_unit = 0.f ;
5255
5356static void wrap_cb (void )
5457{
@@ -82,10 +85,10 @@ void servo_set_bounds(uint a, uint b)
8285{
8386 min_us = a ;
8487 max_us = b ;
85- if (us_per_unit > 0.f )
88+ if (fix16_to_float ( us_per_unit ) > 0.0f )
8689 {
8790 min = min_us / us_per_unit ;
88- max = max_us / us_per_unit ;
91+ max = max_us / us_per_unit ;
8992 }
9093}
9194
@@ -105,7 +108,6 @@ int servo_init(void)
105108 memset (servo_pos , 0 , 32 * sizeof (uint ));
106109 memset (servo_pos_buf , 0 , 16 * sizeof (uint ));
107110
108- //irq_set_exclusive_handler(PWM_IRQ_WRAP, wrap_cb);
109111 irq_add_shared_handler (PWM_IRQ_WRAP , wrap_cb , PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY );
110112
111113 return 0 ;
@@ -130,12 +132,12 @@ int servo_clock_auto(void)
130132 */
131133int servo_clock_source (uint src )
132134{
133- clkdiv = (float )frequency_count_khz (src ) * (float )KILO / (FREQ * WRAP );
135+ clkdiv = (float )frequency_count_khz (src ) * (float )KILO / (PWM_FREQ * WRAP );
134136 if (clkdiv == 0 )
135137 {
136138 return 1 ;
137139 }
138- us_per_unit = 1.f / (FREQ * WRAP ) / MICRO ;
140+ us_per_unit = 1.f / (PWM_FREQ * WRAP ) / MICRO ;
139141
140142 min = min_us / us_per_unit ;
141143 max = max_us / us_per_unit ;
@@ -151,13 +153,13 @@ int servo_clock_source(uint src)
151153 */
152154int servo_clock_manual (uint freq )
153155{
154- clkdiv = (float )freq * 1000.f / (FREQ * WRAP );
156+ clkdiv = (float )( freq * KILO ) / (float )( PWM_FREQ * WRAP );
155157 if (clkdiv == 0 )
156158 {
157159 return 1 ;
158160 }
159- min = 0.025f * WRAP ;
160- max = 0.125f * WRAP ;
161+ min = 0.025f * ( float ) WRAP ;
162+ max = 0.125f * ( float ) WRAP ;
161163
162164 return 0 ;
163165}
@@ -213,7 +215,13 @@ int servo_move_to(uint pin, uint angle)
213215 return 1 ;
214216 }
215217
216- uint val = (float )angle / 180.f * (max - min ) + min ;
218+ uint val = (uint )fix16_to_int (
219+ fix16_mul (
220+ fix16_div (fix16_from_int (angle ), fix16_from_int (180 )),
221+ fix16_from_int (max - min )
222+ )
223+ ) + min ;
224+
217225 uint pos = slice_map [pin ] + (pin % 2 );
218226 servo_pos [16 * servo_pos_buf [pos ] + pos ] = val ;
219227 servo_pos_buf [pos ] = (servo_pos_buf [pos ] + 1 ) % 2 ;
0 commit comments