diff options
| author | Keith Packard <keithp@keithp.com> | 2017-02-20 17:29:15 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-02-20 17:35:51 -0800 | 
| commit | 9603d737e9ea58217ff2c2dd7c350c7a29fba980 (patch) | |
| tree | 3b0996531b8021b43c4640e5154f3c2ba55042d0 /src | |
| parent | 003e9479ad4364d9f7acf189b35f32ccdfd43be0 (diff) | |
altos/stmf0: Support timer 2/3 for the beeper
Tested on timer 2, all four channels.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/stmf0/ao_beep_stm.c | 197 | ||||
| -rw-r--r-- | src/stmf0/stm32f0.h | 34 | 
2 files changed, 201 insertions, 30 deletions
| diff --git a/src/stmf0/ao_beep_stm.c b/src/stmf0/ao_beep_stm.c index 969538fd..84ccd93e 100644 --- a/src/stmf0/ao_beep_stm.c +++ b/src/stmf0/ao_beep_stm.c @@ -21,16 +21,51 @@  #error BEEPER_CHANNEL undefined  #endif +#ifndef BEEPER_TIMER +#define BEEPER_TIMER	1 +#endif + +#if BEEPER_TIMER == 1 +#define timer stm_tim1 +#define STM_RCC_TIMER STM_RCC_APB2ENR_TIM1EN +#define stm_rcc_enr stm_rcc.apb2enr +#endif + +#if BEEPER_TIMER == 2 +#define timer stm_tim2 +#define STM_RCC_TIMER STM_RCC_APB1ENR_TIM2EN +#define stm_rcc_enr stm_rcc.apb1enr +#endif + +#if BEEPER_TIMER == 3 +#define timer stm_tim3 +#define STM_RCC_TIMER STM_RCC_APB1ENR_TIM3EN +#define stm_rcc_enr stm_rcc.apb1enr +#endif + +#ifndef timer +#error BEEPER_TIMER invalid +#endif + +static inline void +disable(void) +{ +	timer.cr1 = 0; +#if BEEPER_TIMER == 1 +	timer.bdtr = 0; +#endif +	stm_rcc_enr &= ~(1 << STM_RCC_TIMER); +} +  void  ao_beep(uint8_t beep)  {  	if (beep == 0) { -		stm_tim1.cr1 = 0; -		stm_tim1.bdtr = 0; -		stm_rcc.apb2enr &= ~(1 << STM_RCC_APB2ENR_TIM1EN); +		disable();  	} else { -		stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_TIM1EN); +		stm_rcc_enr |= (1 << STM_RCC_TIMER); +#if BEEPER_TIMER == 1  		/* Master output enable */  		stm_tim1.bdtr = (1 << STM_TIM1_BDTR_MOE); @@ -184,6 +219,149 @@ ao_beep(uint8_t beep)  		/* Update the values */  		stm_tim1.egr = (1 << STM_TIM1_EGR_UG); +#endif +#if BEEPER_TIMER == 2 || BEEPER_TIMER == 3 + +		timer.cr2 = ((0 << STM_TIM23_CR2_TI1S) | +			     (STM_TIM23_CR2_MMS_RESET << STM_TIM23_CR2_MMS) | +			     (0 << STM_TIM23_CR2_CCDS)); + +		/* Set prescaler to match cc1111 clocks +		 */ +		timer.psc = AO_TIM_CLK / 750000; + +		/* 1. Select the counter clock (internal, external, prescaler). +		 * +		 * Setting SMCR to zero means use the internal clock +		 */ + +		timer.smcr = 0; + +		/* 2. Write the desired data in the TIMx_ARR and TIMx_CCRx registers. */ +		timer.arr = beep; +		timer.ccr1 = beep; + +		/* 3. Set the CCxIE and/or CCxDE bits if an interrupt and/or a +		 * DMA request is to be generated. +		 */ +		/* don't want this */ + +		/* 4. Select the output mode. For example, you must write +		 *  OCxM=011, OCxPE=0, CCxP=0 and CCxE=1 to toggle OCx output +		 *  pin when CNT matches CCRx, CCRx preload is not used, OCx +		 *  is enabled and active high. +		 */ + +#if BEEPER_CHANNEL == 1 +		timer.ccmr1 = ((0 << STM_TIM23_CCMR1_OC2CE) | +			       (STM_TIM23_CCMR1_OC2M_FROZEN << STM_TIM23_CCMR1_OC2M) | +			       (0 << STM_TIM23_CCMR1_OC2PE) | +			       (0 << STM_TIM23_CCMR1_OC2FE) | +			       (STM_TIM23_CCMR1_CC2S_OUTPUT << STM_TIM23_CCMR1_CC2S) | + +			       (0 << STM_TIM23_CCMR1_OC1CE) | +			       (STM_TIM23_CCMR1_OC1M_TOGGLE << STM_TIM23_CCMR1_OC1M) | +			       (0 << STM_TIM23_CCMR1_OC1PE) | +			       (0 << STM_TIM23_CCMR1_OC1FE) | +			       (STM_TIM23_CCMR1_CC1S_OUTPUT << STM_TIM23_CCMR1_CC1S)); + +		timer.ccer = ((0 << STM_TIM23_CCER_CC4P) | +			      (0 << STM_TIM23_CCER_CC4E) | +			      (0 << STM_TIM23_CCER_CC3NP) | +			      (0 << STM_TIM23_CCER_CC3P) | +			      (0 << STM_TIM23_CCER_CC3E) | +			      (0 << STM_TIM23_CCER_CC2NP) | +			      (0 << STM_TIM23_CCER_CC2P) | +			      (0 << STM_TIM23_CCER_CC2E) | +			      (0 << STM_TIM23_CCER_CC1P) | +			      (1 << STM_TIM23_CCER_CC1E)); +#endif +#if BEEPER_CHANNEL == 2 +		timer.ccmr1 = ((0 << STM_TIM23_CCMR1_OC2CE) | +			       (STM_TIM23_CCMR1_OC2M_TOGGLE << STM_TIM23_CCMR1_OC2M) | +			       (0 << STM_TIM23_CCMR1_OC2PE) | +			       (0 << STM_TIM23_CCMR1_OC2FE) | +			       (STM_TIM23_CCMR1_CC2S_OUTPUT << STM_TIM23_CCMR1_CC2S) | + +			       (0 << STM_TIM23_CCMR1_OC1CE) | +			       (STM_TIM23_CCMR1_OC1M_FROZEN << STM_TIM23_CCMR1_OC1M) | +			       (0 << STM_TIM23_CCMR1_OC1PE) | +			       (0 << STM_TIM23_CCMR1_OC1FE) | +			       (STM_TIM23_CCMR1_CC1S_OUTPUT << STM_TIM23_CCMR1_CC1S)); + +		timer.ccer = ((0 << STM_TIM23_CCER_CC4P) | +			      (0 << STM_TIM23_CCER_CC4E) | +			      (0 << STM_TIM23_CCER_CC3NP) | +			      (0 << STM_TIM23_CCER_CC3P) | +			      (0 << STM_TIM23_CCER_CC3E) | +			      (0 << STM_TIM23_CCER_CC2NP) | +			      (0 << STM_TIM23_CCER_CC2P) | +			      (1 << STM_TIM23_CCER_CC2E) | +			      (0 << STM_TIM23_CCER_CC1P) | +			      (0 << STM_TIM23_CCER_CC1E)); +#endif +#if BEEPER_CHANNEL == 3 +		timer.ccmr2 = ((0 << STM_TIM23_CCMR2_OC4CE) | +			       (STM_TIM23_CCMR2_OC4M_FROZEN << STM_TIM23_CCMR2_OC4M) | +			       (0 << STM_TIM23_CCMR2_OC4PE) | +			       (0 << STM_TIM23_CCMR2_OC4FE) | +			       (STM_TIM23_CCMR2_CC4S_OUTPUT << STM_TIM23_CCMR2_CC4S) | + +			       (0 << STM_TIM23_CCMR2_OC3CE) | +			       (STM_TIM23_CCMR2_OC3M_TOGGLE << STM_TIM23_CCMR2_OC3M) | +			       (0 << STM_TIM23_CCMR2_OC3PE) | +			       (0 << STM_TIM23_CCMR2_OC3FE) | +			       (STM_TIM23_CCMR2_CC3S_OUTPUT << STM_TIM23_CCMR2_CC3S)); + +		timer.ccer = ((0 << STM_TIM23_CCER_CC4P) | +			      (0 << STM_TIM23_CCER_CC4E) | +			      (0 << STM_TIM23_CCER_CC3NP) | +			      (0 << STM_TIM23_CCER_CC3P) | +			      (1 << STM_TIM23_CCER_CC3E) | +			      (0 << STM_TIM23_CCER_CC2NP) | +			      (0 << STM_TIM23_CCER_CC2P) | +			      (0 << STM_TIM23_CCER_CC2E) | +			      (0 << STM_TIM23_CCER_CC1P) | +			      (0 << STM_TIM23_CCER_CC1E)); +#endif +#if BEEPER_CHANNEL == 4 +		timer.ccmr2 = ((0 << STM_TIM23_CCMR2_OC4CE) | +			       (STM_TIM23_CCMR2_OC4M_TOGGLE << STM_TIM23_CCMR2_OC4M) | +			       (0 << STM_TIM23_CCMR2_OC4PE) | +			       (0 << STM_TIM23_CCMR2_OC4FE) | +			       (STM_TIM23_CCMR2_CC4S_OUTPUT << STM_TIM23_CCMR2_CC4S) | + +			       (0 << STM_TIM23_CCMR2_OC3CE) | +			       (STM_TIM23_CCMR2_OC3M_FROZEN << STM_TIM23_CCMR2_OC3M) | +			       (0 << STM_TIM23_CCMR2_OC3PE) | +			       (0 << STM_TIM23_CCMR2_OC3FE) | +			       (STM_TIM23_CCMR2_CC3S_OUTPUT << STM_TIM23_CCMR2_CC3S)); + +		timer.ccer = ((0 << STM_TIM23_CCER_CC4P) | +			      (1 << STM_TIM23_CCER_CC4E) | +			      (0 << STM_TIM23_CCER_CC3NP) | +			      (0 << STM_TIM23_CCER_CC3P) | +			      (0 << STM_TIM23_CCER_CC3E) | +			      (0 << STM_TIM23_CCER_CC2NP) | +			      (0 << STM_TIM23_CCER_CC2P) | +			      (0 << STM_TIM23_CCER_CC2E) | +			      (0 << STM_TIM23_CCER_CC1P) | +			      (0 << STM_TIM23_CCER_CC1E)); +#endif +		/* 5. Enable the counter by setting the CEN bit in the TIMx_CR1 register. */ + +		timer.cr1 = ((STM_TIM23_CR1_CKD_1 << STM_TIM23_CR1_CKD) | +			     (0 << STM_TIM23_CR1_ARPE) | +			     (STM_TIM23_CR1_CMS_EDGE << STM_TIM23_CR1_CMS) | +			     (0 << STM_TIM23_CR1_DIR) | +			     (0 << STM_TIM23_CR1_OPM) | +			     (0 << STM_TIM23_CR1_URS) | +			     (0 << STM_TIM23_CR1_UDIS) | +			     (1 << STM_TIM23_CR1_CEN)); + +		/* Update the values */ +		timer.egr = (1 << STM_TIM23_EGR_UG); +#endif  	}  } @@ -198,16 +376,9 @@ ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant  void  ao_beep_init(void)  { -#if BEEPER_CHANNEL == 3 -	/* Our beeper is on PA10, which is hooked to TIM1_CH3. -	 */ -	ao_enable_port(&stm_gpioa); -	stm_afr_set(&stm_gpioa, 10, STM_AFR_AF2); -#else  	ao_enable_port(BEEPER_PORT);  	stm_afr_set(BEEPER_PORT, BEEPER_PIN, STM_AFR_AF2); -#endif -	/* Leave the timer off until requested */ -	stm_rcc.apb2enr &= ~(1 << STM_RCC_APB2ENR_TIM1EN); +	/* Leave the timer off until requested */ +	stm_rcc_enr &= ~(1 << STM_RCC_TIMER);  } diff --git a/src/stmf0/stm32f0.h b/src/stmf0/stm32f0.h index 1c33f020..e53a5dfd 100644 --- a/src/stmf0/stm32f0.h +++ b/src/stmf0/stm32f0.h @@ -1812,15 +1812,15 @@ extern struct stm_tim23 stm_tim2, stm_tim3;  #define STM_TIM23_CCMR2_OC4CE	15  #define STM_TIM23_CCMR2_OC4M	12 -#define  STM_TIM23_CCMR2_OCM_FROZEN			0 -#define  STM_TIM23_CCMR2_OCM_SET_HIGH_ON_MATCH	1 -#define  STM_TIM23_CCMR2_OCM_SET_LOW_ON_MATCH		2 -#define  STM_TIM23_CCMR2_OCM_TOGGLE			3 -#define  STM_TIM23_CCMR2_OCM_FORCE_LOW			4 -#define  STM_TIM23_CCMR2_OCM_FORCE_HIGH			5 -#define  STM_TIM23_CCMR2_OCM_PWM_MODE_1			6 -#define  STM_TIM23_CCMR2_OCM_PWM_MODE_2			7 -#define  STM_TIM23_CCMR2_OCM_MASK			7 +#define  STM_TIM23_CCMR2_OC4M_FROZEN			0 +#define  STM_TIM23_CCMR2_OC4M_SET_HIGH_ON_MATCH	1 +#define  STM_TIM23_CCMR2_OC4M_SET_LOW_ON_MATCH		2 +#define  STM_TIM23_CCMR2_OC4M_TOGGLE			3 +#define  STM_TIM23_CCMR2_OC4M_FORCE_LOW			4 +#define  STM_TIM23_CCMR2_OC4M_FORCE_HIGH		5 +#define  STM_TIM23_CCMR2_OC4M_PWM_MODE_1		6 +#define  STM_TIM23_CCMR2_OC4M_PWM_MODE_2		7 +#define  STM_TIM23_CCMR2_OC4M_MASK			7  #define STM_TIM23_CCMR2_OC4PE	11  #define STM_TIM23_CCMR2_OC4FE	10  #define STM_TIM23_CCMR2_CC4S	8 @@ -1832,15 +1832,15 @@ extern struct stm_tim23 stm_tim2, stm_tim3;  #define STM_TIM23_CCMR2_OC3CE	7  #define STM_TIM23_CCMR2_OC3M	4 -#define  STM_TIM23_CCMR2_OCM_FROZEN			0 -#define  STM_TIM23_CCMR2_OCM_SET_HIGH_ON_MATCH		1 -#define  STM_TIM23_CCMR2_OCM_SET_LOW_ON_MATCH		2 -#define  STM_TIM23_CCMR2_OCM_TOGGLE			3 -#define  STM_TIM23_CCMR2_OCM_FORCE_LOW			4 -#define  STM_TIM23_CCMR2_OCM_FORCE_HIGH			5 +#define  STM_TIM23_CCMR2_OC3M_FROZEN			0 +#define  STM_TIM23_CCMR2_OC3M_SET_HIGH_ON_MATCH		1 +#define  STM_TIM23_CCMR2_OC3M_SET_LOW_ON_MATCH		2 +#define  STM_TIM23_CCMR2_OC3M_TOGGLE			3 +#define  STM_TIM23_CCMR2_OC3M_FORCE_LOW			4 +#define  STM_TIM23_CCMR2_OC3M_FORCE_HIGH		5  #define  STM_TIM23_CCMR2_OC3M_PWM_MODE_1		6 -#define  STM_TIM23_CCMR2_OCM_PWM_MODE_2			7 -#define  STM_TIM23_CCMR2_OCM_MASK			7 +#define  STM_TIM23_CCMR2_OC3M_PWM_MODE_2		7 +#define  STM_TIM23_CCMR2_OC3M_MASK			7  #define STM_TIM23_CCMR2_OC3PE	11  #define STM_TIM23_CCMR2_OC3FE	2  #define STM_TIM23_CCMR2_CC3S	0 | 
