From 87ad1594c31aa4ec12db3095103fe6fd0b1f9cf6 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 16 Dec 2011 19:29:41 +0000 Subject: [PATCH] Add framework for lower half STM32 PWM driver; updates to the STM32 ADC driver git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4192 42af7a65-404d-4744-a932-0658087f49c3 --- arch/arm/src/stm32/Make.defs | 4 + arch/arm/src/stm32/stm32_adc.c | 378 ++++++++++++++++++++++++--- arch/arm/src/stm32/stm32_adc.h | 98 +++++++ arch/arm/src/stm32/stm32_dac.c | 56 ++-- arch/arm/src/stm32/stm32_dac.h | 53 ++++ arch/arm/src/stm32/stm32_pwm.c | 459 +++++++++++++++++++++++++++++++++ arch/arm/src/stm32/stm32_pwm.h | 154 +++++++++++ arch/arm/src/stm32/stm32_tim.c | 80 +++++- arch/arm/src/stm32/stm32_tim.h | 226 ++++++++-------- 9 files changed, 1328 insertions(+), 180 deletions(-) create mode 100644 arch/arm/src/stm32/stm32_pwm.c create mode 100644 arch/arm/src/stm32/stm32_pwm.h diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs index 402a325330..d877516ab8 100644 --- a/arch/arm/src/stm32/Make.defs +++ b/arch/arm/src/stm32/Make.defs @@ -83,6 +83,10 @@ ifeq ($(CONFIG_DAC),y) CHIP_CSRCS += stm32_dac.c endif +ifeq ($(CONFIG_PWM),y) +CHIP_CSRCS += stm32_pwm.c +endif + ifeq ($(CONFIG_DEBUG),y) CHIP_CSRCS += stm32_dumpgpio.c endif diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index b8eac533a4..6438429526 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -83,7 +83,131 @@ #if defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2) || defined(CONFIG_STM32_ADC3) -/* ADC interrupts */ +/* Timer configuration: If a timer trigger is specified, then get information + * about the timer. + */ + +#if defined(CONFIG_STM32_TIM1_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC1 +# define ADC1_TIMER_BASE STM32_TIM1_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY +#elif defined(CONFIG_STM32_TIM2_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2 +# define ADC1_TIMER_BASE STM32_TIM2_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM3_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC1 +# define ADC1_TIMER_BASE STM32_TIM3_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM4_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4 +# define ADC1_TIMER_BASE STM32_TIM4_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM5_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC1 +# define ADC1_TIMER_BASE STM32_TIM5_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM8_ADC1) +# define ADC1_HAVE_TIMER 1 +# define ADC1_EXTSEL_VALUE ??? which ???? +# define ADC1_TIMER_BASE STM32_TIM8_BASE +# define ADC1_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY +#else +# undef ADC1_HAVE_TIMER +#endif + +#if defined(ADC1_HAVE_TIMER) && !defined(CONFIG_STM32_ADC1_SAMPLE_FREQUENCY) +# error "CONFIG_STM32_ADC1_SAMPLE_FREQUENCY not defined" +#endif + +#if defined(CONFIG_STM32_TIM1_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC1 +# define ADC2_TIMER_BASE STM32_TIM1_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY +#elif defined(CONFIG_STM32_TIM2_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2 +# define ADC2_TIMER_BASE STM32_TIM2_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM3_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC1 +# define ADC2_TIMER_BASE STM32_TIM3_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM4_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4 +# define ADC2_TIMER_BASE STM32_TIM4_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM5_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC1 +# define ADC2_TIMER_BASE STM32_TIM5_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM8_ADC2) +# define ADC2_HAVE_TIMER 1 +# define ADC2_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC1 +# define ADC2_TIMER_BASE STM32_TIM8_BASE +# define ADC2_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY +#else +# undef ADC2_HAVE_TIMER +#endif + +#if defined(ADC2_HAVE_TIMER) && !defined(CONFIG_STM32_ADC2_SAMPLE_FREQUENCY) +# error "CONFIG_STM32_ADC2_SAMPLE_FREQUENCY not defined" +#endif + +#if defined(CONFIG_STM32_TIM1_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T1CC1 +# define ADC3_TIMER_BASE STM32_TIM1_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY +#elif defined(CONFIG_STM32_TIM2_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T2CC2 +# define ADC3_TIMER_BASE STM32_TIM2_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM3_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T3CC1 +# define ADC3_TIMER_BASE STM32_TIM3_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM4_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T4CC4 +# define ADC3_TIMER_BASE STM32_TIM4_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM5_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T5CC1 +# define ADC3_TIMER_BASE STM32_TIM5_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY +#elif defined(CONFIG_STM32_TIM8_ADC3) +# define ADC3_HAVE_TIMER 1 +# define ADC3_EXTSEL_VALUE ADC_CR2_EXTSEL_T8CC1 +# define ADC3_TIMER_BASE STM32_TIM8_BASE +# define ADC3_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY +#else +# undef ADC3_HAVE_TIMER +#endif + +#if defined(ADC3_HAVE_TIMER) && !defined(CONFIG_STM32_ADC3_SAMPLE_FREQUENCY) +# error "CONFIG_STM32_ADC3_SAMPLE_FREQUENCY not defined" +#endif + +#if defined(ADC1_HAVE_TIMER) || defined(ADC2_HAVE_TIMER) || defined(ADC3_HAVE_TIMER) +# define ADC_HAVE_TIMER 1 +#else +# undef ADC_HAVE_TIMER +#endif + +/* ADC interrupts ***********************************************************/ #ifdef CONFIG_STM32_STM32F10XX # define ADC_SR_ALLINTS (ADC_SR_AWD | ADC_SR_EOC | ADC_SR_JEOC) @@ -97,7 +221,24 @@ # define ADC_CR1_ALLINTS (ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_JEOCIE | ADC_CR1_OVRIE) #endif -/* The maximum number of samples */ +/* Timer Setup **************************************************************/ +/* Calculate timer divider values based upon ADCn_TIMER_PCLK_FREQUENCY and + * CONFIG_STM32_ADCn_SAMPLE_FREQUENCY. + */ + +#ifdef ADC1_HAVE_TIMER +# warning "Missing Logic" +#endif + +#ifdef ADC2_HAVE_TIMER +# warning "Missing Logic" +#endif + +#ifdef ADC3_HAVE_TIMER +# warning "Missing Logic" +#endif + +/* The maximum number of channels that can be sampled */ #define ADC_MAX_SAMPLES 16 @@ -115,6 +256,11 @@ struct stm32_dev_s uint8_t current; /* Current ADC channel being converted */ xcpt_t isr; /* Interrupt handler for this ADC block */ uint32_t base; /* Base address of registers unique to this ADC block */ +#ifdef ADC_HAVE_TIMER + uint32_t tbase; /* Base address of timer used by this ADC block */ + uint32_t extsel; /* EXTSEL value used by this ADC block */ + uint32_t pclck; /* The PCLK frequency that drivers this timer */ +#endif uint8_t chanlist[ADC_MAX_SAMPLES]; }; @@ -149,7 +295,12 @@ static int adc_setup(FAR struct adc_dev_s *dev); static void adc_shutdown(FAR struct adc_dev_s *dev); static void adc_rxint(FAR struct adc_dev_s *dev, bool enable); static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); -static void adc_enable(FAR struct adc_dev_s *dev, bool enable); +static void adc_enable(FAR struct stm32_dev_s *priv, bool enable); + +#ifdef ADC_HAVE_TIMER +static int adc_timinit(FAR struct stm32_dev_s *priv); +#endif +static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable); /**************************************************************************** * Private Data @@ -180,6 +331,11 @@ static struct stm32_dev_s g_adcpriv1 = #endif .intf = 1, .base = STM32_ADC1_BASE, +#ifdef ADC1_HAVE_TIMER + .tbase = ADC1_TIMER_BASE, + .extsel = ADC1_EXTSEL_VALUE, + .pclck = ADC1_TIMER_PCLK_FREQUENCY, +#endif }; static struct adc_dev_s g_adcdev1 = @@ -203,6 +359,11 @@ static struct stm32_dev_s g_adcpriv2 = #endif .intf = 2; .base = STM32_ADC2_BASE, +#ifdef ADC2_HAVE_TIMER + .tbase = ADC2_TIMER_BASE, + .extsel = ADC2_EXTSEL_VALUE, + .pclck = ADC2_TIMER_PCLK_FREQUENCY, +#endif }; static struct adc_dev_s g_adcdev2 = @@ -226,6 +387,11 @@ static struct stm32_dev_s g_adcpriv3 = #endif .intf = 3; .base = STM32_ADC3_BASE, +#ifdef ADC3_HAVE_TIMER + .tbase = ADC3_TIMER_BASE, + .extsel = ADC3_EXTSEL_VALUE, + .pclck = ADC3_TIMER_PCLK_FREQUENCY, +#endif }; static struct adc_dev_s g_adcdev3 = @@ -277,6 +443,116 @@ static void adc_putreg(struct stm32_dev_s *priv, int offset, uint32_t value) putreg32(value, priv->base + offset); } +/**************************************************************************** + * Name: tim_getreg + * + * Description: + * Read the value of an ADC timer register. + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +#ifdef HAVE_DMA +static uint32_t tim_getreg(struct stm32_dev_s *priv, int offset) +{ + return getreg32(priv->tbase + offset); +} +#endif + +/**************************************************************************** + * Name: tim_putreg + * + * Description: + * Read the value of an ADC timer register. + * + * Input Parameters: + * priv - A reference to the ADC block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void tim_putreg(struct stm32_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->tbase + offset); +} +#endif + +/**************************************************************************** + * Name: adc_timinit + * + * Description: + * Initialize the timer that drivers the ADC sampling for this channel using + * the pre-calculated timer divider definitions. + * + * Input Parameters: + * chan - A reference to the DAC channel state data + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef ADC_HAVE_TIMER +static int adc_timinit(FAR struct stm32_dev_s *priv) +{ + /* Configure the time base: Timer period, prescaler, clock division, + * counter mode (up). + */ +#warning "Missing Logic" + + /* Selection EXTSEL selection: update */ +#warning "Missing Logic" + + /* Enable the counter */ +#warning "Missing Logic" +} +#endif + +/**************************************************************************** + * Name: adc_startconv + * + * Description: + * Start (or stop) the ADC conversion process + * + * Input Parameters: + * priv - A reference to the ADC block status + * enable - True: Start conversion + * + * Returned Value: + * + ****************************************************************************/ + +static void adc_startconv(struct stm32_dev_s *priv, bool enable) +{ + uint32_t regval; + + avdbg("enable: %d\n", enable); + + regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET); + if (enable) + { + /* Start conversion of regular channles */ + + regval |= ADC_CR2_SWSTART; + } + else + { + /* Disable the conversion of regular channels */ + + regval &= ~ADC_CR2_SWSTART; + } + regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET); +} + /**************************************************************************** * Name: adc_rccreset * @@ -363,9 +639,8 @@ static void adc_rccreset(struct stm32_dev_s *priv, bool reset) * *******************************************************************************/ -static void adc_enable(FAR struct adc_dev_s *dev, bool enable) +static void adc_enable(FAR struct stm32_dev_s *priv, bool enable) { - FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; uint32_t regval; avdbg("enable: %d\n", enable); @@ -380,6 +655,10 @@ static void adc_enable(FAR struct adc_dev_s *dev, bool enable) regval &= ~ADC_CR2_ADON; } adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval); + + /* Enable or disable conversions */ + +//adc_startconv(priv, enable); } /**************************************************************************** @@ -473,38 +752,47 @@ static void adc_reset(FAR struct adc_dev_s *dev) regval |= ADC_CR1_AWDEN; /* AWDIE: Analog watchdog interrupt enable */ - + regval |= ADC_CR1_AWDIE; - + /* EOCIE: Interrupt enable for EOC */ regval |= ADC_CR1_EOCIE; - + adc_putreg(priv, STM32_ADC_CR1_OFFSET, regval); -#warning "Only one channel is able to be guarded for the watchdog" -#warning "The channel is configured in the ADC_CR1_AWDCH [4:0]" -#warning "We have to decide if we need this watchdog " - /* ADC1 CR2 Configuration */ - - /* Set the ADON bit to wake up the ADC from power down mode */ regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET); - regval |= ADC_CR2_ADON; - + /* Clear CONT, ALIGN (Right = 0) and EXTTRIG bits */ regval &= ~ADC_CR2_CONT; regval &= ~ADC_CR2_ALIGN; regval &= ~ADC_CR2_EXTSEL_MASK; - - /* SWSTART: Start conversion of regular channels */ -#warning "Don't you want to finish setting up the registers before starting the conversion?" - regval |= ADC_CR2_SWSTART; - adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval); + /* EXTTRIG: External Trigger Conversion mode for regular channels enable*/ + //regval |= ADC_CR2_EXTTRIG; + + /* EXTSEL[2:0]: External event select for regular group + * These bits select the external event used to trigger the start + * of conversion of a regular group: + * 000: Timer 1 CC1 event + * 001: Timer 1 CC2 event + * 010: Timer 1 CC3 event + * 011: Timer 2 CC2 event + * 100: Timer 3 TRGO event + * 101: Timer 4 CC4 event + * 110: EXTI line11/TIM8_TRGO event (TIM8_TRGO is available only in high-density devices) + * 111: SWSTART + */ + + /* Select trigger when SWSTART is set */ + //regval |= ADC_CR2_EXTSEL_SWSTART; + + adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval); + /* Configuration of the channel conversions */ regval = adc_getreg(priv, STM32_ADC_SQR3_OFFSET) & ADC_SQR3_RESERVED; @@ -513,7 +801,7 @@ static void adc_reset(FAR struct adc_dev_s *dev) regval |= (uint32_t)priv->chanlist[i] << offset; } adc_putreg(priv, STM32_ADC_SQR3_OFFSET, regval); - + regval = adc_getreg(priv, STM32_ADC_SQR2_OFFSET) & ADC_SQR2_RESERVED; for (i = 6, offset = 0; i < priv->nchannels && i < 12; i++, offset += 5) { @@ -537,15 +825,21 @@ static void adc_reset(FAR struct adc_dev_s *dev) /* Set the channel index of the first conversion */ priv->current = 0; - irqrestore(flags); - avdbg("CR1: 0x%08x CR2: 0x%08x\n", + /* Set ADON to wake up the ADC from Power Down state. */ + + adc_enable(priv, true); + adc_startconv(priv, true); + irqrestore(flags); + + avdbg("SR: %08x CR1: 0x%08x CR2: 0x%08x\n", + adc_getreg(priv, STM32_ADC_SR_OFFSET), adc_getreg(priv, STM32_ADC_CR1_OFFSET), - adc_getreg(priv, STM32_ADC_CR2_OFFSET)) + adc_getreg(priv, STM32_ADC_CR2_OFFSET)); avdbg("SQR1: 0x%08x SQR2: 0x%08x SQR3: 0x%08x\n", adc_getreg(priv, STM32_ADC_SQR1_OFFSET), adc_getreg(priv, STM32_ADC_SQR2_OFFSET), - adc_getreg(priv, STM32_ADC_SQR3_OFFSET)) + adc_getreg(priv, STM32_ADC_SQR3_OFFSET)); } /**************************************************************************** @@ -632,9 +926,9 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) regval = adc_getreg(priv, STM32_ADC_CR1_OFFSET); if (enable) { - /* Enable the end-of-conversion ADC interrupt */ + /* Enable the end-of-conversion ADC and analog watchdog interrupts */ - regval |= ADC_CR1_EOCIE; + regval |= (ADC_CR1_EOCIE | ADC_CR1_AWDIE); } else { @@ -659,7 +953,7 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) { - avdbg("intf: %d\n", priv->intf); + avdbg("Entry\n"); return -ENOTTY; } @@ -680,7 +974,6 @@ static int adc_interrupt(FAR struct adc_dev_s *dev) FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; uint32_t adcsr; int32_t value; - uint8_t ch; avdbg("intf: %d\n", priv->intf); @@ -700,6 +993,10 @@ static int adc_interrupt(FAR struct adc_dev_s *dev) value = adc_getreg(priv, STM32_ADC_DR_OFFSET); value &= ADC_DR_DATA_MASK; +#ifdef ADC_DUALMODE +#error "not yet implemented" + value &= ADC_DR_ADC2DATA_MASK; +#endif /* Give the ADC data to the ADC dirver. adc_receive accepts 3 parameters: * @@ -708,18 +1005,21 @@ static int adc_interrupt(FAR struct adc_dev_s *dev) * 3) The third is the converted data for the channel. */ - adc_receive(dev, priv->current, value); + avdbg("Calling adc_receive(priv, ch=%d, value=%d)\n", + priv->chanlist[priv->current], value); + adc_receive(dev, priv->chanlist[priv->current], value); + /* Set the channel number of the next channel that will complete conversion */ if (++priv->current >= priv->nchannels) { - /* Restart the conversion sequence from the beginning */ + /* Restart the conversion sequence from the beginning */ #warning "Missing logic" - - /* Reset the index to the first channel to be converted */ - - priv->current = 0; + + /* Reset the index to the first channel to be converted */ + + priv->current = 0; } } @@ -744,7 +1044,7 @@ static int adc12_interrupt(int irq, void *context) uint32_t regval; uint32_t pending; - avdbg("irq: %d\n"); + avdbg("irq: %d\n", irq); /* Check for pending ADC1 interrupts */ @@ -793,7 +1093,7 @@ static int adc3_interrupt(int irq, void *context) uint32_t regval; uint32_t pending; - avdbg("irq: %d\n"); + avdbg("irq: %d\n", irq); /* Check for pending ADC3 interrupts */ @@ -828,7 +1128,7 @@ static int adc123_interrupt(int irq, void *context) uint32_t regval; uint32_t pending; - avdbg("irq: %d\n"); + avdbg("irq: %d\n", irq); /* Check for pending ADC1 interrupts */ diff --git a/arch/arm/src/stm32/stm32_adc.h b/arch/arm/src/stm32/stm32_adc.h index eb5926f288..ce778c5d24 100644 --- a/arch/arm/src/stm32/stm32_adc.h +++ b/arch/arm/src/stm32/stm32_adc.h @@ -47,6 +47,104 @@ #include +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is to + * control periodic ADC sampling. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_ADC must also be defined to indicate that timer "n" is intended + * to be used for that purpose. + */ + +/* For the STM32 F1 line, timers 1-4 may be used. For STM32 F4 line, timers 1-5 and + * 8 may be used. + */ + +#ifndef CONFIG_STM32_TIM1 +# undef CONFIG_STM32_TIM1_ADC +# undef CONFIG_STM32_TIM1_ADC1 +# undef CONFIG_STM32_TIM1_ADC2 +# undef CONFIG_STM32_TIM1_ADC3 +#endif +#ifndef CONFIG_STM32_TIM2 +# undef CONFIG_STM32_TIM2_ADC +# undef CONFIG_STM32_TIM2_ADC1 +# undef CONFIG_STM32_TIM2_ADC2 +# undef CONFIG_STM32_TIM2_ADC3 +#endif +#ifndef CONFIG_STM32_TIM3 +# undef CONFIG_STM32_TIM3_ADC +# undef CONFIG_STM32_TIM3_ADC1 +# undef CONFIG_STM32_TIM3_ADC2 +# undef CONFIG_STM32_TIM3_ADC3 +#endif +#ifndef CONFIG_STM32_TIM4 +# undef CONFIG_STM32_TIM4_ADC +# undef CONFIG_STM32_TIM4_ADC1 +# undef CONFIG_STM32_TIM4_ADC2 +# undef CONFIG_STM32_TIM4_ADC3 +#endif + +#if defined(CONFIG_STM32_STM32F40XX) +# ifndef CONFIG_STM32_TIM5 +# undef CONFIG_STM32_TIM5_ADC +# undef CONFIG_STM32_TIM5_ADC1 +# undef CONFIG_STM32_TIM5_ADC2 +# undef CONFIG_STM32_TIM5_ADC3 +# endif +# ifndef CONFIG_STM32_TIM8 +# undef CONFIG_STM32_TIM8_ADC +# undef CONFIG_STM32_TIM8_ADC1 +# undef CONFIG_STM32_TIM8_ADC2 +# undef CONFIG_STM32_TIM8_ADC3 +# endif +#else +# undef CONFIG_STM32_TIM5_ADC +# undef CONFIG_STM32_TIM5_ADC1 +# undef CONFIG_STM32_TIM5_ADC2 +# undef CONFIG_STM32_TIM5_ADC3 +# undef CONFIG_STM32_TIM8_ADC +# undef CONFIG_STM32_TIM8_ADC1 +# undef CONFIG_STM32_TIM8_ADC2 +# undef CONFIG_STM32_TIM8_ADC3 +#endif + +/* Timers 6, 7, and 10-14 are not used with the ADC by any supported family */ + +#undef CONFIG_STM32_TIM6_ADC +#undef CONFIG_STM32_TIM6_ADC1 +#undef CONFIG_STM32_TIM6_ADC2 +#undef CONFIG_STM32_TIM6_ADC3 +#undef CONFIG_STM32_TIM7_ADC +#undef CONFIG_STM32_TIM7_ADC1 +#undef CONFIG_STM32_TIM7_ADC2 +#undef CONFIG_STM32_TIM7_ADC3 +#undef CONFIG_STM32_TIM9_ADC +#undef CONFIG_STM32_TIM9_ADC1 +#undef CONFIG_STM32_TIM9_ADC2 +#undef CONFIG_STM32_TIM9_ADC3 +#undef CONFIG_STM32_TIM10_ADC +#undef CONFIG_STM32_TIM10_ADC1 +#undef CONFIG_STM32_TIM10_ADC2 +#undef CONFIG_STM32_TIM10_ADC3 +#undef CONFIG_STM32_TIM11_ADC +#undef CONFIG_STM32_TIM11_ADC1 +#undef CONFIG_STM32_TIM11_ADC2 +#undef CONFIG_STM32_TIM11_ADC3 +#undef CONFIG_STM32_TIM12_ADC +#undef CONFIG_STM32_TIM12_ADC1 +#undef CONFIG_STM32_TIM12_ADC2 +#undef CONFIG_STM32_TIM12_ADC3 +#undef CONFIG_STM32_TIM13_ADC +#undef CONFIG_STM32_TIM13_ADC1 +#undef CONFIG_STM32_TIM13_ADC2 +#undef CONFIG_STM32_TIM13_ADC3 +#undef CONFIG_STM32_TIM14_ADC +#undef CONFIG_STM32_TIM14_ADC1 +#undef CONFIG_STM32_TIM14_ADC2 +#undef CONFIG_STM32_TIM14_ADC3 + /************************************************************************************ * Public Function Prototypes ************************************************************************************/ diff --git a/arch/arm/src/stm32/stm32_dac.c b/arch/arm/src/stm32/stm32_dac.c index 8d152c57f7..ad767371fd 100644 --- a/arch/arm/src/stm32/stm32_dac.c +++ b/arch/arm/src/stm32/stm32_dac.c @@ -172,49 +172,49 @@ #ifdef CONFIG_STM32_DAC1_DMA # if CONFIG_STM32_DAC1_TIMER == 6 -# ifndef CONFIG_STM32_TIM6 -# error "CONFIG_STM32_TIM6 required for DAC1" +# ifndef CONFIG_STM32_TIM6_DAC +# error "CONFIG_STM32_TIM6_DAC required for DAC1" # endif # define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM6 # define DAC1_TIMER_BASE STM32_TIM6_BASE # define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC1_TIMER == 3 && defined(CONFIG_STM32_CONNECTIVITYLINE) -# ifndef CONFIG_STM32_TIM3 -# error "CONFIG_STM32_TIM3 required for DAC1" +# ifndef CONFIG_STM32_TIM3_DAC +# error "CONFIG_STM32_TIM3_DAC required for DAC1" # endif # define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM3 # define DAC1_TIMER_BASE STM32_TIM3_BASE # define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC1_TIMER == 8 && !defined(CONFIG_STM32_CONNECTIVITYLINE) -# ifndef CONFIG_STM32_TIM8 -# error "CONFIG_STM32_TIM8 required for DAC1" +# ifndef CONFIG_STM32_TIM8_DAC +# error "CONFIG_STM32_TIM8_DAC required for DAC1" # endif # define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM8 # define DAC1_TIMER_BASE STM32_TIM8_BASE # define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY # elif CONFIG_STM32_DAC1_TIMER == 7 -# ifndef CONFIG_STM32_TIM7 -# error "CONFIG_STM32_TIM7 required for DAC1" +# ifndef CONFIG_STM32_TIM7_DAC +# error "CONFIG_STM32_TIM7_DAC required for DAC1" # endif # define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM7 # define DAC1_TIMER_BASE STM32_TIM7_BASE # elif CONFIG_STM32_DAC1_TIMER == 5 -# ifndef CONFIG_STM32_TIM5 -# error "CONFIG_STM32_TIM5 required for DAC1" +# ifndef CONFIG_STM32_TIM5_DAC +# error "CONFIG_STM32_TIM5_DAC required for DAC1" # endif # define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM5 # define DAC1_TIMER_BASE STM32_TIM5_BASE # define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC1_TIMER == 2 -# ifndef CONFIG_STM32_TIM2 -# error "CONFIG_STM32_TIM2 required for DAC1" +# ifndef CONFIG_STM32_TIM2_DAC +# error "CONFIG_STM32_TIM2_DAC required for DAC1" # endif # define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM2 # define DAC1_TIMER_BASE STM32_TIM2_BASE # define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC1_TIMER == 4 -# ifndef CONFIG_STM32_TIM4 -# error "CONFIG_STM32_TIM4 required for DAC1" +# ifndef CONFIG_STM32_TIM4_DAC +# error "CONFIG_STM32_TIM4_DAC required for DAC1" # endif # define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM4 # define DAC1_TIMER_BASE STM32_TIM4_BASE @@ -228,50 +228,50 @@ #ifdef CONFIG_STM32_DAC2_DMA # if CONFIG_STM32_DAC2_TIMER == 6 -# ifndef CONFIG_STM32_TIM6 -# error "CONFIG_STM32_TIM6 required for DAC2" +# ifndef CONFIG_STM32_TIM6_DAC +# error "CONFIG_STM32_TIM6_DAC required for DAC2" # endif # define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM6 # define DAC2_TIMER_BASE STM32_TIM6_BASE # define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC2_TIMER == 3 && defined(CONFIG_STM32_CONNECTIVITYLINE) -# ifndef CONFIG_STM32_TIM3 -# error "CONFIG_STM32_TIM3 required for DAC2" +# ifndef CONFIG_STM32_TIM3_DAC +# error "CONFIG_STM32_TIM3_DAC required for DAC2" # endif # define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM3 # define DAC2_TIMER_BASE STM32_TIM3_BASE # define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC2_TIMER == 8 && !defined(CONFIG_STM32_CONNECTIVITYLINE) -# ifndef CONFIG_STM32_TIM8 -# error "CONFIG_STM32_TIM8 required for DAC2" +# ifndef CONFIG_STM32_TIM8_DAC +# error "CONFIG_STM32_TIM8_DAC required for DAC2" # endif # define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM8 # define DAC2_TIMER_BASE STM32_TIM8_BASE # define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY # elif CONFIG_STM32_DAC2_TIMER == 7 -# ifndef CONFIG_STM32_TIM7 -# error "CONFIG_STM32_TIM7 required for DAC2" +# ifndef CONFIG_STM32_TIM7_DAC +# error "CONFIG_STM32_TIM7_DAC required for DAC2" # endif # define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM7 # define DAC2_TIMER_BASE STM32_TIM7_BASE # define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC2_TIMER == 5 -# ifndef CONFIG_STM32_TIM5 -# error "CONFIG_STM32_TIM5 required for DAC2" +# ifndef CONFIG_STM32_TIM5_DAC +# error "CONFIG_STM32_TIM5_DAC required for DAC2" # endif # define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM5 # define DAC2_TIMER_BASE STM32_TIM5_BASE # define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC2_TIMER == 2 -# ifndef CONFIG_STM32_TIM2 -# error "CONFIG_STM32_TIM2 required for DAC2" +# ifndef CONFIG_STM32_TIM2_DAC +# error "CONFIG_STM32_TIM2_DAC required for DAC2" # endif # define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM2 # define DAC2_TIMER_BASE STM32_TIM2_BASE # define DAC2_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY # elif CONFIG_STM32_DAC2_TIMER == 4 -# ifndef CONFIG_STM32_TIM4 -# error "CONFIG_STM32_TIM4 required for DAC2" +# ifndef CONFIG_STM32_TIM4_DAC +# error "CONFIG_STM32_TIM4_DAC required for DAC2" # endif # define DAC2_TSEL_VALUE DAC_CR_TSEL_TIM4 # define DAC2_TIMER_BASE STM32_TIM4_BASE diff --git a/arch/arm/src/stm32/stm32_dac.h b/arch/arm/src/stm32/stm32_dac.h index 41d681ee76..44404e6fb3 100644 --- a/arch/arm/src/stm32/stm32_dac.h +++ b/arch/arm/src/stm32/stm32_dac.h @@ -47,6 +47,59 @@ #include +/************************************************************************************ + * Pre-processor definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is to + * control periodic DAC outputs. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_DAC must also be defined to indicate that timer "n" is intended + * to be used for that purpose. + */ + +#ifndef CONFIG_STM32_TIM1 +# undef CONFIG_STM32_TIM1_DAC +#endif +#ifndef CONFIG_STM32_TIM2 +# undef CONFIG_STM32_TIM2_DAC +#endif +#ifndef CONFIG_STM32_TIM3 +# undef CONFIG_STM32_TIM3_DAC +#endif +#ifndef CONFIG_STM32_TIM4 +# undef CONFIG_STM32_TIM4_DAC +#endif +#ifndef CONFIG_STM32_TIM5 +# undef CONFIG_STM32_TIM5_DAC +#endif +#ifndef CONFIG_STM32_TIM6 +# undef CONFIG_STM32_TIM6_DAC +#endif +#ifndef CONFIG_STM32_TIM7 +# undef CONFIG_STM32_TIM7_DAC +#endif +#ifndef CONFIG_STM32_TIM8 +# undef CONFIG_STM32_TIM8_DAC +#endif +#ifndef CONFIG_STM32_TIM9 +# undef CONFIG_STM32_TIM9_DAC +#endif +#ifndef CONFIG_STM32_TIM10 +# undef CONFIG_STM32_TIM10_DAC +#endif +#ifndef CONFIG_STM32_TIM11 +# undef CONFIG_STM32_TIM11_DAC +#endif +#ifndef CONFIG_STM32_TIM12 +# undef CONFIG_STM32_TIM12_DAC +#endif +#ifndef CONFIG_STM32_TIM13 +# undef CONFIG_STM32_TIM13_DAC +#endif +#ifndef CONFIG_STM32_TIM14 +# undef CONFIG_STM32_TIM14_DAC +#endif + /************************************************************************************ * Public Function Prototypes ************************************************************************************/ diff --git a/arch/arm/src/stm32/stm32_pwm.c b/arch/arm/src/stm32/stm32_pwm.c new file mode 100644 index 0000000000..8646bfcd76 --- /dev/null +++ b/arch/arm/src/stm32/stm32_pwm.c @@ -0,0 +1,459 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_pwm.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32_pwm.h" +#include "stm32_internal.h" + +/* This module then only compiles if there is at least one enabled timer + * intended for use with the PWM upper half driver. + */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM2_PWM) || \ + defined(CONFIG_STM32_TIM3_PWM) || defined(CONFIG_STM32_TIM4_PWM) || \ + defined(CONFIG_STM32_TIM5_PWM) || defined(CONFIG_STM32_TIM6_PWM) || \ + defined(CONFIG_STM32_TIM7_PWM) || defined(CONFIG_STM32_TIM8_PWM) || \ + defined(CONFIG_STM32_TIM9_PWM) || defined(CONFIG_STM32_TIM10_PWM) || \ + defined(CONFIG_STM32_TIM11_PWM) || defined(CONFIG_STM32_TIM12_PWM) || \ + defined(CONFIG_STM32_TIM13_PWM) || defined(CONFIG_STM32_TIM14_PWM) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure representst the state of one PWM timer */ + +struct stm32_pwmtimer_s +{ + uint32_t base; /* The base address of the timer */ +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev); +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev); +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, FAR const struct pwm_info_s *info); +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev); +static int pwm_pulsecount(FAR struct pwm_lowerhalf_s *dev, FAR pwm_count_t *count); +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* This is the list of lower half PWM driver methods used by the upper half driver */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = pwm_setup(FAR struct pwm_lowerhalf_s *dev); + .shutdown = pwm_shutdown(FAR struct pwm_lowerhalf_s *dev); + .start = pwm_start(FAR struct pwm_lowerhalf_s *dev, FAR const struct pwm_info_s *info); + .stop = pwm_stop(FAR struct pwm_lowerhalf_s *dev); + .pulsecount = pwm_pulsecount(FAR struct pwm_lowerhalf_s *dev, FAR pwm_count_t *count); + .ioctl = pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg); +}; + +/* The following represent the state of each possible PWM driver */ + +#ifdef CONFIG_STM32_TIM1_PWM +static struct stm32_pwmtimer_s g_pwm1dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM1_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM2_PWM +static struct stm32_pwmtimer_s g_pwm2dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM2_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM3_PWM +static struct stm32_pwmtimer_s g_pwm3dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM3_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM4_PWM +static struct stm32_pwmtimer_s g_pwm4dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM4_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM5_PWM +static struct stm32_pwmtimer_s g_pwm5dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM5_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM6_PWM +static struct stm32_pwmtimer_s g_pwm6dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM6_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM7_PWM +static struct stm32_pwmtimer_s g_pwm7dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM7_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM8_PWM +static struct stm32_pwmtimer_s g_pwm8dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM8_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM9_PWM +static struct stm32_pwmtimer_s g_pwm9dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM9_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM10_PWM +static struct stm32_pwmtimer_s g_pwm10dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM10_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM11_PWM +static struct stm32_pwmtimer_s g_pwm11dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM11_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM12_PWM +static struct stm32_pwmtimer_s g_pwm12dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM12_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM13_PWM +static struct stm32_pwmtimer_s g_pwm13dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM13_BASE; +}; +#endif + +#ifdef CONFIG_STM32_TIM14_PWM +static struct stm32_pwmtimer_s g_pwm14dev = +{ + .ops = *g_pwmops; + .base = STM32_TIM14_BASE; +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) +{ +#warning "Missing logic" + return -ENOSYS; +} + +/**************************************************************************** + * Name: pwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) +{ +#warning "Missing logic" + return -ENOSYS; +} + +/**************************************************************************** + * Name: pwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_start(FAR struct pwm_lowerhalf_s *dev, FAR const struct pwm_info_s *info) +{ +#warning "Missing logic" + return -ENOSYS; +} + +/**************************************************************************** + * Name: pwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) +{ +#warning "Missing logic" + return -ENOSYS; +} + +/**************************************************************************** + * Name: pwm_pulsecount + * + * Description: + * Get the number of pulses generated + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * count - A pointer to the location to return the pulse count + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_pulsecount(FAR struct pwm_lowerhalf_s *dev, FAR pwm_count_t *count) +{ +#warning "Missing logic" + return -ENOSYS; +} + +/**************************************************************************** + * Name: + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ + /* There are no platform-specific ioctl commands */ + + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,14}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer) +{ + FAR struct stm32_pwmtimer_s *lower; + + switch (timer) + { +#ifdef CONFIG_STM32_TIM1_PWM + case 1: + lower = &g_pwm1dev; + break; +#endif +#ifdef CONFIG_STM32_TIM2_PWM + case 2: + lower = &g_pwm2dev; + break; +#endif +#ifdef CONFIG_STM32_TIM3_PWM + case 3: + lower = &g_pwm3dev; + break; +#endif +#ifdef CONFIG_STM32_TIM4_PWM + case 4: + lower = &g_pwm4dev; + break; +#endif +#ifdef CONFIG_STM32_TIM5_PWM + case 5: + lower = &g_pwm5dev; + break; +#endif +#ifdef CONFIG_STM32_TIM6_PWM + case 6: + lower = &g_pwm6dev; + break; +#endif +#ifdef CONFIG_STM32_TIM7_PWM + case 7: + lower = &g_pwm7dev; + break; +#endif +#ifdef CONFIG_STM32_TIM8_PWM + case 8: + lower = &g_pwm8dev; + break; +#endif +#ifdef CONFIG_STM32_TIM9_PWM + case 9: + lower = &g_pwm9dev; + break; +#endif +#ifdef CONFIG_STM32_TIM10_PWM + case 10: + lower = &g_pwm10dev; + break; +#endif +#ifdef CONFIG_STM32_TIM11_PWM + case 11: + lower = &g_pwm11dev; + break; +#endif +#ifdef CONFIG_STM32_TIM12_PWM + case 12: + lower = &g_pwm12dev; + break; +#endif +#ifdef CONFIG_STM32_TIM13_PWM + case 13: + lower = &g_pwm13dev; + break; +#endif +#ifdef CONFIG_STM32_TIM14_PWM + case 14: + lower = &g_pwm14dev; + break; +#endif + default: + return NULL; + } + + return (FAR struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_STM32_TIMn_PWM, n = 1,...,14 */ diff --git a/arch/arm/src/stm32/stm32_pwm.h b/arch/arm/src/stm32/stm32_pwm.h new file mode 100644 index 0000000000..6204cda210 --- /dev/null +++ b/arch/arm/src/stm32/stm32_pwm.h @@ -0,0 +1,154 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_pwm.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_TIM_H +#define __ARCH_ARM_SRC_STM32_STM32_TIM_H + +/* The STM32 does not have dedicated PWM hardware. Rather, pulsed output control + * is a capabilitiy of the STM32 timers. The logic in this file implements the + * lower half of the standard, NuttX PWM interface using the STM32 timers. That + * interface is described in include/nuttx/pwm.h. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32_tim.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is + * to generate modulated outputs for such things as motor control. If CONFIG_STM32_TIMn + * is defined then the CONFIG_STM32_TIMn_PWM must also be defined to indicate that + * timer "n" is intended to be used for pulsed output signal generation. + */ + +#ifndef CONFIG_STM32_TIM1 +# undef CONFIG_STM32_TIM1_PWM +#endif +#ifndef CONFIG_STM32_TIM2 +# undef CONFIG_STM32_TIM2_PWM +#endif +#ifndef CONFIG_STM32_TIM3 +# undef CONFIG_STM32_TIM3_PWM +#endif +#ifndef CONFIG_STM32_TIM4 +# undef CONFIG_STM32_TIM4_PWM +#endif +#ifndef CONFIG_STM32_TIM5 +# undef CONFIG_STM32_TIM5_PWM +#endif +#ifndef CONFIG_STM32_TIM6 +# undef CONFIG_STM32_TIM6_PWM +#endif +#ifndef CONFIG_STM32_TIM7 +# undef CONFIG_STM32_TIM7_PWM +#endif +#ifndef CONFIG_STM32_TIM8 +# undef CONFIG_STM32_TIM8_PWM +#endif +#ifndef CONFIG_STM32_TIM9 +# undef CONFIG_STM32_TIM9_PWM +#endif +#ifndef CONFIG_STM32_TIM10 +# undef CONFIG_STM32_TIM10_PWM +#endif +#ifndef CONFIG_STM32_TIM11 +# undef CONFIG_STM32_TIM11_PWM +#endif +#ifndef CONFIG_STM32_TIM12 +# undef CONFIG_STM32_TIM12_PWM +#endif +#ifndef CONFIG_STM32_TIM13 +# undef CONFIG_STM32_TIM13_PWM +#endif +#ifndef CONFIG_STM32_TIM14 +# undef CONFIG_STM32_TIM14_PWM +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_pwminitialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the STM32 MCU and MCU family but is somewhere in + * the range of {1,..,14}. + * + * Returned Value: + * On success, a pointer to the STM32 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ************************************************************************************/ + +EXTERN FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_TIM_H */ diff --git a/arch/arm/src/stm32/stm32_tim.c b/arch/arm/src/stm32/stm32_tim.c index 5ce4951789..e25f02df46 100644 --- a/arch/arm/src/stm32/stm32_tim.c +++ b/arch/arm/src/stm32/stm32_tim.c @@ -4,6 +4,11 @@ * Copyright (C) 2011 Uros Platise. All rights reserved. * Author: Uros Platise * + * With modifications and updates by: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -33,10 +38,9 @@ * ************************************************************************************/ -/** \file - * \author Uros Platise - * \brief STM32 Basic, General and Advanced Timers - */ +/************************************************************************************ + * Included Files + ************************************************************************************/ #include #include @@ -59,6 +63,74 @@ #include "stm32_gpio.h" #include "stm32_tim.h" +/************************************************************************************ + * Private Types + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. Such special purposes include: + * + * - To generate modulated outputs for such things as motor control. If CONFIG_STM32_TIMn + * is defined then the CONFIG_STM32_TIMn_PWM may also be defined to indicate that + * the timer is intended to be used for pulsed output modulation. + * + * - To control periodic ADC input sampling. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_ADC may also be defined to indicate that timer "n" is intended + * to be used for that purpose. + * + * - To control periodic DAC outputs. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_DAC may also be defined to indicate that timer "n" is intended + * to be used for that purpose. + * + * In any of these cases, the timer will not be used by this timer module. + */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined (CONFIG_STM32_TIM1_ADC) || defined(CONFIG_STM32_TIM1_DAC) +# undef CONFIG_STM32_TIM1 +#endif +#if defined(CONFIG_STM32_TIM2_PWM || defined (CONFIG_STM32_TIM2_ADC) || defined(CONFIG_STM32_TIM2_DAC) +# undef CONFIG_STM32_TIM2 +#endif +#if defined(CONFIG_STM32_TIM3_PWM || defined (CONFIG_STM32_TIM3_ADC) || defined(CONFIG_STM32_TIM3_DAC) +# undef CONFIG_STM32_TIM3 +#endif +#if defined(CONFIG_STM32_TIM4_PWM || defined (CONFIG_STM32_TIM4_ADC) || defined(CONFIG_STM32_TIM4_DAC) +# undef CONFIG_STM32_TIM4 +#endif +#if defined(CONFIG_STM32_TIM5_PWM || defined (CONFIG_STM32_TIM5_ADC) || defined(CONFIG_STM32_TIM5_DAC) +# undef CONFIG_STM32_TIM5 +#endif +#if defined(CONFIG_STM32_TIM6_PWM || defined (CONFIG_STM32_TIM6_ADC) || defined(CONFIG_STM32_TIM6_DAC) +# undef CONFIG_STM32_TIM6 +#endif +#if defined(CONFIG_STM32_TIM7_PWM || defined (CONFIG_STM32_TIM7_ADC) || defined(CONFIG_STM32_TIM7_DAC) +# undef CONFIG_STM32_TIM7 +#endif +#if defined(CONFIG_STM32_TIM8_PWM || defined (CONFIG_STM32_TIM8_ADC) || defined(CONFIG_STM32_TIM8_DAC) +# undef CONFIG_STM32_TIM8 +#endif +#if defined(CONFIG_STM32_TIM9_PWM || defined (CONFIG_STM32_TIM9_ADC) || defined(CONFIG_STM32_TIM9_DAC) +# undef CONFIG_STM32_TIM9 +#endif +#if defined(CONFIG_STM32_TIM10_PWM || defined (CONFIG_STM32_TIM10_ADC) || defined(CONFIG_STM32_TIM10_DAC) +# undef CONFIG_STM32_TIM10 +#endif +#if defined(CONFIG_STM32_TIM11_PWM || defined (CONFIG_STM32_TIM11_ADC) || defined(CONFIG_STM32_TIM11_DAC) +# undef CONFIG_STM32_TIM11 +#endif +#if defined(CONFIG_STM32_TIM12_PWM || defined (CONFIG_STM32_TIM12_ADC) || defined(CONFIG_STM32_TIM12_DAC) +# undef CONFIG_STM32_TIM12 +#endif +#if defined(CONFIG_STM32_TIM13_PWM || defined (CONFIG_STM32_TIM13_ADC) || defined(CONFIG_STM32_TIM13_DAC) +# undef CONFIG_STM32_TIM13 +#endif +#if defined(CONFIG_STM32_TIM14_PWM || defined (CONFIG_STM32_TIM14_ADC) || defined(CONFIG_STM32_TIM14_DAC) +# undef CONFIG_STM32_TIM14 +#endif + +/* This module then only compiles if there are enabled timers that are not intended for + * some other purpose. + */ + #if defined(CONFIG_STM32_TIM1) || defined(CONFIG_STM32_TIM2) || defined(CONFIG_STM32_TIM3) || \ defined(CONFIG_STM32_TIM4) || defined(CONFIG_STM32_TIM5) || defined(CONFIG_STM32_TIM6) || \ defined(CONFIG_STM32_TIM7) || defined(CONFIG_STM32_TIM8) diff --git a/arch/arm/src/stm32/stm32_tim.h b/arch/arm/src/stm32/stm32_tim.h index 1aa18328e2..8f12b18756 100644 --- a/arch/arm/src/stm32/stm32_tim.h +++ b/arch/arm/src/stm32/stm32_tim.h @@ -4,6 +4,11 @@ * Copyright (C) 2011 Uros Platise. All rights reserved. * Author: Uros Platise * + * With modifications and updates by: + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -33,14 +38,13 @@ * ************************************************************************************/ -/** \file - * \author Uros Platise - * \brief STM32 Timer Device Driver - */ - #ifndef __ARCH_ARM_SRC_STM32_STM32_TIM_H #define __ARCH_ARM_SRC_STM32_STM32_TIM_H +/************************************************************************************ + * Included Files + ************************************************************************************/ + #include #include "chip.h" @@ -49,107 +53,7 @@ /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ - -#ifndef __ASSEMBLY__ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" { -#else -#define EXTERN extern -#endif - -/************************************************************************************ - * Public Types - ************************************************************************************/ - -/** TIM Device Structure - */ -struct stm32_tim_dev_s { - struct stm32_tim_ops_s *ops; -}; - - -/** TIM Modes of Operation - */ -typedef enum { - STM32_TIM_MODE_UNUSED = -1, - - /* One of the following */ - STM32_TIM_MODE_MASK = 0x0310, - STM32_TIM_MODE_DISABLED = 0x0000, - STM32_TIM_MODE_UP = 0x0100, - STM32_TIM_MODE_DOWN = 0x0110, - STM32_TIM_MODE_UPDOWN = 0x0200, - STM32_TIM_MODE_PULSE = 0x0300, - - /* One of the following */ - STM32_TIM_MODE_CK_INT = 0x0000, -// STM32_TIM_MODE_CK_INT_TRIG = 0x0400, -// STM32_TIM_MODE_CK_EXT = 0x0800, -// STM32_TIM_MODE_CK_EXT_TRIG = 0x0C00, - - /* Clock sources, OR'ed with CK_EXT */ -// STM32_TIM_MODE_CK_CHINVALID = 0x0000, -// STM32_TIM_MODE_CK_CH1 = 0x0001, -// STM32_TIM_MODE_CK_CH2 = 0x0002, -// STM32_TIM_MODE_CK_CH3 = 0x0003, -// STM32_TIM_MODE_CK_CH4 = 0x0004 - - /* Todo: external trigger block */ - -} stm32_tim_mode_t; - - -/** TIM Channel Modes - */ -typedef enum { - STM32_TIM_CH_DISABLED = 0x00, - - /* Common configuration */ - STM32_TIM_CH_POLARITY_POS = 0x00, - STM32_TIM_CH_POLARITY_NEG = 0x01, - - /* MODES: */ - STM32_TIM_CH_MODE_MASK = 0x06, - - /* Output Compare Modes */ - STM32_TIM_CH_OUTPWM = 0x04, /** Enable standard PWM mode, active high when counter < compare */ -// STM32_TIM_CH_OUTCOMPARE = 0x06, - - // TODO other modes ... as PWM capture, ENCODER and Hall Sensor -// STM32_TIM_CH_INCAPTURE = 0x10, -// STM32_TIM_CH_INPWM = 0x20 -// STM32_TIM_CH_DRIVE_OC -- open collector mode - -} stm32_tim_channel_t; - - -/** TIM Operations - */ -struct stm32_tim_ops_s { - - /* Basic Timers */ - - int (*setmode)(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode); - int (*setclock)(FAR struct stm32_tim_dev_s *dev, uint32_t freq); - void (*setperiod)(FAR struct stm32_tim_dev_s *dev, uint16_t period); - - /* General and Advanced Timers Adds */ - - int (*setchannel)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, stm32_tim_channel_t mode); - int (*setcompare)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, uint16_t compare); - int (*getcapture)(FAR struct stm32_tim_dev_s *dev, uint8_t channel); - - int (*setisr)(FAR struct stm32_tim_dev_s *dev, int (*handler)(int irq, void *context), int source); - void (*enableint)(FAR struct stm32_tim_dev_s *dev, int source); - void (*disableint)(FAR struct stm32_tim_dev_s *dev, int source); - void (*ackint)(FAR struct stm32_tim_dev_s *dev, int source); -}; - - -/* Helpers */ +/* Helpers **************************************************************************/ #define STM32_TIM_SETMODE(d,mode) ((d)->ops->setmode(d,mode)) #define STM32_TIM_SETCLOCK(d,freq) ((d)->ops->setclock(d,freq)) @@ -162,17 +66,121 @@ struct stm32_tim_ops_s { #define STM32_TIM_DISABLEINT(d,s) ((d)->ops->disableint(d,s)) #define STM32_TIM_ACKINT(d,s) ((d)->ops->ackint(d,s)) +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/* TIM Device Structure */ + +struct stm32_tim_dev_s +{ + struct stm32_tim_ops_s *ops; +}; + +/* TIM Modes of Operation */ + +typedef enum +{ + STM32_TIM_MODE_UNUSED = -1, + + /* One of the following */ + + STM32_TIM_MODE_MASK = 0x0310, + STM32_TIM_MODE_DISABLED = 0x0000, + STM32_TIM_MODE_UP = 0x0100, + STM32_TIM_MODE_DOWN = 0x0110, + STM32_TIM_MODE_UPDOWN = 0x0200, + STM32_TIM_MODE_PULSE = 0x0300, + + /* One of the following */ + + STM32_TIM_MODE_CK_INT = 0x0000, +//STM32_TIM_MODE_CK_INT_TRIG = 0x0400, +//STM32_TIM_MODE_CK_EXT = 0x0800, +//STM32_TIM_MODE_CK_EXT_TRIG = 0x0C00, + + /* Clock sources, OR'ed with CK_EXT */ + +//STM32_TIM_MODE_CK_CHINVALID = 0x0000, +//STM32_TIM_MODE_CK_CH1 = 0x0001, +//STM32_TIM_MODE_CK_CH2 = 0x0002, +//STM32_TIM_MODE_CK_CH3 = 0x0003, +//STM32_TIM_MODE_CK_CH4 = 0x0004 + + /* Todo: external trigger block */ + +} stm32_tim_mode_t; + +/* TIM Channel Modes */ + +typedef enum +{ + STM32_TIM_CH_DISABLED = 0x00, + + /* Common configuration */ + + STM32_TIM_CH_POLARITY_POS = 0x00, + STM32_TIM_CH_POLARITY_NEG = 0x01, + + /* MODES: */ + + STM32_TIM_CH_MODE_MASK = 0x06, + + /* Output Compare Modes */ + + STM32_TIM_CH_OUTPWM = 0x04, /** Enable standard PWM mode, active high when counter < compare */ +//STM32_TIM_CH_OUTCOMPARE = 0x06, + + // TODO other modes ... as PWM capture, ENCODER and Hall Sensor +//STM32_TIM_CH_INCAPTURE = 0x10, +//STM32_TIM_CH_INPWM = 0x20 +//STM32_TIM_CH_DRIVE_OC -- open collector mode + +} stm32_tim_channel_t; + +/* TIM Operations */ + +struct stm32_tim_ops_s +{ + /* Basic Timers */ + + int (*setmode)(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode); + int (*setclock)(FAR struct stm32_tim_dev_s *dev, uint32_t freq); + void (*setperiod)(FAR struct stm32_tim_dev_s *dev, uint16_t period); + + /* General and Advanced Timers Adds */ + + int (*setchannel)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, stm32_tim_channel_t mode); + int (*setcompare)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, uint16_t compare); + int (*getcapture)(FAR struct stm32_tim_dev_s *dev, uint8_t channel); + + int (*setisr)(FAR struct stm32_tim_dev_s *dev, int (*handler)(int irq, void *context), int source); + void (*enableint)(FAR struct stm32_tim_dev_s *dev, int source); + void (*disableint)(FAR struct stm32_tim_dev_s *dev, int source); + void (*ackint)(FAR struct stm32_tim_dev_s *dev, int source); +}; /************************************************************************************ * Public Functions ************************************************************************************/ -/** Power-up timer and get its structure */ +/* Power-up timer and get its structure */ + EXTERN FAR struct stm32_tim_dev_s * stm32_tim_init(int timer); -/** Power-down timer, mark it as unused */ -EXTERN int stm32_tim_deinit(FAR struct stm32_tim_dev_s * dev); +/* Power-down timer, mark it as unused */ +EXTERN int stm32_tim_deinit(FAR struct stm32_tim_dev_s * dev); #undef EXTERN #if defined(__cplusplus)