STM32 DAC DMA fixes from John Wharington
This commit is contained in:
parent
413aba0bf5
commit
b57f54fbd0
@ -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).
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 =
|
||||
{
|
||||
@ -408,6 +440,30 @@ static struct stm32_dac_s g_dacblock;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
@ -445,12 +501,38 @@ 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);
|
||||
}
|
||||
#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
|
||||
*
|
||||
@ -564,6 +646,23 @@ static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
|
||||
# warning "Missing logic"
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
@ -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)
|
||||
{
|
||||
/* Yes.. allocate a DMA channel */
|
||||
/* Determine if DMA is supported by this channel */
|
||||
|
||||
priv->dma = stm32_dmachannel(priv->dmachan);
|
||||
if (!priv->dma)
|
||||
if (chan->hasdma)
|
||||
{
|
||||
/* Yes.. DAC trigger enable */
|
||||
|
||||
stm32_dac_modify_cr(chan, 0, DAC_CR_TEN);
|
||||
|
||||
/* 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;
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user