STM32 ADC driver fixes

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5247 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-10-21 16:53:38 +00:00
parent a630e4a117
commit 1ce3801086
5 changed files with 33 additions and 6 deletions

View File

@ -3496,3 +3496,8 @@
optimized for size. optimized for size.
* lib/strings/lib_memset.c: CONFIG_MEMSET_64BIT will perform 64-bit * lib/strings/lib_memset.c: CONFIG_MEMSET_64BIT will perform 64-bit
aligned memset() operations. aligned memset() operations.
* arch/arm/src/stm32/stm32_adc.c: Need to put the ADC back into the
initial reset in the open/setup logic. Opening the ADC driver works
the first time, but not the second because the device is left in a
powered down state on the last close.

View File

@ -694,10 +694,10 @@ static int adc_timinit(FAR struct stm32_dev_s *priv)
case 4: /* TimerX TRGO event */ case 4: /* TimerX TRGO event */
{ {
#warning "TRGO support not yet implemented" /* TODO: TRGO support not yet implemented */
/* Set the event TRGO */ /* Set the event TRGO */
ccenable = 0;
egr = GTIM_EGR_TG; egr = GTIM_EGR_TG;
/* Set the duty cycle by writing to the CCR register for this channel */ /* Set the duty cycle by writing to the CCR register for this channel */
@ -971,7 +971,7 @@ static void adc_reset(FAR struct adc_dev_s *dev)
avdbg("intf: ADC%d\n", priv->intf); avdbg("intf: ADC%d\n", priv->intf);
flags = irqsave(); flags = irqsave();
/* Enable ADC reset state */ /* Enable ADC reset state */
adc_rccreset(priv, true); adc_rccreset(priv, true);
@ -1164,6 +1164,10 @@ static int adc_setup(FAR struct adc_dev_s *dev)
ret = irq_attach(priv->irq, priv->isr); ret = irq_attach(priv->irq, priv->isr);
if (ret == OK) if (ret == OK)
{ {
/* Make sure that the ADC device is in the powered up, reset state */
adc_reset(dev);
/* Enable the ADC interrupt */ /* Enable the ADC interrupt */
avdbg("Enable the ADC interrupt: irq=%d\n", priv->irq); avdbg("Enable the ADC interrupt: irq=%d\n", priv->irq);

View File

@ -287,7 +287,7 @@
#if defined(ADC1_HAVE_TIMER) || defined(ADC2_HAVE_TIMER) || defined(ADC3_HAVE_TIMER) #if defined(ADC1_HAVE_TIMER) || defined(ADC2_HAVE_TIMER) || defined(ADC3_HAVE_TIMER)
# define ADC_HAVE_TIMER 1 # define ADC_HAVE_TIMER 1
# if defined(CONFIG_STM32_STM32F10XX) && defined(CONFIG_STM32_FORCEPOWER) # if defined(CONFIG_STM32_STM32F10XX) && !defined(CONFIG_STM32_FORCEPOWER)
# warning "CONFIG_STM32_FORCEPOWER must be defined to enable the timer(s)" # warning "CONFIG_STM32_FORCEPOWER must be defined to enable the timer(s)"
# endif # endif
#else #else

View File

@ -593,6 +593,12 @@ Shenzhou-specific Configuration Options
CONFIG_STM32_ADC1 CONFIG_STM32_ADC1
CONFIG_STM32_ADC2 CONFIG_STM32_ADC2
Timer and I2C devices may need to the following to force power to be applied
unconditionally at power up. (Otherwise, the device is powered when it is
initialized).
CONFIG_STM32_FORCEPOWER
Timer devices may be used for different purposes. One special purpose is 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 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 is defined (as above) then the following may also be defined to indicate that
@ -798,6 +804,7 @@ Where <subdir> is one of the following:
CONFIG_STM32_TIM1_ADC1=y : Allocate Timer 1 to ADC 1 CONFIG_STM32_TIM1_ADC1=y : Allocate Timer 1 to ADC 1
CONFIG_STM32_ADC1_SAMPLE_FREQUENCY=100 : Set sampling frequency to 100Hz CONFIG_STM32_ADC1_SAMPLE_FREQUENCY=100 : Set sampling frequency to 100Hz
CONFIG_STM32_ADC1_TIMTRIG=0 : Trigger on timer output 0 CONFIG_STM32_ADC1_TIMTRIG=0 : Trigger on timer output 0
CONFIG_STM32_FORCEPOWER=y : Apply power to TIM1 a boot up time
CONFIG_EXAMPLES_ADC=y : Enable the apps/examples/adc built-in CONFIG_EXAMPLES_ADC=y : Enable the apps/examples/adc built-in
nxwm nxwm

View File

@ -143,7 +143,7 @@ static int adc_open(FAR struct file *filep)
dev->ad_recv.af_head = 0; dev->ad_recv.af_head = 0;
dev->ad_recv.af_tail = 0; dev->ad_recv.af_tail = 0;
/* Finally, Enable the CAN RX interrupt */ /* Finally, Enable the ADC RX interrupt */
dev->ad_ops->ao_rxint(dev, true); dev->ad_ops->ao_rxint(dev, true);
@ -151,9 +151,11 @@ static int adc_open(FAR struct file *filep)
dev->ad_ocount = tmp; dev->ad_ocount = tmp;
} }
irqrestore(flags); irqrestore(flags);
} }
} }
sem_post(&dev->ad_closesem); sem_post(&dev->ad_closesem);
} }
return ret; return ret;
@ -370,6 +372,10 @@ static int adc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Name: adc_receive
****************************************************************************/
int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data) int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
{ {
FAR struct adc_fifo_s *fifo = &dev->ad_recv; FAR struct adc_fifo_s *fifo = &dev->ad_recv;
@ -390,7 +396,7 @@ int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
if (nexttail != fifo->af_head) if (nexttail != fifo->af_head)
{ {
/* Add the new, decoded CAN message at the tail of the FIFO */ /* Add the new, decoded ADC sample at the tail of the FIFO */
fifo->af_buffer[fifo->af_tail].am_channel = ch; fifo->af_buffer[fifo->af_tail].am_channel = ch;
fifo->af_buffer[fifo->af_tail].am_data = data; fifo->af_buffer[fifo->af_tail].am_data = data;
@ -403,11 +409,16 @@ int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
{ {
sem_post(&fifo->af_sem); sem_post(&fifo->af_sem);
} }
err = OK; err = OK;
} }
return err; return err;
} }
/****************************************************************************
* Name: adc_register
****************************************************************************/
int adc_register(FAR const char *path, FAR struct adc_dev_s *dev) int adc_register(FAR const char *path, FAR struct adc_dev_s *dev)
{ {
/* Initialize the ADC device structure */ /* Initialize the ADC device structure */