9
0
Fork 0

Add framework for lower half STM32 PWM driver; updates to the STM32 ADC driver

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4192 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2011-12-16 19:29:41 +00:00
parent 6a721988fb
commit 51b91c96af
12 changed files with 1655 additions and 181 deletions

View File

@ -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

View File

@ -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 */

View File

@ -47,6 +47,104 @@
#include <nuttx/analog/adc.h>
/************************************************************************************
* 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
************************************************************************************/

View File

@ -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

View File

@ -47,6 +47,59 @@
#include <nuttx/analog/dac.h>
/************************************************************************************
* 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
************************************************************************************/

View File

@ -0,0 +1,459 @@
/****************************************************************************
* arch/arm/src/stm32/stm32_pwm.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* 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 <nuttx/config.h>
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/pwm.h>
#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 */

View File

@ -0,0 +1,154 @@
/************************************************************************************
* arch/arm/src/stm32/stm32_pwm.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#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 */

View File

@ -4,6 +4,11 @@
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
* With modifications and updates by:
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <nuttx/arch.h>
@ -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)

View File

@ -4,6 +4,11 @@
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
* With modifications and updates by:
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#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)

View File

@ -481,7 +481,40 @@ STM3210E-EVAL-specific Configuration Options
CONFIG_STM32_FORCEPOWER
Alternate pin mappings (should not be used with the STM3210E-EVAL board):
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 (as above) then the following may also be defined to indicate that
the timer is intended to be used for pulsed output modulation, ADC conversion,
or DAC conversion.
CONFIG_STM32_TIM1_PWM
CONFIG_STM32_TIM2_PWM
CONFIG_STM32_TIM3_PWM
CONFIG_STM32_TIM4_PWM
CONFIG_STM32_TIM5_PWM
CONFIG_STM32_TIM6_PWM
CONFIG_STM32_TIM7_PWM
CONFIG_STM32_TIM8_PWM
CONFIG_STM32_TIM1_ADC
CONFIG_STM32_TIM2_ADC
CONFIG_STM32_TIM3_ADC
CONFIG_STM32_TIM4_ADC
CONFIG_STM32_TIM5_ADC
CONFIG_STM32_TIM6_ADC
CONFIG_STM32_TIM7_ADC
CONFIG_STM32_TIM8_ADC
CONFIG_STM32_TIM1_DAC
CONFIG_STM32_TIM2_DAC
CONFIG_STM32_TIM3_DAC
CONFIG_STM32_TIM4_DAC
CONFIG_STM32_TIM5_DAC
CONFIG_STM32_TIM6_DAC
CONFIG_STM32_TIM7_DAC
CONFIG_STM32_TIM8_DAC
Alternate pin mappings (should not be used with the STM3210E-EVAL board):
CONFIG_STM32_TIM1_FULL_REMAP
CONFIG_STM32_TIM1_PARTIAL_REMAP

View File

@ -360,7 +360,47 @@ STM3240G-EVAL-specific Configuration Options
CONFIG_STM32_FORCEPOWER
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 (as above) then the following may also be defined to indicate that
the timer is intended to be used for pulsed output modulation, ADC conversion,
or DAC conversion.
CONFIG_STM32_TIM1_PWM
CONFIG_STM32_TIM2_PWM
CONFIG_STM32_TIM3_PWM
CONFIG_STM32_TIM4_PWM
CONFIG_STM32_TIM5_PWM
CONFIG_STM32_TIM6_PWM
CONFIG_STM32_TIM7_PWM
CONFIG_STM32_TIM8_PWM
CONFIG_STM32_TIM9_PWM
CONFIG_STM32_TIM10_PWM
CONFIG_STM32_TIM11_PWM
CONFIG_STM32_TIM12_PWM
CONFIG_STM32_TIM13_PWM
CONFIG_STM32_TIM14_PWM
CONFIG_STM32_TIM1_ADC
CONFIG_STM32_TIM2_ADC
CONFIG_STM32_TIM3_ADC
CONFIG_STM32_TIM4_ADC
CONFIG_STM32_TIM5_ADC
CONFIG_STM32_TIM6_ADC
CONFIG_STM32_TIM7_ADC
CONFIG_STM32_TIM8_ADC
CONFIG_STM32_TIM1_DAC
CONFIG_STM32_TIM2_DAC
CONFIG_STM32_TIM3_DAC
CONFIG_STM32_TIM4_DAC
CONFIG_STM32_TIM5_DAC
CONFIG_STM32_TIM6_DAC
CONFIG_STM32_TIM7_DAC
CONFIG_STM32_TIM8_DAC
JTAG Enable settings (by default JTAG-DP and SW-DP are disabled):
CONFIG_STM32_JTAG_FULL_ENABLE - Enables full SWJ (JTAG-DP + SW-DP)
CONFIG_STM32_JTAG_NOJNTRST_ENABLE - Enables full SWJ (JTAG-DP + SW-DP)
but without JNTRST.

253
nuttx/include/nuttx/pwm.h Normal file
View File

@ -0,0 +1,253 @@
/****************************************************************************
* include/nuttx/pwm.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 __INCLUDE_NUTTX_PWM_H
#define __INCLUDE_NUTTX_PWM_H
/* For the purposes of this driver, a PWM device is any devices and generates
* periodic outputs of controlled frequency and pulse width. Such is device
* might be use, for example, to perform pulse-width modulated output or
* frequency/pulse-count modulated output (such as might be needed to control
* a stepper motor.
*
* The PWM driver is split into two parts:
*
* 1) An "upper half", generic driver that provides the comman PWM interface
* to application level code, and
* 2) An "lower half" platform-specific driver that implements the low-level
* timer controls to implement the PWM functionality.
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <fixedmath.h>
#include <nuttx/ioctl.h>
#ifdef CONFIG_PWM
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/* The PWM module uses a standard character driver framework. However, since
* the PWM driver is a devices control interface and not a data transfer
* interface, the majority of the functionality is implemented in driver
* ioctl calls. The PWM ioctal commands are lised below:
*
* PWMIOC_SETCHARACTERISTICS - Set the characteristics of the next pulsed
* output. This command will neither start nor stop the pulsed output.
* It will either setup the configuration that will be used when the
* output is started; or it will change the characteristics of the pulsed
* output on the fly if the timer is already started.
*
* ioctl argument: A read-only reference to struct pwm_info_s that provides
* the characteristics of the pulsed output.
*
* PWMIOC_GETCHARACTERISTICS - Get the currently selected characteristics of
* the pulsed output (independent of whether the output is start or stopped).
*
* ioctl argument: A reference to struct pwm_info_s to recevie the
* characteristics of the pulsed output.
*
* PWMIOC_START - Start the pulsed output. The PWMIOC_SETCHARACTERISTICS
* command must have previously been sent.
*
* ioctl argument: None
*
* PWMIOC_STOP - Stop the pulsed output.
*
* ioctl argument: None
*
* PWMIOC_GETPULSECOUNT - Return the number of pulses generated.
*
* ioctl argument: A pointer to a pwm_count_t variable that will be used to
* receive the pulse count
*/
#define PWMIOC_SETCHARACTERISTICS _PWMIOC(1)
#define PWMIOC_GETCHARACTERISTICS _PWMIOC(2)
#define PWMIOC_START _PWMIOC(3)
#define PWMIOC_STOP _PWMIOC(4)
#define PWMIOC_GETPULSECOUNT _PWMIOC(5)
/****************************************************************************
* Public Types
****************************************************************************/
/* This structure describes the characteristics of the pulsed output */
struct pwm_info_s
{
uint32_t frequency; /* Frequency of the pulse train */
b16_t duty; /* Duty of the pulse train, "1" to "0" duration */
};
/* This type is used to return pulse counts */
#ifdef CONFIG_HAVE_LONG_LONG
typedef uint16_t pwm_count_t;
#else
struct pwm_count_s
{
uint32_t ms; /* Most significant 32-bits of the 64-count */
uint32_t ls; /* Least significant 32-bits of the 64-count */
};
typedef struct pwm_count_s pwm_count_t;
#endif
/* This structure is a set a callback functions used to call from the upper-
* half, generic PWM driver into lower-half, platform-specific logic that
* supports the low-level timer outputs.
*/
struct pwm_lowerhalf_s;
struct pwm_ops_s
{
/* 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.
*/
CODE int (*setup)(FAR struct pwm_lowerhalf_s *dev);
/* 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
*/
CODE int (*shutdown)(FAR struct pwm_lowerhalf_s *dev);
/* (Re-)initialize the timer resources and start the pulsed output */
CODE int (*start)(FAR struct pwm_lowerhalf_s *dev, FAR const struct pwm_info_s *info);
/* Stop the pulsed output and reset the timer resources*/
CODE int (*stop)(FAR struct pwm_lowerhalf_s *dev);
/* Get the number of pulses generated */
CODE int (*pulsecount)(FAR struct pwm_lowerhalf_s *dev, FAR pwm_count_t *count);
/* Lower-half logic may support platform-specific ioctl commands */
CODE int (*ioctl)(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg);
};
/* This structure is the generic form of state structure used by lower half
* timer driver. This state structure is passed to the pwm driver when the
* driver is initialized. Then, on subsequent callbacks into the lower half
* timer logic, this structure is provided so that the timer logic can
* maintain state information.
*
* Normally that timer logic will have its own, custom state structure
* that is simply cast to struct pwm_lowerhalf_s. In order to perform such casts,
* the initial fields of the custom state structure match the initial fields
* of the following generic PWM state structure.
*/
struct pwm_lowerhalf_s
{
/* The first field of this state structure must be a pointer to the PWM
* callback structure:
*/
FAR const struct pwm_ops_s *ops;
/* The custom timer state structure may include additional fields after
* the pointer to the PWM callback structgure.
*/
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
/****************************************************************************
* "Upper-Half" ADC Driver Interfaces
****************************************************************************/
/****************************************************************************
* Name: pwm_register
*
* Description:
* This function binds an instance of a "lower half" timer driver with the
* "upper half" PWM device and registers that device so that can be used
* by application code.
*
* When this function is called, the "lower half" driver should be in the
* reset state (as if the shutdown() method had already been called).
*
* Input parameters:
* path - The full path to the driver to be registers in the NuttX pseudo-
* filesystem. The recommended convention is to name all PWM drivers
* as "/dev/pwm0", "/dev/pwm1", etc. where the driver path differs only
* in the "minor" number at the end of the device name.
* dev - A pointer to an instance of lower half timer driver. This instance
* is bound to the PWM driver and must persists as long as the driver
* persists.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
int pwm_register(FAR const char *path, FAR struct pwm_lowerhalf_s *dev);
/****************************************************************************
* Platform-Independent "Lower-Half" ADC Driver Interfaces
****************************************************************************/
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_PWM */
#endif /* __INCLUDE_NUTTX_PWM_H */