Skip to content

Commit 24833db

Browse files
committed
misc: rp1-pio: Convert floats to 24.8 fixed point
Floating point arithmetic is not supported in the kernel, so use fixed point instead. Signed-off-by: Phil Elwell <phil@raspberrypi.com>
1 parent a0b0a6e commit 24833db

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

include/linux/pio_rp1.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ enum gpio_drive_strength {
171171
GPIO_DRIVE_STRENGTH_12MA = 3
172172
};
173173

174+
struct fp24_8 {
175+
uint32_t val;
176+
};
177+
174178
typedef rp1_pio_sm_config pio_sm_config;
175179

176180
typedef struct rp1_pio_client *PIO;
@@ -218,6 +222,13 @@ void pio_close(PIO pio);
218222
int pio_sm_config_xfer(PIO pio, uint sm, uint dir, uint buf_size, uint buf_count);
219223
int pio_sm_xfer_data(PIO pio, uint sm, uint dir, uint data_bytes, void *data);
220224

225+
static inline struct fp24_8 make_fp24_8(uint mul, uint div)
226+
{
227+
struct fp24_8 res = { .val = ((unsigned long long)mul << 8) / div };
228+
229+
return res;
230+
}
231+
221232
static inline bool pio_can_add_program(struct rp1_pio_client *client,
222233
const pio_program_t *program)
223234
{
@@ -396,16 +407,18 @@ static inline int pio_sm_clear_fifos(struct rp1_pio_client *client, uint sm)
396407
return rp1_pio_sm_clear_fifos(client, &args);
397408
}
398409

399-
static inline bool pio_calculate_clkdiv_from_float(float div, uint16_t *div_int,
410+
static inline bool pio_calculate_clkdiv_from_fp24_8(struct fp24_8 div, uint16_t *div_int,
400411
uint8_t *div_frac)
401412
{
402-
if (bad_params_if(NULL, div < 1 || div > 65536))
413+
uint inum = (div.val >> 8);
414+
415+
if (bad_params_if(NULL, inum < 1 || inum > 65536))
403416
return false;
404-
*div_int = (uint16_t)div;
417+
*div_int = (uint16_t)inum;
405418
if (*div_int == 0)
406419
*div_frac = 0;
407420
else
408-
*div_frac = (uint8_t)((div - (float)*div_int) * (1u << 8u));
421+
*div_frac = div.val & 0xff;
409422
return true;
410423
}
411424

@@ -421,11 +434,11 @@ static inline int pio_sm_set_clkdiv_int_frac(struct rp1_pio_client *client, uint
421434
return rp1_pio_sm_set_clkdiv(client, &args);
422435
}
423436

424-
static inline int pio_sm_set_clkdiv(struct rp1_pio_client *client, uint sm, float div)
437+
static inline int pio_sm_set_clkdiv(struct rp1_pio_client *client, uint sm, struct fp24_8 div)
425438
{
426439
struct rp1_pio_sm_set_clkdiv_args args = { .sm = sm };
427440

428-
if (!pio_calculate_clkdiv_from_float(div, &args.div_int, &args.div_frac))
441+
if (!pio_calculate_clkdiv_from_fp24_8(div, &args.div_int, &args.div_frac))
429442
return -EINVAL;
430443
return rp1_pio_sm_set_clkdiv(client, &args);
431444
}
@@ -745,12 +758,12 @@ static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_
745758
(((uint)div_int) << PROC_PIO_SM0_CLKDIV_INT_LSB);
746759
}
747760

748-
static inline void sm_config_set_clkdiv(pio_sm_config *c, float div)
761+
static inline void sm_config_set_clkdiv(pio_sm_config *c, struct fp24_8 div)
749762
{
750763
uint16_t div_int;
751764
uint8_t div_frac;
752765

753-
pio_calculate_clkdiv_from_float(div, &div_int, &div_frac);
766+
pio_calculate_clkdiv_from_fp24_8(div, &div_int, &div_frac);
754767
sm_config_set_clkdiv_int_frac(c, div_int, div_frac);
755768
}
756769

0 commit comments

Comments
 (0)