Skip to content

Commit 5435133

Browse files
author
3djc
committed
fix: make timing scale with mcu clock
1 parent 7d9198a commit 5435133

1 file changed

Lines changed: 24 additions & 13 deletions

File tree

radio/src/targets/common/arm/stm32/stm32_rgbleds.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,21 @@ static uint8_t _b_offset;
4747
#define RGBLEDS_DMA_BUFFER_LEN (RGBLEDS_DMA_BUFFER_HALF_LEN * 2)
4848
#define RGBLEDS_DMA_IRQ_PRIO 3
4949

50+
// Bit timing in ns (period / '1' HIGH / '0' HIGH), converted to timer ticks at
51+
// init from the actual timer clock so it holds on any clock domain.
5052
#if defined(RGB_LEDS_900NS)
51-
// RGBLEDSB have a shorter timing, so we can use a faster timer clock
52-
#define RGBLEDS_FREQ 1200000UL // tick = 1/12MHz = 83.3 ns
53-
#define RGBLEDS_TIMER_PERIOD 11UL // 11 × 83.3 = 916,7 ns period
54-
#define RGBLEDS_ONE 7 // 7 × 83.3 = 583.3 ns HIGH, 3 × 83.3 = 250.0 ns LOW
55-
#define RGBLEDS_ZERO 3 // 3 × 83.3 = 250.0 ns HIGH, 7 × 83.3 = 583.3 ns LOW
53+
#define RGBLEDS_PERIOD_NS 917UL
54+
#define RGBLEDS_T1H_NS 583UL
55+
#define RGBLEDS_T0H_NS 250UL
5656
#else
57-
// Generic RGBLEDS
58-
#define RGBLEDS_FREQ 800000UL // tick = 1250/20 = 62.5 ns
59-
#define RGBLEDS_TIMER_PERIOD 20UL // 20 × 62.5 = 1250 ns period
60-
#define RGBLEDS_ONE (3 * RGBLEDS_TIMER_PERIOD / 4) // 15 × 62.5 = 937.5 ns HIGH (550–950), 5 × 62.5 = 312.5 ns LOW (220–400)
61-
#define RGBLEDS_ZERO (1 * RGBLEDS_TIMER_PERIOD / 4) // 5 × 62.5 = 312.5 ns HIGH (220–400) , 15 × 62.5 = 937.5 ns LOW (550–950)
57+
#define RGBLEDS_PERIOD_NS 1250UL
58+
#define RGBLEDS_T1H_NS 938UL
59+
#define RGBLEDS_T0H_NS 313UL
6260
#endif
6361

62+
#define RGBLEDS_NS_TO_TICKS(freq, ns) \
63+
(uint32_t)(((uint64_t)(freq) * (ns) + 500000000UL) / 1000000000UL)
64+
6465

6566
// Debug facility
6667
#if defined(LED_STRIP_DEBUG_GPIO) && defined(LED_STRIP_DEBUG_GPIO_PIN)
@@ -92,6 +93,10 @@ static void _led_dbg_init() {
9293
typedef uint16_t led_timer_value_t;
9394
uint8_t pulse_inc = 1;
9495

96+
// HIGH time (timer ticks) for a '1' and a '0' bit, computed at init.
97+
static led_timer_value_t _led_one;
98+
static led_timer_value_t _led_zero;
99+
95100
// DMA buffer contains pulses for 2 LED at a time
96101
// (allows for refill at HT and TC)
97102
#if defined(STM32_SUPPORT_32BIT_TIMERS)
@@ -105,7 +110,7 @@ static uint8_t _led_seq_cnt;
105110
static void _fill_byte(uint8_t c, led_timer_value_t* dma_buffer)
106111
{
107112
for (int i = 0; i < 8; i++) {
108-
dma_buffer[i*pulse_inc] = c & 0x80 ? RGBLEDS_ONE : RGBLEDS_ZERO;
113+
dma_buffer[i*pulse_inc] = c & 0x80 ? _led_one : _led_zero;
109114
c <<= 1;
110115
}
111116
}
@@ -197,9 +202,15 @@ static void _led_set_dma_periph_addr(const stm32_pulse_timer_t* tim)
197202

198203
static void _init_timer(const stm32_pulse_timer_t* tim)
199204
{
200-
stm32_pulse_init(tim, RGBLEDS_FREQ * RGBLEDS_TIMER_PERIOD);
205+
// Run at the full timer clock (prescaler 0) and derive the periods from it.
206+
uint32_t cnt_freq = tim->TIM_Freq;
207+
stm32_pulse_init(tim, cnt_freq);
201208
stm32_pulse_config_output(tim, true, LL_TIM_OCMODE_PWM1, 0);
202-
LL_TIM_SetAutoReload(tim->TIMx, RGBLEDS_TIMER_PERIOD - 1);
209+
210+
uint32_t period = RGBLEDS_NS_TO_TICKS(cnt_freq, RGBLEDS_PERIOD_NS);
211+
_led_one = RGBLEDS_NS_TO_TICKS(cnt_freq, RGBLEDS_T1H_NS);
212+
_led_zero = RGBLEDS_NS_TO_TICKS(cnt_freq, RGBLEDS_T0H_NS);
213+
LL_TIM_SetAutoReload(tim->TIMx, period - 1);
203214

204215
// pulse driver uses DMA to ARR, but we need CCRx
205216
_led_set_dma_periph_addr(tim);

0 commit comments

Comments
 (0)