altos: Get stm32l pwm driver working
authorKeith Packard <keithp@keithp.com>
Sat, 26 Dec 2015 07:20:29 +0000 (23:20 -0800)
committerKeith Packard <keithp@keithp.com>
Sat, 26 Dec 2015 07:20:29 +0000 (23:20 -0800)
Fix the CCMR1_OC1PE and CCMR2_OC3PE values.
Disable clock when no PWM outputs are running.
Fix the apb1enr value for the timer.
Set ARR value to PWM_MAX - 1 -- ARR is off by one.
Sets the GPIO pins to 40MHz bandwidth for sharper edges.

Tested on EasyMega, but that code is not included as it breaks the
companion protocol.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/stm/ao_pwm_stm.c
src/stm/stm32l.h
src/telemega-v2.0/ao_pins.h

index cea2103038b2ffe61cda7134a50f138d10e984bf..ce1fa6f3ea77bd7a8aa339721f24ee765ba6e64d 100644 (file)
@@ -27,11 +27,23 @@ ao_pwm_up(void)
 {
        if (pwm_running++ == 0) {
                struct stm_tim234       *tim = &AO_PWM_TIMER;
+
                tim->ccr1 = 0;
                tim->ccr2 = 0;
                tim->ccr3 = 0;
                tim->ccr4 = 0;
-               tim->arr = PWM_MAX;     /* turn on the timer */
+               tim->arr = PWM_MAX - 1; /* turn on the timer */
+               tim->cr1 = ((STM_TIM234_CR1_CKD_1 << STM_TIM234_CR1_CKD) |
+                           (0 << STM_TIM234_CR1_ARPE) |
+                           (STM_TIM234_CR1_CMS_EDGE << STM_TIM234_CR1_CMS) |
+                           (STM_TIM234_CR1_DIR_UP << STM_TIM234_CR1_DIR) |
+                           (0 << STM_TIM234_CR1_OPM) |
+                           (0 << STM_TIM234_CR1_URS) |
+                           (0 << STM_TIM234_CR1_UDIS) |
+                           (1 << STM_TIM234_CR1_CEN));
+
+               /* Set the timer running */
+               tim->egr = (1 << STM_TIM234_EGR_UG);
        }
 }
 
@@ -40,7 +52,19 @@ ao_pwm_down(void)
 {
        if (--pwm_running == 0) {
                struct stm_tim234       *tim = &AO_PWM_TIMER;
-               tim->arr = 0;   /* turn off the timer */
+
+               tim->arr = 0;
+               tim->cr1 = ((STM_TIM234_CR1_CKD_1 << STM_TIM234_CR1_CKD) |
+                           (0 << STM_TIM234_CR1_ARPE) |
+                           (STM_TIM234_CR1_CMS_EDGE << STM_TIM234_CR1_CMS) |
+                           (STM_TIM234_CR1_DIR_UP << STM_TIM234_CR1_DIR) |
+                           (0 << STM_TIM234_CR1_OPM) |
+                           (0 << STM_TIM234_CR1_URS) |
+                           (0 << STM_TIM234_CR1_UDIS) |
+                           (0 << STM_TIM234_CR1_CEN));
+
+               /* Stop the timer */
+               tim->egr = (1 << STM_TIM234_EGR_UG);
        }
 }
 
@@ -49,14 +73,12 @@ ao_pwm_set(uint8_t pwm, uint16_t value)
 {
        struct stm_tim234       *tim = &AO_PWM_TIMER;
 
+       if (value > PWM_MAX)
+               value = PWM_MAX;
        if (value != 0) {
                if (pwm_value[pwm] == 0)
                        ao_pwm_up();
-       } else {
-               if (pwm_value[pwm] != 0)
-                       ao_pwm_down();
        }
-       pwm_value[pwm] = value;
        switch (pwm) {
        case 0:
                tim->ccr1 = value;
@@ -71,6 +93,11 @@ ao_pwm_set(uint8_t pwm, uint16_t value)
                tim->ccr4 = value;
                break;
        }
+       if (value == 0) {
+               if (pwm_value[pwm] != 0)
+                       ao_pwm_down();
+       }
+       pwm_value[pwm] = value;
 }
 
 static void
@@ -100,13 +127,10 @@ ao_pwm_init(void)
 {
        struct stm_tim234       *tim = &AO_PWM_TIMER;
 
-       stm_rcc.apb1enr |= AO_PWM_TIMER_ENABLE;
-       tim->ccr1 = 0;
-       tim->ccr2 = 0;
-       tim->ccr3 = 0;
-       tim->ccr4 = 0;
-       tim->arr = 0;   /* turn off the timer */
-       tim->psc = 0;
+       stm_rcc.apb1enr |= (1 << AO_PWM_TIMER_ENABLE);
+
+       tim->cr1 = 0;
+       tim->psc = AO_PWM_TIMER_SCALE - 1;
        tim->cnt = 0;
        tim->ccer = ((1 << STM_TIM234_CCER_CC1E) |
                     (0 << STM_TIM234_CCER_CC1P) |
@@ -119,26 +143,26 @@ ao_pwm_init(void)
 
        tim->ccmr1 = ((0 << STM_TIM234_CCMR1_OC2CE) |
                      (STM_TIM234_CCMR1_OC2M_PWM_MODE_1 << STM_TIM234_CCMR1_OC2M) |
-                     (1 << STM_TIM234_CCMR1_OC2PE) |
+                     (0 << STM_TIM234_CCMR1_OC2PE) |
                      (0 << STM_TIM234_CCMR1_OC2FE) |
                      (STM_TIM234_CCMR1_CC2S_OUTPUT << STM_TIM234_CCMR1_CC2S) |
 
                      (0 << STM_TIM234_CCMR1_OC1CE) |
                      (STM_TIM234_CCMR1_OC1M_PWM_MODE_1 << STM_TIM234_CCMR1_OC1M) |
-                     (1 << STM_TIM234_CCMR1_OC1PE) |
+                     (0 << STM_TIM234_CCMR1_OC1PE) |
                      (0 << STM_TIM234_CCMR1_OC1FE) |
                      (STM_TIM234_CCMR1_CC1S_OUTPUT << STM_TIM234_CCMR1_CC1S));
 
 
        tim->ccmr2 = ((0 << STM_TIM234_CCMR2_OC4CE) |
                      (STM_TIM234_CCMR2_OC4M_PWM_MODE_1 << STM_TIM234_CCMR2_OC4M) |
-                     (1 << STM_TIM234_CCMR2_OC4PE) |
+                     (0 << STM_TIM234_CCMR2_OC4PE) |
                      (0 << STM_TIM234_CCMR2_OC4FE) |
                      (STM_TIM234_CCMR2_CC4S_OUTPUT << STM_TIM234_CCMR2_CC4S) |
 
                      (0 << STM_TIM234_CCMR2_OC3CE) |
                      (STM_TIM234_CCMR2_OC3M_PWM_MODE_1 << STM_TIM234_CCMR2_OC3M) |
-                     (1 << STM_TIM234_CCMR2_OC3PE) |
+                     (0 << STM_TIM234_CCMR2_OC3PE) |
                      (0 << STM_TIM234_CCMR2_OC3FE) |
                      (STM_TIM234_CCMR2_CC3S_OUTPUT << STM_TIM234_CCMR2_CC3S));
        tim->egr = 0;
@@ -150,25 +174,19 @@ ao_pwm_init(void)
                    (STM_TIM234_CR2_MMS_RESET<< STM_TIM234_CR2_MMS) |
                    (0 << STM_TIM234_CR2_CCDS));
 
-       tim->cr1 = ((STM_TIM234_CR1_CKD_1 << STM_TIM234_CR1_CKD) |
-                   (1 << STM_TIM234_CR1_ARPE) |
-                   (STM_TIM234_CR1_CMS_EDGE << STM_TIM234_CR1_CMS) |
-                   (STM_TIM234_CR1_DIR_UP << STM_TIM234_CR1_DIR) |
-                   (0 << STM_TIM234_CR1_OPM) |
-                   (0 << STM_TIM234_CR1_URS) |
-                   (0 << STM_TIM234_CR1_UDIS) |
-                   (1 << STM_TIM234_CR1_CEN));
-
-       stm_afr_set(&stm_gpiod, 12, STM_AFR_AF2);
+       stm_afr_set(AO_PWM_0_GPIO, AO_PWM_0_PIN, STM_AFR_AF2);
+       stm_ospeedr_set(AO_PWM_0_GPIO, AO_PWM_0_PIN, STM_OSPEEDR_40MHz);
 #if NUM_PWM > 1
-       stm_afr_set(&stm_gpiod, 13, STM_AFR_AF2);
+       stm_afr_set(AO_PWM_1_GPIO, AO_PWM_1_PIN, STM_AFR_AF2);
+       stm_ospeedr_set(AO_PWM_1_GPIO, AO_PWM_1_PIN, STM_OSPEEDR_40MHz);
 #endif
 #if NUM_PWM > 2
-       stm_afr_set(&stm_gpiod, 14, STM_AFR_AF2);
+       stm_afr_set(AO_PWM_2_GPIO, AO_PWM_2_PIN, STM_AFR_AF2);
+       stm_ospeedr_set(AO_PWM_2_GPIO, AO_PWM_2_PIN, STM_OSPEEDR_40MHz);
 #endif
 #if NUM_PWM > 3
-       stm_afr_set(&stm_gpiod, 15, STM_AFR_AF2);
+       stm_afr_set(AO_PWM_3_GPIO, AO_PWM_3_PIN, STM_AFR_AF2);
+       stm_ospeedr_set(AO_PWM_3_GPIO, AO_PWM_3_PIN, STM_OSPEEDR_40MHz);
 #endif
-
        ao_cmd_register(&ao_pwm_cmds[0]);
 }
index 799cccbd2a1848bd9510ad0aa1f62d2cea857ee3..01afedc625bc0b66fe4c07798237903019e5f2a9 100644 (file)
@@ -1775,7 +1775,7 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4;
 #define  STM_TIM234_CCMR1_OC1M_PWM_MODE_1              6
 #define  STM_TIM234_CCMR1_OC1M_PWM_MODE_2              7
 #define  STM_TIM234_CCMR1_OC1M_MASK                    7
-#define STM_TIM234_CCMR1_OC1PE 11
+#define STM_TIM234_CCMR1_OC1PE 3
 #define STM_TIM234_CCMR1_OC1FE 2
 #define STM_TIM234_CCMR1_CC1S  0
 #define  STM_TIM234_CCMR1_CC1S_OUTPUT                  0
@@ -1815,7 +1815,7 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4;
 #define  STM_TIM234_CCMR2_OC3M_PWM_MODE_1              6
 #define  STM_TIM234_CCMR2_OC3M_PWM_MODE_2              7
 #define  STM_TIM234_CCMR2_OC3M_MASK                    7
-#define STM_TIM234_CCMR2_OC3PE 11
+#define STM_TIM234_CCMR2_OC3PE 3
 #define STM_TIM234_CCMR2_OC3FE 2
 #define STM_TIM234_CCMR2_CC3S  0
 #define  STM_TIM234_CCMR2_CC3S_OUTPUT                  0
index b88dd08c4f78edc952d051cdbbf909a1508ed68c..ed5935b4c101ed5879655ae8d9ca17e57af456a6 100644 (file)
@@ -387,8 +387,20 @@ struct ao_adc {
  */
 
 #define NUM_PWM                        4
-#define PWM_MAX                        1024
+#define PWM_MAX                        1023
 #define AO_PWM_TIMER           stm_tim4
 #define AO_PWM_TIMER_ENABLE    STM_RCC_APB1ENR_TIM4EN
 
+#define AO_PWM_0_GPIO          (&stm_gpiod)
+#define AO_PWM_0_PIN           12
+
+#define AO_PWM_1_GPIO          (&stm_gpiod)
+#define AO_PWM_1_PIN           13
+
+#define AO_PWM_2_GPIO          (&stm_gpiod)
+#define AO_PWM_2_PIN           14
+
+#define AO_PWM_3_GPIO          (&stm_gpiod)
+#define AO_PWM_3_PIN           15
+
 #endif /* _AO_PINS_H_ */