summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-07-30 08:54:32 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-07-30 08:54:32 -0600
commit019941a2df4f928a79ed476e3a166d77230233dc (patch)
treeb25834fff51127384b5b7992fa2d0858e45eed49
parentcba8961476cc94e0e08484890517030976e3ac14 (diff)
downloadnuttx-019941a2df4f928a79ed476e3a166d77230233dc.tar.gz
nuttx-019941a2df4f928a79ed476e3a166d77230233dc.tar.bz2
nuttx-019941a2df4f928a79ed476e3a166d77230233dc.zip
STM32 DAC DMA fixes from John Wharington
-rw-r--r--nuttx/ChangeLog3
-rw-r--r--nuttx/arch/arm/src/stm32/Kconfig59
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_dac.h2
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h2
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h9
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_dac.c321
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c10
7 files changed, 362 insertions, 44 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index db65c4a15..c165364a1 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5229,4 +5229,7 @@
(2013-7-29).
* arch/arm/src/armv7-a/arm_cache.S: Separate the bigger cache
operations into separater files (2013-7-29).
+ * arch/arm/src/stm32/stm32_dac.c: Fixed numerous DAC driver
+ errors and added support for DAC DMA (contributed by John
+ Wharington, 2013-7-30).
diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig
index 7249b382f..094d86488 100644
--- a/nuttx/arch/arm/src/stm32/Kconfig
+++ b/nuttx/arch/arm/src/stm32/Kconfig
@@ -675,7 +675,7 @@ config STM32_SPI1
config STM32_SPI2
bool "SPI2"
default n
- depends on STM32_CONNECTIVITYLINE || STM32_STM32F20XX || STM32_STM32F40XX || (STM32_VALUELINE && STM32_HIGHDENSITY) || (STM32_STM32F10XX && (STM32_HIGHDENSITY || STM32_MEDIUMDENSITY))
+ depends on STM32_CONNECTIVITYLINE || STM32_STM32F20XX || STM32_STM32F40XX || (STM32_VALUELINE && STM32_HIGHDENSITY) || (STM32_STM32F10XX && (STM32_HIGHDENSITY || STM32_MEDIUMDENSITY)) || STM32_STM32F30XX
select SPI
select STM32_SPI
@@ -1121,7 +1121,7 @@ config ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG
config STM32_CCMEXCLUDE
bool "Exclude CCM SRAM from the heap"
- depends on STM32_STM32F20XX || STM32_STM32F40XX
+ depends on STM32_STM32F20XX || STM32_STM32F40XX || STM32_STM32F30XX
default y if ARCH_DMA || ELF
---help---
Exclude CCM SRAM from the HEAP because (1) it cannot be used for DMA
@@ -2202,6 +2202,61 @@ config STM32_TIM14_DAC2
endchoice
+menu "DAC Configuration"
+ depends on STM32_DAC1 || STM32_DAC2
+
+config STM32_DAC1_DMA
+ bool "DAC1 DMA"
+ depends on STM32_DAC1
+ default n
+ ---help---
+ If DMA is selected, then a timer and output frequency must also be
+ provided to support the DMA transfer. The DMA transfer could be
+ supported by and EXTI trigger, but this feature is not currently
+ supported by the driver.
+
+if STM32_DAC1_DMA
+
+config STM32_DAC1_TIMER
+ int "DAC1 timer"
+ range 2 7
+
+config STM32_DAC1_TIMER_FREQUENCY
+ int "DAC1 timer frequency"
+ default 0
+ range 0 14
+
+endif
+
+config STM32_DAC2_DMA
+ bool "DAC2 DMA"
+ depends on STM32_DAC2
+ default n
+ ---help---
+ If DMA is selected, then a timer and output frequency must also be
+ provided to support the DMA transfer. The DMA transfer could be
+ supported by and EXTI trigger, but this feature is not currently
+ supported by the driver.
+
+if STM32_DAC2_DMA
+
+config STM32_DAC2_TIMER
+ int "DAC2 timer"
+ default 0
+ range 2 7
+
+config STM32_DAC2_TIMER_FREQUENCY
+ int "DAC2 timer frequency"
+ default 0
+
+endif
+
+config STM32_DAC_DMA_BUFFER_SIZE
+ int "DAC DMA buffer size"
+ default 256
+
+endmenu
+
config STM32_USART
bool
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_dac.h b/nuttx/arch/arm/src/stm32/chip/stm32_dac.h
index 7b6069b8b..28c606d45 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32_dac.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_dac.h
@@ -103,7 +103,7 @@
# define DAC_CR_TSEL_TIM4 (5 << DAC_CR_TSEL_SHIFT) /* Timer 4 TRGO event */
# define DAC_CR_TSEL_EXT9 (6 << DAC_CR_TSEL_SHIFT) /* External line9 */
# define DAC_CR_TSEL_SW (7 << DAC_CR_TSEL_SHIFT) /* Software trigger */
-#define DAC_CR_WAVE_SHIFT (6) /* Bits 6-7: DAC channel noise/triangle wave generation */enable
+#define DAC_CR_WAVE_SHIFT (6) /* Bits 6-7: DAC channel noise/triangle wave generation */
#define DAC_CR_WAVE_MASK (3 << DAC_CR_WAVE_SHIFT)
# define DAC_CR_WAVE_DISABLED (0 << DAC_CR_WAVE_SHIFT) /* Wave generation disabled */
# define DAC_CR_WAVE_NOISE (1 << DAC_CR_WAVE_SHIFT) /* Noise wave generation enabled */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h
index 1b7740faf..cb6d89a6f 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f10xxx_dma.h
@@ -291,7 +291,7 @@
#define STM32_DMA2_CHAN1 (7)
#define STM32_DMA2_CHAN2 (8)
-#define STM32_DMA2_CHAN3 (1)
+#define STM32_DMA2_CHAN3 (9)
#define STM32_DMA2_CHAN4 (10)
#define STM32_DMA2_CHAN5 (11)
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h b/nuttx/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h
index 38216843e..24ab01d1f 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f30xxx_pinmap.h
@@ -97,6 +97,15 @@
#define GPIO_COMP6_OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN10)
#define GPIO_COMP7_OUT (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN2)
+/* DAC -" Once the DAC channelx is enabled, the corresponding GPIO pin
+ * (PA4 or PA5) is automatically connected to the analog converter output
+ * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin
+ * should first be configured to analog (AIN)".
+ */
+
+#define GPIO_DAC1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4)
+#define GPIO_DAC2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5)
+
/* I2C */
#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN15)
diff --git a/nuttx/arch/arm/src/stm32/stm32_dac.c b/nuttx/arch/arm/src/stm32/stm32_dac.c
index 916ce331b..d3cef440c 100644
--- a/nuttx/arch/arm/src/stm32/stm32_dac.c
+++ b/nuttx/arch/arm/src/stm32/stm32_dac.c
@@ -1,7 +1,7 @@
/************************************************************************************
* arch/arm/src/stm32/stm32_dac.c
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,7 @@
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
+#include <math.h>
#include <semaphore.h>
#include <errno.h>
#include <debug.h>
@@ -57,6 +58,8 @@
#include "chip.h"
#include "stm32.h"
#include "stm32_dac.h"
+#include "stm32_rcc.h"
+#include "stm32_dma.h"
#ifdef CONFIG_DAC
@@ -85,9 +88,9 @@
/* DMA configuration. */
#if defined(CONFIG_STM32_DAC1_DMA) || defined(CONFIG_STM32_DAC2_DMA)
-# if defined(CONFIG_STM32_STM32F10XX)
+# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX)
# ifndef CONFIG_STM32_DMA2
-# warning "STM32 F1 DAC DMA support requires CONFIG_STM32_DMA2"
+# warning "STM32 F1/F3 DAC DMA support requires CONFIG_STM32_DMA2"
# undef CONFIG_STM32_DAC1_DMA
# undef CONFIG_STM32_DAC2_DMA
# endif
@@ -139,7 +142,7 @@
#undef HAVE_DMA
#if defined(CONFIG_STM32_DAC1_DMA) || defined(CONFIG_STM32_DAC2_DMA)
-# if defined(CONFIG_STM32_STM32F10XX)
+# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX)
# define HAVE_DMA 1
# define DAC_DMA 2
# define DAC1_DMA_CHAN DMACHAN_DAC_CHAN1
@@ -149,7 +152,7 @@
# define DAC_DMA 1
# define DAC1_DMA_CHAN DMAMAP_DAC1
# define DAC2_DMA_CHAN DMAMAP_DAC2
-# endif
+# endif
#endif
/* Timer configuration. The STM32 supports 8 different trigger for DAC
@@ -170,11 +173,20 @@
* This driver does not support the EXTI trigger.
*/
+#undef NEED_TIM6
+#undef NEED_TIM3
+#undef NEED_TIM8
+#undef NEED_TIM7
+#undef NEED_TIM5
+#undef NEED_TIM2
+#undef NEED_TIM4
+
#ifdef CONFIG_STM32_DAC1_DMA
# if CONFIG_STM32_DAC1_TIMER == 6
# ifndef CONFIG_STM32_TIM6_DAC
# error "CONFIG_STM32_TIM6_DAC required for DAC1"
# endif
+# define NEED_TIM6
# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM6
# define DAC1_TIMER_BASE STM32_TIM6_BASE
# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY
@@ -182,6 +194,7 @@
# ifndef CONFIG_STM32_TIM3_DAC
# error "CONFIG_STM32_TIM3_DAC required for DAC1"
# endif
+# define NEED_TIM3
# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM3
# define DAC1_TIMER_BASE STM32_TIM3_BASE
# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY
@@ -189,6 +202,7 @@
# ifndef CONFIG_STM32_TIM8_DAC
# error "CONFIG_STM32_TIM8_DAC required for DAC1"
# endif
+# define NEED_TIM8
# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM8
# define DAC1_TIMER_BASE STM32_TIM8_BASE
# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK2_FREQUENCY
@@ -196,12 +210,14 @@
# ifndef CONFIG_STM32_TIM7_DAC
# error "CONFIG_STM32_TIM7_DAC required for DAC1"
# endif
+# define NEED_TIM7
# 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_DAC
# error "CONFIG_STM32_TIM5_DAC required for DAC1"
# endif
+# define NEED_TIM5
# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM5
# define DAC1_TIMER_BASE STM32_TIM5_BASE
# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY
@@ -209,6 +225,7 @@
# ifndef CONFIG_STM32_TIM2_DAC
# error "CONFIG_STM32_TIM2_DAC required for DAC1"
# endif
+# define NEED_TIM2
# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM2
# define DAC1_TIMER_BASE STM32_TIM2_BASE
# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY
@@ -216,6 +233,7 @@
# ifndef CONFIG_STM32_TIM4_DAC
# error "CONFIG_STM32_TIM4_DAC required for DAC1"
# endif
+# define NEED_TIM4
# define DAC1_TSEL_VALUE DAC_CR_TSEL_TIM4
# define DAC1_TIMER_BASE STM32_TIM4_BASE
# define DAC1_TIMER_PCLK_FREQUENCY STM32_PCLK1_FREQUENCY
@@ -283,9 +301,14 @@
# define DAC2_TSEL_VALUE DAC_CR_TSEL_SW
#endif
+#ifndef CONFIG_STM32_DAC_DMA_BUFFER_SIZE
+# define CONFIG_STM32_DAC_DMA_BUFFER_SIZE 256
+#endif
+
/* Calculate timer divider values based upon DACn_TIMER_PCLK_FREQUENCY and
* CONFIG_STM32_DACn_TIMER_FREQUENCY.
*/
+
#warning "Missing Logic"
/****************************************************************************
@@ -306,13 +329,17 @@ struct stm32_chan_s
uint8_t inuse : 1; /* True, the driver is in use and not available */
#ifdef HAVE_DMA
uint8_t hasdma : 1; /* True, this channel supports DMA */
+ uint8_t timer; /* Timer number 2-8 */
#endif
uint8_t intf; /* DAC zero-based interface number (0 or 1) */
+ uint32_t dro; /* Data output register */
#ifdef HAVE_DMA
uint16_t dmachan; /* DMA channel needed by this DAC */
DMA_HANDLE dma; /* Allocated DMA channel */
uint32_t tsel; /* CR trigger select value */
uint32_t tbase; /* Timer base address */
+ uint32_t tfrequency; /* Timer frequency */
+ uint16_t dmabuffer[CONFIG_STM32_DAC_DMA_BUFFER_SIZE]; /* DMA transfer buffer */
#endif
};
@@ -340,7 +367,6 @@ static void dac_shutdown(FAR struct dac_dev_s *dev);
static void dac_txint(FAR struct dac_dev_s *dev, bool enable);
static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg);
static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg);
-static int dac_interrupt(int irq, void *context);
/* Initialization */
@@ -367,14 +393,17 @@ static const struct dac_ops_s g_dacops =
#ifdef CONFIG_STM32_DAC1
static struct stm32_chan_s g_dac1priv =
{
- .intf = 0;
+ .intf = 0,
+ .dro = STM32_DAC_DHR12R1,
#ifdef CONFIG_STM32_DAC1_DMA
- .hasdma = 1;
+ .hasdma = 1,
.dmachan = DAC1_DMA_CHAN,
+ .timer = CONFIG_STM32_DAC1_TIMER,
.tsel = DAC1_TSEL_VALUE,
- .tbase = DAC1_TIMER_BASE
+ .tbase = DAC1_TIMER_BASE,
+ .tfrequency = CONFIG_STM32_DAC1_TIMER_FREQUENCY,
#endif
-}
+};
static struct dac_dev_s g_dac1dev =
{
@@ -386,14 +415,17 @@ static struct dac_dev_s g_dac1dev =
#ifdef CONFIG_STM32_DAC2
static struct stm32_chan_s g_dac2priv =
{
- .intf = 1;
+ .intf = 1,
+ .dro = STM32_DAC_DHR12R2,
#ifdef CONFIG_STM32_DAC2_DMA
- .hasdma = 1;
+ .hasdma = 1,
.dmachan = DAC2_DMA_CHAN,
- .tsel = DAC2_TSEL_VALUE.
+ .timer = CONFIG_STM32_DAC2_TIMER,
+ .tsel = DAC2_TSEL_VALUE,
.tbase = DAC2_TIMER_BASE
+ .tfrequency = CONFIG_STM32_DAC2_TIMER_FREQUENCY,
#endif
-}
+};
static struct dac_dev_s g_dac2dev =
{
@@ -409,6 +441,30 @@ static struct stm32_dac_s g_dacblock;
****************************************************************************/
/****************************************************************************
+ * Name: stm32_dac_modify_cr
+ *
+ * Description:
+ * Modify the contents of the DAC control register.
+ *
+ * Input Parameters:
+ * priv - Driver state instance
+ * clearbits - Bits in the control register to be cleared
+ * setbits - Bits in the control register to be set
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void stm32_dac_modify_cr(FAR struct stm32_chan_s *priv,
+ uint32_t clearbits, uint32_t setbits)
+{
+ uint32_t cr = getreg32(STM32_DAC_CR);
+ modifyreg32(STM32_DAC_CR, clearbits << (priv->intf*16), setbits << (priv->intf*16));
+ uint32_t cr1 = getreg32(STM32_DAC_CR);
+}
+
+/****************************************************************************
* Name: tim_getreg
*
* Description:
@@ -445,6 +501,7 @@ static uint32_t tim_getreg(struct stm32_chan_s *chan, int offset)
*
****************************************************************************/
+#ifdef HAVE_DMA
static void tim_putreg(struct stm32_chan_s *chan, int offset, uint32_t value)
{
putreg32(value, chan->tbase + offset);
@@ -452,6 +509,31 @@ static void tim_putreg(struct stm32_chan_s *chan, int offset, uint32_t value)
#endif
/****************************************************************************
+ * Name: tim_modifyreg
+ *
+ * Description:
+ * Modify the value of an DMA timer register.
+ *
+ * Input Parameters:
+ * priv - Driver state instance
+ * offset - The timer register offset
+ * clear_bits - Bits in the control register to be cleared
+ * set_bits - Bits in the control register to be set
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_DMA
+static void tim_modifyreg(struct stm32_chan_s *chan, int offset,
+ uint32_t clear_bits, uint32_t set_bits)
+{
+ modifyreg32(chan->tbase + offset, clear_bits, set_bits);
+}
+#endif
+
+/****************************************************************************
* Name: dac_interrupt
*
* Description:
@@ -565,6 +647,23 @@ static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
}
/****************************************************************************
+ * Name: dac_dmatxcallback
+ *
+ * Description:
+ * DMA callback function.
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
+{
+}
+
+/****************************************************************************
* Name: dac_send
*
* Description:
@@ -579,8 +678,14 @@ static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
{
+ struct stm32_chan_s * chan = dev->ad_priv;
+
+ /* Enable DAC Channel */
+
+ stm32_dac_modify_cr(chan, 0, DAC_CR_EN);
+
#ifdef HAVE_DMA
- if (priv->hasdma)
+ if (chan->hasdma)
{
/* Configure the DMA stream/channel.
*
@@ -597,23 +702,47 @@ static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
* - Memory Burst: single
* - Peripheral Burst: single
*/
-#warning "Missing logic"
+
+ uint32_t ccr =
+ DMA_CCR_MSIZE_16BITS | /* Memory size */
+ DMA_CCR_PSIZE_16BITS | /* Peripheral size */
+ DMA_CCR_MINC | /* Memory increment mode */
+ DMA_CCR_CIRC | /* Circular buffer */
+ DMA_CCR_DIR; /* Read from memory */
+
+ stm32_dmasetup(chan->dma, chan->dro, (uint32_t)chan->dmabuffer,
+ CONFIG_STM32_DAC_DMA_BUFFER_SIZE, ccr);
/* Enable DMA */
-#warning "Missing logic"
- /* Enable DAC Channel */
-#warning "Missing logic"
+ stm32_dmastart(chan->dma, dac_dmatxcallback, chan, false);
/* Enable DMA for DAC Channel */
-#warning "Missing logic"
+
+ stm32_dac_modify_cr(chan, 0, DAC_CR_DMAEN);
}
else
+#endif
{
/* Non-DMA transfer */
-#warning "Missing logic"
+
+ putreg16(msg->am_data, chan->dro);
+#ifdef CONFIG_STM32_DAC2
+ if (chan->intf)
+ {
+ dac_txdone(&g_dac2dev);
+ }
+ else
+#endif
+ {
+ dac_txdone(&g_dac1dev);
+ }
}
- return -ENOSYS;
+
+ /* Reset counters (generate an update) */
+
+ tim_modifyreg(chan, STM32_BTIM_EGR_OFFSET, 0, ATIM_EGR_UG);
+ return OK;
}
/****************************************************************************
@@ -652,16 +781,114 @@ static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg)
#ifdef HAVE_DMA
static int dac_timinit(struct stm32_chan_s *chan)
{
+ uint32_t prescaler;
+ uint32_t numerator;
+ uint32_t regaddr;
+ uint32_t setbits;
+
/* Configure the time base: Timer period, prescaler, clock division,
* counter mode (up).
*/
-#warning "Missing Logic"
+
+ /* Enable the timer. At most, two of the following cases (pluse the
+ * default) will be enabled
+ */
+
+ numerator = 2 * STM32_TIM27_FREQUENCY;
+ regaddr = STM32_RCC_APB1ENR;
+
+ switch (chan->timer)
+ {
+#ifdef NEED_TIM2
+ case 2:
+ setbits = RCC_APB1ENR_TIM2EN;
+ break;
+#endif
+#ifdef NEED_TIM3
+ case 3:
+ setbits = RCC_APB1ENR_TIM3EN;
+ break;
+#endif
+#ifdef NEED_TIM4
+ case 4:
+ setbits = RCC_APB1ENR_TIM4EN;
+ break;
+#endif
+#ifdef NEED_TIM5
+ case 5:
+ setbits = RCC_APB1ENR_TIM5EN;
+ break;
+#endif
+#ifdef NEED_TIM6
+ case 6:
+ setbits = RCC_APB1ENR_TIM6EN;
+ break;
+#endif
+#ifdef NEED_TIM8
+ case 8:
+ regaddr = STM32_RCC_APB2ENR;
+ setbits = RCC_APB2ENR_TIM8EN;
+ numerator = 2 * STM32_TIM18_FREQUENCY
+ break;
+#endif
+#ifdef NEED_TIM7
+ case 7:
+ setbits = RCC_APB1ENR_TIM7EN;
+ break;
+#endif
+ default:
+ adbg("Could not enable timer\n");
+ break;
+ }
+
+ /* Enable the timer. */
+
+ modifyreg32(regaddr, 0, setbits);
+
+ /* Calculate the pre-scaler value */
+
+ prescaler = numerator / chan->tfrequency;
+
+ /* We need to decrement value for '1', but only, if we are allowed to
+ * not to cause underflow. Check for overflow.
+ */
+
+ if (prescaler > 0)
+ {
+ prescaler--;
+ }
+
+ if (prescaler > 0xffff)
+ {
+ prescaler = 0xffff;
+ }
+
+ /* Set prescaler */
+
+ tim_putreg(chan, STM32_BTIM_PSC_OFFSET, 0);
+
+ /* Set period */
+
+ tim_putreg(chan, STM32_BTIM_ARR_OFFSET, prescaler);
+
+ /* Count mode up, auto reload */
+
+ tim_modifyreg(chan, STM32_BTIM_CR1_OFFSET, 0, ATIM_CR1_ARPE);
/* Selection TRGO selection: update */
-#warning "Missing Logic"
+
+ tim_modifyreg(chan, STM32_BTIM_CR2_OFFSET, ATIM_CR2_MMS_MASK,
+ ATIM_CR2_MMS_UPDATE);
+
+ /* Update DMA request enable ???? */
+#if 0
+ tim_modifyreg(chan, STM32_BTIM_DIER_OFFSET, 0, ATIM_DIER_UDE);
+#endif
/* Enable the counter */
-#warning "Missing Logic"
+
+ tim_modifyreg(chan, STM32_BTIM_CR1_OFFSET, 0, ATIM_CR1_CEN);
+ return OK;
}
#endif
@@ -681,6 +908,8 @@ static int dac_timinit(struct stm32_chan_s *chan)
static int dac_chaninit(struct stm32_chan_s *chan)
{
+ int ret;
+
/* Is the selected channel already in-use? */
if (chan->inuse)
@@ -706,17 +935,33 @@ static int dac_chaninit(struct stm32_chan_s *chan)
* - Set wave generation == None.
* - Enable the output buffer.
*/
-#warning "Missing logic"
- /* Determine if DMA is supported by this channel */
+ /* Disable before change */
+
+ stm32_dac_modify_cr(chan, DAC_CR_EN, 0);
+
+ uint16_t clear =
+ DAC_CR_TSEL_MASK | DAC_CR_MAMP_MASK | DAC_CR_WAVE_MASK | DAC_CR_BOFF;
+ uint16_t set =
+ chan->tsel | /* Set trigger source (SW or timer TRGO event) */
+ DAC_CR_MAMP_AMP1 | /* Set waveform characteristics */
+ DAC_CR_WAVE_DISABLED | /* Set no noise */
+ DAC_CR_BOFF; /* Enable output buffer */
+ stm32_dac_modify_cr(chan, clear, set);
#ifdef HAVE_DMA
- if (priv->hasdma)
+ /* Determine if DMA is supported by this channel */
+
+ if (chan->hasdma)
{
- /* Yes.. allocate a DMA channel */
+ /* Yes.. DAC trigger enable */
+
+ stm32_dac_modify_cr(chan, 0, DAC_CR_TEN);
- priv->dma = stm32_dmachannel(priv->dmachan);
- if (!priv->dma)
+ /* Allocate a DMA channel */
+
+ chan->dma = stm32_dmachannel(chan->dmachan);
+ if (!chan->dma)
{
adbg("Failed to allocate a DMA channel\n");
return -EBUSY;
@@ -730,6 +975,7 @@ static int dac_chaninit(struct stm32_chan_s *chan)
adbg("Failed to initialize the DMA timer: %d\n", ret);
return ret;
}
+
}
#endif
@@ -770,12 +1016,12 @@ static int dac_blockinit(void)
flags = irqsave();
regval = getreg32(STM32_RCC_APB1RSTR);
- regval |= RCC_APB1RSTR_DACRST
+ regval |= RCC_APB1RSTR_DACRST;
putreg32(regval, STM32_RCC_APB1RSTR);
/* Take the DAC out of reset state */
- regval &= ~RCC_APB1RSTR_DACRST
+ regval &= ~RCC_APB1RSTR_DACRST;
putreg32(regval, STM32_RCC_APB1RSTR);
irqrestore(flags);
@@ -817,7 +1063,7 @@ FAR struct dac_dev_s *stm32_dacinitialize(int intf)
if (intf == 1)
{
avdbg("DAC1 Selected\n");
- dev = &g_dacdev1;
+ dev = &g_dac1dev;
}
else
#endif
@@ -831,6 +1077,7 @@ FAR struct dac_dev_s *stm32_dacinitialize(int intf)
#endif
{
adbg("No such DAC interface: %d\n", intf);
+ errno = ENODEV;
return NULL;
}
@@ -840,7 +1087,8 @@ FAR struct dac_dev_s *stm32_dacinitialize(int intf)
if (ret < 0)
{
adbg("Failed to initialize the DAC block: %d\n", ret);
- return ret;
+ errno = ret;
+ return NULL;
}
/* Configure the selected DAC channel */
@@ -850,7 +1098,8 @@ FAR struct dac_dev_s *stm32_dacinitialize(int intf)
if (ret < 0)
{
adbg("Failed to initialize DAC channel %d: %d\n", intf, ret);
- return ret;
+ errno = ret;
+ return NULL;
}
return dev;
diff --git a/nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c b/nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c
index 9ab64ce7e..616d2aa1a 100644
--- a/nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c
+++ b/nuttx/arch/arm/src/stm32/stm32f10xxx_dma.c
@@ -58,7 +58,7 @@
/* Only for the STM32F10xx family for now */
-#ifdef CONFIG_STM32_STM32F10XX
+#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX)
/****************************************************************************
* Pre-processor Definitions
@@ -157,7 +157,7 @@ static struct stm32_dma_s g_dma[DMA_NCHANNELS] =
},
{
.chan = 3,
-#ifdef CONFIG_STM32_CONNECTIVITYLINE
+#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F30XX)
.irq = STM32_IRQ_DMA2CH4,
#else
.irq = STM32_IRQ_DMA2CH45,
@@ -166,7 +166,7 @@ static struct stm32_dma_s g_dma[DMA_NCHANNELS] =
},
{
.chan = 4,
-#ifdef CONFIG_STM32_CONNECTIVITYLINE
+#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F30XX)
.irq = STM32_IRQ_DMA2CH5,
#else
.irq = STM32_IRQ_DMA2CH45,
@@ -288,7 +288,7 @@ static int stm32_dmainterrupt(int irq, void *context)
}
else
#if STM32_NDMA > 1
-#ifdef CONFIG_STM32_CONNECTIVITYLINE
+#if defined(CONFIG_STM32_CONNECTIVITYLINE) || defined(CONFIG_STM32_STM32F30XX)
if (irq >= STM32_IRQ_DMA2CH1 && irq <= STM32_IRQ_DMA2CH5)
#else
if (irq >= STM32_IRQ_DMA2CH1 && irq <= STM32_IRQ_DMA2CH45)
@@ -615,10 +615,12 @@ bool stm32_dmacapable(uint32_t maddr)
{
switch (maddr & STM32_REGION_MASK)
{
+#if defined(CONFIG_STM32_STM32F10XX)
case STM32_FSMC_BANK1:
case STM32_FSMC_BANK2:
case STM32_FSMC_BANK3:
case STM32_FSMC_BANK4:
+#endif
case STM32_SRAM_BASE:
case STM32_CODE_BASE:
/* All RAM and flash is supported */