Fix the LED PWM support for non shared timers

This is the fixes https://github.com/PX4/Firmware/issues/5710
  by adding 2 concepts.

  1) Allowing a board to define BOARD_HAS_SHARED_PWM_TIMERS
     in this case the io_timeris will be initalized as the
     led_pwm_timers  - there is an assumptionm that the
     number of io_timers == the number of led_pwm timers

  2) Allowing a board to define BOARD_LED_PWM_RATE
     To set an alternate frequency

  Future expansion will require:
  1) The ability to have a config with both the I2C RGB LED and
     PWM RGB LED drivers loaded.
  2) The higher level driver to create  multiple instances of the
     /dev/rgbld, to support internal and  external User facing
     RGB LED as supported in FMUv5
This commit is contained in:
David Sidrane
2016-12-13 12:14:38 -10:00
committed by Lorenz Meier
parent 4712ed1889
commit 0baab8263b
+63
View File
@@ -63,6 +63,15 @@
#if defined(BOARD_HAS_LED_PWM)
/* Board can override rate */
#if (BOARD_LED_PWM_RATE)
# define LED_PWM_RATE BOARD_LED_PWM_RATE
#else
# define LED_PWM_RATE 50
#endif
#define REG(_tmr, _reg) (*(volatile uint32_t *)(led_pwm_timers[_tmr].base + _reg))
#define rCR1(_tmr) REG(_tmr, STM32_GTIM_CR1_OFFSET)
@@ -104,6 +113,56 @@ led_pwm_timer_get_period(unsigned timer)
return (rARR(timer));
}
#if !defined(BOARD_HAS_SHARED_PWM_TIMERS)
static void led_pwm_timer_init_timer(unsigned timer)
{
irqstate_t flags = px4_enter_critical_section();
/* enable the timer clock before we try to talk to it */
modifyreg32(led_pwm_timers[timer].clock_register, 0, led_pwm_timers[timer].clock_bit);
/* disable and configure the timer */
rCR1(timer) = 0;
rCR2(timer) = 0;
rSMCR(timer) = 0;
rDIER(timer) = 0;
rCCER(timer) = 0;
rCCMR1(timer) = 0;
rCCMR2(timer) = 0;
rCCR1(timer) = 0;
rCCR2(timer) = 0;
rCCR3(timer) = 0;
rCCR4(timer) = 0;
rCCER(timer) = 0;
rDCR(timer) = 0;
if ((led_pwm_timers[timer].base == STM32_TIM1_BASE) || (led_pwm_timers[timer].base == STM32_TIM8_BASE)) {
/* master output enable = on */
rBDTR(timer) = ATIM_BDTR_MOE;
}
/* If the timer clock source provided as clock_freq is the STM32_APBx_TIMx_CLKIN
* then configure the timer to free-run at 1MHz.
* Otherwize, other frequencies are attainable by adjusting .clock_freq accordingly.
*/
rPSC(timer) = (led_pwm_timers[timer].clock_freq / 1000000) - 1;
/* configure the timer to update at the desired rate */
rARR(timer) = 1000000 / LED_PWM_RATE;
/* generate an update event; reloads the counter and all registers */
rEGR(timer) = GTIM_EGR_UG;
px4_leave_critical_section(flags);
}
#endif
static void
led_pwm_channel_init(unsigned channel)
@@ -233,7 +292,11 @@ led_pwm_servo_init(void)
{
/* do basic timer initialisation first */
for (unsigned i = 0; i < arraySize(led_pwm_timers); i++) {
#if defined(BOARD_HAS_SHARED_PWM_TIMERS)
io_timer_init_timer(i);
#else
led_pwm_timer_init_timer(i);
#endif
}
/* now init channels */