diff options
| author | Keith Packard <keithp@keithp.com> | 2015-12-25 23:20:29 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2015-12-25 23:20:29 -0800 | 
| commit | 742f7c834bb5d651d2bebf2069d4e8facc33390d (patch) | |
| tree | 3e788eb5b228717467a802a882a1d348a7b0acc1 | |
| parent | 8aa0ab9fe9ca41f6d520d388973164bc0c599a06 (diff) | |
altos: Get stm32l pwm driver working
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>
| -rw-r--r-- | src/stm/ao_pwm_stm.c | 80 | ||||
| -rw-r--r-- | src/stm/stm32l.h | 4 | ||||
| -rw-r--r-- | src/telemega-v2.0/ao_pins.h | 14 | 
3 files changed, 64 insertions, 34 deletions
| diff --git a/src/stm/ao_pwm_stm.c b/src/stm/ao_pwm_stm.c index cea21030..ce1fa6f3 100644 --- a/src/stm/ao_pwm_stm.c +++ b/src/stm/ao_pwm_stm.c @@ -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]);  } diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 799cccbd..01afedc6 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -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 diff --git a/src/telemega-v2.0/ao_pins.h b/src/telemega-v2.0/ao_pins.h index b88dd08c..ed5935b4 100644 --- a/src/telemega-v2.0/ao_pins.h +++ b/src/telemega-v2.0/ao_pins.h @@ -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_ */ | 
