mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
STM32 DAC: Fix DMA support for STM32F2xxx and STM32F4xxx
This commit is contained in:
@@ -5367,7 +5367,7 @@ if STM32_DAC1_DMA
|
|||||||
|
|
||||||
config STM32_DAC1_TIMER
|
config STM32_DAC1_TIMER
|
||||||
int "DAC1 timer"
|
int "DAC1 timer"
|
||||||
range 2 7
|
range 2 8
|
||||||
|
|
||||||
config STM32_DAC1_TIMER_FREQUENCY
|
config STM32_DAC1_TIMER_FREQUENCY
|
||||||
int "DAC1 timer frequency"
|
int "DAC1 timer frequency"
|
||||||
@@ -5390,7 +5390,7 @@ if STM32_DAC2_DMA
|
|||||||
config STM32_DAC2_TIMER
|
config STM32_DAC2_TIMER
|
||||||
int "DAC2 timer"
|
int "DAC2 timer"
|
||||||
default 0
|
default 0
|
||||||
range 2 7
|
range 2 8
|
||||||
|
|
||||||
config STM32_DAC2_TIMER_FREQUENCY
|
config STM32_DAC2_TIMER_FREQUENCY
|
||||||
int "DAC2 timer frequency"
|
int "DAC2 timer frequency"
|
||||||
|
|||||||
@@ -479,12 +479,10 @@
|
|||||||
#define ATIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection */
|
#define ATIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection */
|
||||||
#define ATIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection */
|
#define ATIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection */
|
||||||
#define ATIM_CR2_MMS_MASK (7 << ATIM_CR2_MMS_SHIFT)
|
#define ATIM_CR2_MMS_MASK (7 << ATIM_CR2_MMS_SHIFT)
|
||||||
#ifdef CONFIG_STM32_STM32F30XX
|
# define ATIM_CR2_MMS_RESET (0 << ATIM_CR2_MMS_SHIFT) /* 000: Reset - TIMx_EGR UG bit is TRGO */
|
||||||
# define ATIM_CR2_MMS_RESET (0 << ATIM_CR2_MMS_SHIFT) /* 000: Reset - TIMx_EGR UG bit is TRG9 */
|
|
||||||
# define ATIM_CR2_MMS_ENABLE (1 << ATIM_CR2_MMS_SHIFT) /* 001: Enable - CNT_EN is TRGO */
|
# define ATIM_CR2_MMS_ENABLE (1 << ATIM_CR2_MMS_SHIFT) /* 001: Enable - CNT_EN is TRGO */
|
||||||
# define ATIM_CR2_MMS_UPDATE (2 << ATIM_CR2_MMS_SHIFT) /* 010: Update event is TRGH0*/
|
# define ATIM_CR2_MMS_UPDATE (2 << ATIM_CR2_MMS_SHIFT) /* 010: Update event is TRGO */
|
||||||
# define ATIM_CR2_MMS_COMPP (3 << ATIM_CR2_MMS_SHIFT) /* 010: Compare Pulse - CC1IF flag */
|
# define ATIM_CR2_MMS_COMPP (3 << ATIM_CR2_MMS_SHIFT) /* 010: Compare Pulse - CC1IF flag */
|
||||||
#endif
|
|
||||||
# define ATIM_CR2_MMS_OC1REF (4 << ATIM_CR2_MMS_SHIFT) /* 100: Compare OC1REF is TRGO */
|
# define ATIM_CR2_MMS_OC1REF (4 << ATIM_CR2_MMS_SHIFT) /* 100: Compare OC1REF is TRGO */
|
||||||
# define ATIM_CR2_MMS_OC2REF (5 << ATIM_CR2_MMS_SHIFT) /* 101: Compare OC2REF is TRGO */
|
# define ATIM_CR2_MMS_OC2REF (5 << ATIM_CR2_MMS_SHIFT) /* 101: Compare OC2REF is TRGO */
|
||||||
# define ATIM_CR2_MMS_OC3REF (6 << ATIM_CR2_MMS_SHIFT) /* 110: Compare OC3REF is TRGO */
|
# define ATIM_CR2_MMS_OC3REF (6 << ATIM_CR2_MMS_SHIFT) /* 110: Compare OC3REF is TRGO */
|
||||||
@@ -966,14 +964,14 @@
|
|||||||
#define GTIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection (TIM2-5,1,&16 only) */
|
#define GTIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection (TIM2-5,1,&16 only) */
|
||||||
#define GTIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection (not TIM16) */
|
#define GTIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection (not TIM16) */
|
||||||
#define GTIM_CR2_MMS_MASK (7 << GTIM_CR2_MMS_SHIFT)
|
#define GTIM_CR2_MMS_MASK (7 << GTIM_CR2_MMS_SHIFT)
|
||||||
# define GTIM_CR2_RESET (0 << GTIM_CR2_MMS_SHIFT) /* 000: Reset */
|
# define GTIM_CR2_MMS_RESET (0 << GTIM_CR2_MMS_SHIFT) /* 000: Reset */
|
||||||
# define GTIM_CR2_ENAB (1 << GTIM_CR2_MMS_SHIFT) /* 001: Enable */
|
# define GTIM_CR2_MMS_ENABLE (1 << GTIM_CR2_MMS_SHIFT) /* 001: Enable */
|
||||||
# define GTIM_CR2_UPDT (2 << GTIM_CR2_MMS_SHIFT) /* 010: Update */
|
# define GTIM_CR2_MMS_UPDATE (2 << GTIM_CR2_MMS_SHIFT) /* 010: Update */
|
||||||
# define GTIM_CR2_CMPP (3 << GTIM_CR2_MMS_SHIFT) /* 011: Compare Pulse */
|
# define GTIM_CR2_MMS_COMPP (3 << GTIM_CR2_MMS_SHIFT) /* 011: Compare Pulse */
|
||||||
# define GTIM_CR2_CMP1 (4 << GTIM_CR2_MMS_SHIFT) /* 100: Compare - OC1REF signal is used as trigger output (TRGO) */
|
# define GTIM_CR2_MMS_OC1REF (4 << GTIM_CR2_MMS_SHIFT) /* 100: Compare - OC1REF signal is used as trigger output (TRGO) */
|
||||||
# define GTIM_CR2_CMP2 (5 << GTIM_CR2_MMS_SHIFT) /* 101: Compare - OC2REF signal is used as trigger output (TRGO) */
|
# define GTIM_CR2_MMS_OC2REF (5 << GTIM_CR2_MMS_SHIFT) /* 101: Compare - OC2REF signal is used as trigger output (TRGO) */
|
||||||
# define GTIM_CR2_CMP3 (6 << GTIM_CR2_MMS_SHIFT) /* 110: Compare - OC3REF signal is used as trigger output (TRGO, TIM2-5 and TIM15 only) */
|
# define GTIM_CR2_MMS_OC3REF (6 << GTIM_CR2_MMS_SHIFT) /* 110: Compare - OC3REF signal is used as trigger output (TRGO, TIM2-5 and TIM15 only) */
|
||||||
# define GTIM_CR2_CMP4 (7 << GTIM_CR2_MMS_SHIFT) /* 111: Compare - OC4REF signal is used as trigger output (TRGO, TIM2-5 and TIM15 only) */
|
# define GTIM_CR2_MMS_OC4REF (7 << GTIM_CR2_MMS_SHIFT) /* 111: Compare - OC4REF signal is used as trigger output (TRGO, TIM2-5 and TIM15 only) */
|
||||||
#define GTIM_CR2_TI1S (1 << 7) /* Bit 7: TI1 Selection (not TIM16) */
|
#define GTIM_CR2_TI1S (1 << 7) /* Bit 7: TI1 Selection (not TIM16) */
|
||||||
#define GTIM_CR2_OIS1 (1 << 8) /* Bit 8: COutput Idle state 1 (OC1 output) (TIM15-17 only) */
|
#define GTIM_CR2_OIS1 (1 << 8) /* Bit 8: COutput Idle state 1 (OC1 output) (TIM15-17 only) */
|
||||||
#define GTIM_CR2_OIS1N (1 << 9) /* Bit 9: Output Idle state 1 (OC1N output) (TIM15-17 only) */
|
#define GTIM_CR2_OIS1N (1 << 9) /* Bit 9: Output Idle state 1 (OC1N output) (TIM15-17 only) */
|
||||||
|
|||||||
+125
-75
@@ -311,6 +311,22 @@
|
|||||||
|
|
||||||
#warning "Missing Logic"
|
#warning "Missing Logic"
|
||||||
|
|
||||||
|
/* DMA stream/channel configuration */
|
||||||
|
|
||||||
|
#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
||||||
|
# define DAC_DMA_CONTROL_WORD (DMA_SCR_MSIZE_16BITS | \
|
||||||
|
DMA_SCR_PSIZE_16BITS | \
|
||||||
|
DMA_SCR_MINC | \
|
||||||
|
DMA_SCR_CIRC | \
|
||||||
|
DMA_SCR_DIR_M2P)
|
||||||
|
#else
|
||||||
|
# define DAC_DMA_CONTROL_WORD (DMA_CCR_MSIZE_16BITS | \
|
||||||
|
DMA_CCR_PSIZE_16BITS | \
|
||||||
|
DMA_CCR_MINC | \
|
||||||
|
DMA_CCR_CIRC | \
|
||||||
|
DMA_CCR_DIR)
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -349,14 +365,15 @@ struct stm32_chan_s
|
|||||||
/* DAC Register access */
|
/* DAC Register access */
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static uint32_t tim_getreg(struct stm32_chan_s *chan, int offset);
|
static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset);
|
||||||
static void tim_putreg(struct stm32_chan_s *chan, int offset, uint32_t value);
|
static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
|
uint32_t value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Interrupt handler */
|
/* Interrupt handler */
|
||||||
|
|
||||||
#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
||||||
static int dac_interrupt(int irq, void *context);
|
static int dac_interrupt(int irq, FAR void *context);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* DAC methods */
|
/* DAC methods */
|
||||||
@@ -371,9 +388,9 @@ static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg);
|
|||||||
/* Initialization */
|
/* Initialization */
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static int dac_timinit(struct stm32_chan_s *chan);
|
static int dac_timinit(FAR struct stm32_chan_s *chan);
|
||||||
#endif
|
#endif
|
||||||
static int dac_chaninit(struct stm32_chan_s *chan);
|
static int dac_chaninit(FAR struct stm32_chan_s *chan);
|
||||||
static int dac_blockinit(void);
|
static int dac_blockinit(void);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -422,7 +439,7 @@ static struct stm32_chan_s g_dac2priv =
|
|||||||
.dmachan = DAC2_DMA_CHAN,
|
.dmachan = DAC2_DMA_CHAN,
|
||||||
.timer = CONFIG_STM32_DAC2_TIMER,
|
.timer = CONFIG_STM32_DAC2_TIMER,
|
||||||
.tsel = DAC2_TSEL_VALUE,
|
.tsel = DAC2_TSEL_VALUE,
|
||||||
.tbase = DAC2_TIMER_BASE
|
.tbase = DAC2_TIMER_BASE,
|
||||||
.tfrequency = CONFIG_STM32_DAC2_TIMER_FREQUENCY,
|
.tfrequency = CONFIG_STM32_DAC2_TIMER_FREQUENCY,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -456,12 +473,13 @@ static struct stm32_dac_s g_dacblock;
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline void stm32_dac_modify_cr(FAR struct stm32_chan_s *priv,
|
static inline void stm32_dac_modify_cr(FAR struct stm32_chan_s *chan,
|
||||||
uint32_t clearbits, uint32_t setbits)
|
uint32_t clearbits, uint32_t setbits)
|
||||||
{
|
{
|
||||||
uint32_t cr = getreg32(STM32_DAC_CR);
|
uint32_t shift;
|
||||||
modifyreg32(STM32_DAC_CR, clearbits << (priv->intf*16), setbits << (priv->intf*16));
|
|
||||||
uint32_t cr1 = getreg32(STM32_DAC_CR);
|
shift = chan->intf * 16;
|
||||||
|
modifyreg32(STM32_DAC_CR, clearbits << shift, setbits << shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -480,7 +498,7 @@ static inline void stm32_dac_modify_cr(FAR struct stm32_chan_s *priv,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static uint32_t tim_getreg(struct stm32_chan_s *chan, int offset)
|
static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset)
|
||||||
{
|
{
|
||||||
return getreg32(chan->tbase + offset);
|
return getreg32(chan->tbase + offset);
|
||||||
}
|
}
|
||||||
@@ -502,7 +520,8 @@ static uint32_t tim_getreg(struct stm32_chan_s *chan, int offset)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static void tim_putreg(struct stm32_chan_s *chan, int offset, uint32_t value)
|
static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
|
uint32_t value)
|
||||||
{
|
{
|
||||||
putreg32(value, chan->tbase + offset);
|
putreg32(value, chan->tbase + offset);
|
||||||
}
|
}
|
||||||
@@ -517,8 +536,8 @@ static void tim_putreg(struct stm32_chan_s *chan, int offset, uint32_t value)
|
|||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* priv - Driver state instance
|
* priv - Driver state instance
|
||||||
* offset - The timer register offset
|
* offset - The timer register offset
|
||||||
* clear_bits - Bits in the control register to be cleared
|
* clearbits - Bits in the control register to be cleared
|
||||||
* set_bits - Bits in the control register to be set
|
* setbits - Bits in the control register to be set
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -526,10 +545,10 @@ static void tim_putreg(struct stm32_chan_s *chan, int offset, uint32_t value)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static void tim_modifyreg(struct stm32_chan_s *chan, int offset,
|
static void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
uint32_t clear_bits, uint32_t set_bits)
|
uint32_t clearbits, uint32_t setbits)
|
||||||
{
|
{
|
||||||
modifyreg32(chan->tbase + offset, clear_bits, set_bits);
|
modifyreg32(chan->tbase + offset, clearbits, setbits);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -548,7 +567,7 @@ static void tim_modifyreg(struct stm32_chan_s *chan, int offset,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
||||||
static int dac_interrupt(int irq, void *context)
|
static int dac_interrupt(int irq, FAR void *context)
|
||||||
{
|
{
|
||||||
#warning "Missing logic"
|
#warning "Missing logic"
|
||||||
return OK;
|
return OK;
|
||||||
@@ -574,7 +593,6 @@ static int dac_interrupt(int irq, void *context)
|
|||||||
static void dac_reset(FAR struct dac_dev_s *dev)
|
static void dac_reset(FAR struct dac_dev_s *dev)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
uint32_t regval;
|
|
||||||
|
|
||||||
/* Reset only the selected DAC channel; the other DAC channel must remain
|
/* Reset only the selected DAC channel; the other DAC channel must remain
|
||||||
* functional.
|
* functional.
|
||||||
@@ -605,8 +623,8 @@ static void dac_reset(FAR struct dac_dev_s *dev)
|
|||||||
|
|
||||||
static int dac_setup(FAR struct dac_dev_s *dev)
|
static int dac_setup(FAR struct dac_dev_s *dev)
|
||||||
{
|
{
|
||||||
# warning "Missing logic"
|
#warning "Missing logic"
|
||||||
return -ENOSYS;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -625,7 +643,7 @@ static int dac_setup(FAR struct dac_dev_s *dev)
|
|||||||
|
|
||||||
static void dac_shutdown(FAR struct dac_dev_s *dev)
|
static void dac_shutdown(FAR struct dac_dev_s *dev)
|
||||||
{
|
{
|
||||||
# warning "Missing logic"
|
#warning "Missing logic"
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -643,7 +661,7 @@ static void dac_shutdown(FAR struct dac_dev_s *dev)
|
|||||||
|
|
||||||
static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
|
static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
|
||||||
{
|
{
|
||||||
# warning "Missing logic"
|
#warning "Missing logic"
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -659,7 +677,7 @@ static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,7 +696,7 @@ static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
|||||||
|
|
||||||
static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
|
static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
|
||||||
{
|
{
|
||||||
struct stm32_chan_s * chan = dev->ad_priv;
|
FAR struct stm32_chan_s *chan = dev->ad_priv;
|
||||||
|
|
||||||
/* Enable DAC Channel */
|
/* Enable DAC Channel */
|
||||||
|
|
||||||
@@ -703,15 +721,8 @@ static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
|
|||||||
* - Peripheral Burst: single
|
* - Peripheral Burst: single
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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,
|
stm32_dmasetup(chan->dma, chan->dro, (uint32_t)chan->dmabuffer,
|
||||||
CONFIG_STM32_DAC_DMA_BUFFER_SIZE, ccr);
|
CONFIG_STM32_DAC_DMA_BUFFER_SIZE, DAC_DMA_CONTROL_WORD);
|
||||||
|
|
||||||
/* Enable DMA */
|
/* Enable DMA */
|
||||||
|
|
||||||
@@ -760,7 +771,7 @@ 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_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
@@ -781,10 +792,12 @@ static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static int dac_timinit(struct stm32_chan_s *chan)
|
static int dac_timinit(FAR struct stm32_chan_s *chan)
|
||||||
{
|
{
|
||||||
|
uint32_t pclk;
|
||||||
uint32_t prescaler;
|
uint32_t prescaler;
|
||||||
uint32_t numerator;
|
uint32_t timclk;
|
||||||
|
uint32_t reload;
|
||||||
uint32_t regaddr;
|
uint32_t regaddr;
|
||||||
uint32_t setbits;
|
uint32_t setbits;
|
||||||
|
|
||||||
@@ -796,46 +809,46 @@ static int dac_timinit(struct stm32_chan_s *chan)
|
|||||||
* default) will be enabled
|
* default) will be enabled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
numerator = 2 * STM32_TIM27_FREQUENCY;
|
pclk = STM32_TIM27_FREQUENCY;
|
||||||
regaddr = STM32_RCC_APB1ENR;
|
regaddr = STM32_RCC_APB1ENR;
|
||||||
|
|
||||||
switch (chan->timer)
|
switch (chan->timer)
|
||||||
{
|
{
|
||||||
#ifdef NEED_TIM2
|
#ifdef NEED_TIM2
|
||||||
case 2:
|
case 2:
|
||||||
setbits = RCC_APB1ENR_TIM2EN;
|
setbits = RCC_APB1ENR_TIM2EN;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NEED_TIM3
|
#ifdef NEED_TIM3
|
||||||
case 3:
|
case 3:
|
||||||
setbits = RCC_APB1ENR_TIM3EN;
|
setbits = RCC_APB1ENR_TIM3EN;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NEED_TIM4
|
#ifdef NEED_TIM4
|
||||||
case 4:
|
case 4:
|
||||||
setbits = RCC_APB1ENR_TIM4EN;
|
setbits = RCC_APB1ENR_TIM4EN;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NEED_TIM5
|
#ifdef NEED_TIM5
|
||||||
case 5:
|
case 5:
|
||||||
setbits = RCC_APB1ENR_TIM5EN;
|
setbits = RCC_APB1ENR_TIM5EN;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NEED_TIM6
|
#ifdef NEED_TIM6
|
||||||
case 6:
|
case 6:
|
||||||
setbits = RCC_APB1ENR_TIM6EN;
|
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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NEED_TIM7
|
#ifdef NEED_TIM7
|
||||||
case 7:
|
case 7:
|
||||||
setbits = RCC_APB1ENR_TIM7EN;
|
setbits = RCC_APB1ENR_TIM7EN;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_TIM8
|
||||||
|
case 8:
|
||||||
|
regaddr = STM32_RCC_APB2ENR;
|
||||||
|
setbits = RCC_APB2ENR_TIM8EN;
|
||||||
|
pclk = STM32_TIM18_FREQUENCY;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
@@ -847,31 +860,65 @@ static int dac_timinit(struct stm32_chan_s *chan)
|
|||||||
|
|
||||||
modifyreg32(regaddr, 0, setbits);
|
modifyreg32(regaddr, 0, setbits);
|
||||||
|
|
||||||
/* Calculate the pre-scaler value */
|
/* Calculate optimal values for the timer prescaler and for the timer reload
|
||||||
|
* register. If 'frequency' is the desired frequency, then
|
||||||
prescaler = numerator / chan->tfrequency;
|
*
|
||||||
|
* reload = timclk / frequency
|
||||||
/* We need to decrement value for '1', but only, if we are allowed to
|
* timclk = pclk / presc
|
||||||
* not to cause underflow. Check for overflow.
|
*
|
||||||
|
* Or,
|
||||||
|
*
|
||||||
|
* reload = pclk / presc / frequency
|
||||||
|
*
|
||||||
|
* There are many solutions to this this, but the best solution will be the
|
||||||
|
* one that has the largest reload value and the smallest prescaler value.
|
||||||
|
* That is the solution that should give us the most accuracy in the timer
|
||||||
|
* control. Subject to:
|
||||||
|
*
|
||||||
|
* 0 <= presc <= 65536
|
||||||
|
* 1 <= reload <= 65535
|
||||||
|
*
|
||||||
|
* So presc = pclk / 65535 / frequency would be optimal.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* pclk = 42 MHz
|
||||||
|
* frequency = 100 Hz
|
||||||
|
*
|
||||||
|
* prescaler = 42,000,000 / 65,535 / 100
|
||||||
|
* = 6.4 (or 7 -- taking the ceiling always)
|
||||||
|
* timclk = 42,000,000 / 7
|
||||||
|
* = 6,000,000
|
||||||
|
* reload = 6,000,000 / 100
|
||||||
|
* = 60,000
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (prescaler > 0)
|
prescaler = (pclk / chan->tfrequency + 65534) / 65535;
|
||||||
|
if (prescaler < 1)
|
||||||
{
|
{
|
||||||
prescaler--;
|
prescaler = 1;
|
||||||
|
}
|
||||||
|
else if (prescaler > 65536)
|
||||||
|
{
|
||||||
|
prescaler = 65536;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prescaler > 0xffff)
|
timclk = pclk / prescaler;
|
||||||
|
|
||||||
|
reload = timclk / chan->tfrequency;
|
||||||
|
if (reload < 1)
|
||||||
{
|
{
|
||||||
prescaler = 0xffff;
|
reload = 1;
|
||||||
|
}
|
||||||
|
else if (reload > 65535)
|
||||||
|
{
|
||||||
|
reload = 65535;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set prescaler */
|
/* Set the reload and prescaler values */
|
||||||
|
|
||||||
tim_putreg(chan, STM32_BTIM_PSC_OFFSET, 0);
|
tim_putreg(chan, STM32_BTIM_ARR_OFFSET, (uint16_t)reload);
|
||||||
|
tim_putreg(chan, STM32_BTIM_PSC_OFFSET, (uint16_t)(prescaler - 1));
|
||||||
/* Set period */
|
|
||||||
|
|
||||||
tim_putreg(chan, STM32_BTIM_ARR_OFFSET, prescaler);
|
|
||||||
|
|
||||||
/* Count mode up, auto reload */
|
/* Count mode up, auto reload */
|
||||||
|
|
||||||
@@ -908,9 +955,11 @@ static int dac_timinit(struct stm32_chan_s *chan)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int dac_chaninit(struct stm32_chan_s *chan)
|
static int dac_chaninit(FAR struct stm32_chan_s *chan)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
uint16_t clearbits;
|
||||||
|
uint16_t setbits;
|
||||||
|
|
||||||
/* Is the selected channel already in-use? */
|
/* Is the selected channel already in-use? */
|
||||||
|
|
||||||
@@ -942,14 +991,16 @@ static int dac_chaninit(struct stm32_chan_s *chan)
|
|||||||
|
|
||||||
stm32_dac_modify_cr(chan, DAC_CR_EN, 0);
|
stm32_dac_modify_cr(chan, DAC_CR_EN, 0);
|
||||||
|
|
||||||
uint16_t clear =
|
clearbits = DAC_CR_TSEL_MASK |
|
||||||
DAC_CR_TSEL_MASK | DAC_CR_MAMP_MASK | DAC_CR_WAVE_MASK | DAC_CR_BOFF;
|
DAC_CR_MAMP_MASK |
|
||||||
uint16_t set =
|
DAC_CR_WAVE_MASK |
|
||||||
|
DAC_CR_BOFF;
|
||||||
|
setbits =
|
||||||
chan->tsel | /* Set trigger source (SW or timer TRGO event) */
|
chan->tsel | /* Set trigger source (SW or timer TRGO event) */
|
||||||
DAC_CR_MAMP_AMP1 | /* Set waveform characteristics */
|
DAC_CR_MAMP_AMP1 | /* Set waveform characteristics */
|
||||||
DAC_CR_WAVE_DISABLED | /* Set no noise */
|
DAC_CR_WAVE_DISABLED | /* Set no noise */
|
||||||
DAC_CR_BOFF; /* Enable output buffer */
|
DAC_CR_BOFF; /* Enable output buffer */
|
||||||
stm32_dac_modify_cr(chan, clear, set);
|
stm32_dac_modify_cr(chan, clearbits, setbits);
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
/* Determine if DMA is supported by this channel */
|
/* Determine if DMA is supported by this channel */
|
||||||
@@ -977,7 +1028,6 @@ static int dac_chaninit(struct stm32_chan_s *chan)
|
|||||||
adbg("Failed to initialize the DMA timer: %d\n", ret);
|
adbg("Failed to initialize the DMA timer: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1089,7 +1139,7 @@ FAR struct dac_dev_s *stm32_dacinitialize(int intf)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
adbg("Failed to initialize the DAC block: %d\n", ret);
|
adbg("Failed to initialize the DAC block: %d\n", ret);
|
||||||
errno = ret;
|
errno = -ret;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1100,7 +1150,7 @@ FAR struct dac_dev_s *stm32_dacinitialize(int intf)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
adbg("Failed to initialize DAC channel %d: %d\n", intf, ret);
|
adbg("Failed to initialize DAC channel %d: %d\n", intf, ret);
|
||||||
errno = ret;
|
errno = -ret;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1997,7 +1997,7 @@ FAR struct dma2d_layer_s *up_dma2dcreatelayer(fb_coord_t width,
|
|||||||
|
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
errno = ret;
|
errno = -ret;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1090,7 +1090,7 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate optimal values for the timer prescaler and for the timer reload
|
/* Calculate optimal values for the timer prescaler and for the timer reload
|
||||||
* register. If' frequency' is the desired frequency, then
|
* register. If 'frequency' is the desired frequency, then
|
||||||
*
|
*
|
||||||
* reload = timclk / frequency
|
* reload = timclk / frequency
|
||||||
* timclk = pclk / presc
|
* timclk = pclk / presc
|
||||||
@@ -1118,7 +1118,7 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv,
|
|||||||
* = 6.4 (or 7 -- taking the ceiling always)
|
* = 6.4 (or 7 -- taking the ceiling always)
|
||||||
* timclk = 42,000,000 / 7
|
* timclk = 42,000,000 / 7
|
||||||
* = 6,000,000
|
* = 6,000,000
|
||||||
* reload = 7,000,000 / 100
|
* reload = 6,000,000 / 100
|
||||||
* = 60,000
|
* = 60,000
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user