@@ -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() {
9293typedef uint16_t led_timer_value_t ;
9394uint8_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;
105110static 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
198203static 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