Skip to content

Commit 9ebaa64

Browse files
committed
chage rounding of all float clkdivs to round to neareset; default to nearest (which is a backwards incompatible change, but I think OK), and add ability to turn it off
1 parent 4bf91aa commit 9ebaa64

File tree

6 files changed

+42
-0
lines changed
  • src
    • rp2040/pico_platform/include/pico
    • rp2350/pico_platform/include/pico
    • rp2_common
      • hardware_adc/include/hardware
      • hardware_clocks/include/hardware
      • hardware_pio/include/hardware
      • hardware_pwm/include/hardware

6 files changed

+42
-0
lines changed

src/rp2040/pico_platform/include/pico/platform.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@
7070
#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS)
7171
#endif
7272

73+
// PICO_CONFIG: PICO_CLKDIV_ROUND_NEAREST, True if floating point clock divisors should be rounded to the nearest possible clock divisor by default rather than rounding down, type=bool, default=1, group-pico_platform
74+
#ifndef PICO_CLKDIV_ROUND_NEAREST
75+
#define PICO_CLKDIV_ROUND_NEAREST 1
76+
#endif
77+
7378
#ifndef __ASSEMBLER__
7479

7580
/*! \brief No-op function for the body of tight loops

src/rp2350/pico_platform/include/pico/platform.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
#define PICO_USE_STACK_GUARDS 0
6464
#endif
6565

66+
// PICO_CONFIG: PICO_CLKDIV_ROUND_NEAREST, True if floating point clock divisors should be rounded to the nearest possible clock divisor by default rather than rounding down, type=bool, default=1, group-pico_platform
67+
#ifndef PICO_CLKDIV_ROUND_NEAREST
68+
#define PICO_CLKDIV_ROUND_NEAREST 1
69+
#endif
70+
6671
#ifndef __ASSEMBLER__
6772

6873
/*! \brief No-op function for the body of tight loops

src/rp2_common/hardware_adc/include/hardware/adc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@
7070
#define ADC_TEMPERATURE_CHANNEL_NUM (NUM_ADC_CHANNELS - 1)
7171
#endif
7272

73+
// PICO_CONFIG: PICO_ADC_CLKDIV_ROUND_NEAREST, True if floating point ADC clock divisors should be rounded to the nearest possible clock divisor rather than rounding down, type=bool, default=PICO_CLKDIV_ROUND_NEAREST, group-hardware_pio
74+
#ifndef PICO_ADC_CLKDIV_ROUND_NEAREST
75+
#define PICO_ADC_CLKDIV_ROUND_NEAREST PICO_CLKDIV_ROUND_NEAREST
76+
#endif
77+
7378
#ifdef __cplusplus
7479
extern "C" {
7580
#endif
@@ -198,6 +203,9 @@ static inline void adc_run(bool run) {
198203
*/
199204
static inline void adc_set_clkdiv(float clkdiv) {
200205
invalid_params_if(HARDWARE_ADC, clkdiv >= 1 << (ADC_DIV_INT_MSB - ADC_DIV_INT_LSB + 1));
206+
#if PICO_ADC_CLKDIV_ROUND_NEAREST
207+
clkdiv += 0.5f / (1 << ADC_DIV_INT_LSB); // round to the nearest fraction
208+
#endif
201209
adc_hw->div = (uint32_t)(clkdiv * (float) (1 << ADC_DIV_INT_LSB));
202210
}
203211

src/rp2_common/hardware_clocks/include/hardware/clocks.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ extern "C" {
253253
#else
254254
#define PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS 0
255255
#endif
256+
#endif
257+
258+
// PICO_CONFIG: PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST, True if floating point GPIO clock divisors should be rounded to the nearest possible clock divisor rather than rounding down, type=bool, default=PICO_CLKDIV_ROUND_NEAREST, group-hardware_pio
259+
#ifndef PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST
260+
#define PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST PICO_CLKDIV_ROUND_NEAREST
256261
#endif
257262

258263
typedef clock_num_t clock_handle_t;
@@ -387,6 +392,9 @@ static inline void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_in
387392
static inline void clock_gpio_init(uint gpio, uint src, float div)
388393
{
389394
uint div_int = (uint)div;
395+
#if PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST
396+
div += 0.5f / (1 << (CLOCKS_CLK_GPOUT0_DIV_FRAC_MSB + 1 - CLOCKS_CLK_GPOUT0_DIV_FRAC_LSB)); // round to the nearest fraction
397+
#endif
390398
#if CLOCKS_CLK_GPOUT0_DIV_FRAC_MSB - CLOCKS_CLK_GPOUT0_DIV_FRAC_LSB == 15
391399
uint16_t frac = (uint16_t)((div - (float)div_int) * (1u << 16));
392400
clock_gpio_init_int_frac16(gpio, src, div_int, frac);

src/rp2_common/hardware_pio/include/hardware/pio.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
#define PICO_PIO_VERSION 0
3232
#endif
3333
#endif
34+
35+
// PICO_CONFIG: PICO_PIO_CLKDIV_ROUND_NEAREST, True if floating point PIO clock divisors should be rounded to the nearest possible clock divisor rather than rounding down, type=bool, default=PICO_CLKDIV_ROUND_NEAREST, group-hardware_pio
36+
#ifndef PICO_PIO_CLKDIV_ROUND_NEAREST
37+
#define PICO_PIO_CLKDIV_ROUND_NEAREST PICO_CLKDIV_ROUND_NEAREST
38+
#endif
39+
3440
/** \file hardware/pio.h
3541
* \defgroup hardware_pio hardware_pio
3642
*
@@ -488,7 +494,9 @@ static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_
488494

489495
static inline void pio_calculate_clkdiv8_from_float(float div, uint32_t *div_int, uint8_t *div_frac8) {
490496
valid_params_if(HARDWARE_PIO, div >= 1 && div <= 65536);
497+
#if PICO_PIO_CLKDIV_ROUND_NEAREST
491498
div += 0.5f / 256; // round to the nearest 1/256
499+
#endif
492500
*div_int = (uint16_t)div;
493501
// not a strictly necessary check, but if this changes, then this method should
494502
// probably no longer be used in favor of one with a larger fraction

src/rp2_common/hardware_pwm/include/hardware/pwm.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ static_assert(DREQ_PWM_WRAP7 == DREQ_PWM_WRAP0 + 7, "");
103103
})
104104
#endif
105105

106+
// PICO_CONFIG: PICO_PWM_CLKDIV_ROUND_NEAREST, True if floating point PWM clock divisors should be rounded to the nearest possible clock divisor rather than rounding down, type=bool, default=PICO_CLKDIV_ROUND_NEAREST, group-hardware_pio
107+
#ifndef PICO_PWM_CLKDIV_ROUND_NEAREST
108+
#define PICO_PWM_CLKDIV_ROUND_NEAREST PICO_CLKDIV_ROUND_NEAREST
109+
#endif
110+
106111
static inline void check_slice_num_param(__unused uint slice_num) {
107112
valid_params_if(HARDWARE_PWM, slice_num < NUM_PWM_SLICES);
108113
}
@@ -155,6 +160,9 @@ static inline void pwm_config_set_phase_correct(pwm_config *c, bool phase_correc
155160
*/
156161
static inline void pwm_config_set_clkdiv(pwm_config *c, float div) {
157162
valid_params_if(HARDWARE_PWM, div >= 1.f && div < 256.f);
163+
#if PICO_PWM_CLKDIV_ROUND_NEAREST
164+
div += 0.5f / (1 << PWM_CH0_DIV_INT_LSB); // round to the nearest fraction
165+
#endif
158166
c->div = (uint32_t)(div * (float)(1u << PWM_CH0_DIV_INT_LSB));
159167
}
160168

0 commit comments

Comments
 (0)