diff --git a/arch/arm/src/lpc17xx/lpc17_dac.c b/arch/arm/src/lpc17xx/lpc17_dac.c index 4f9a9332c3..13ac212f6e 100644 --- a/arch/arm/src/lpc17xx/lpc17_dac.c +++ b/arch/arm/src/lpc17xx/lpc17_dac.c @@ -65,7 +65,7 @@ #include "lpc17_pinconn.h" #include "lpc17_dac.h" -#if defined(CONFIG_LPC17_DAC) +#ifdef CONFIG_LPC17_DAC /**************************************************************************** * Private Types @@ -91,17 +91,17 @@ static int dac_interrupt(int irq, void *context); static const struct dac_ops_s g_dacops = { - .ao_reset =dac_reset, - .ao_setup = dac_setup, - .ao_shutdown = dac_shutdown, - .ao_txint = dac_txint, - .ao_send = dac_send, - .ao_ioctl = dac_ioctl, + .ao_reset =dac_reset, + .ao_setup = dac_setup, + .ao_shutdown = dac_shutdown, + .ao_txint = dac_txint, + .ao_send = dac_send, + .ao_ioctl = dac_ioctl, }; static struct dac_dev_s g_dacdev = { - .ad_ops = &g_dacops, + .ad_ops = &g_dacops, }; /**************************************************************************** @@ -114,22 +114,21 @@ static struct dac_dev_s g_dacdev = static void dac_reset(FAR struct dac_dev_s *dev) { - irqstate_t flags; - uint32_t regval; + irqstate_t flags; + uint32_t regval; - flags = irqsave(); + flags = irqsave(); - regval = getreg32(LPC17_SYSCON_PCLKSEL0); - regval &= ~SYSCON_PCLKSEL0_DAC_MASK; - regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_DAC_SHIFT); - putreg32(regval, LPC17_SYSCON_PCLKSEL0); + regval = getreg32(LPC17_SYSCON_PCLKSEL0); + regval &= ~SYSCON_PCLKSEL0_DAC_MASK; + regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_DAC_SHIFT); + putreg32(regval, LPC17_SYSCON_PCLKSEL0); - //putreg32(DAC_CTRL_DBLBUFEN,LPC17_DAC_CTRL); ? + //putreg32(DAC_CTRL_DBLBUFEN,LPC17_DAC_CTRL); ? - lpc17_configgpio(GPIO_AOUT); - - irqrestore(flags); + lpc17_configgpio(GPIO_AOUT); + irqrestore(flags); } /* Configure the DAC. This method is called the first time that the DAC @@ -140,7 +139,7 @@ static void dac_reset(FAR struct dac_dev_s *dev) static int dac_setup(FAR struct dac_dev_s *dev) { - return OK; + return OK; } /* Disable the DAC. This method is called when the DAC device is closed. @@ -159,17 +158,17 @@ 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) { - putreg32((msg->am_data>>16)&0xfffff,LPC17_DAC_CR); - dac_txdone(&g_dacdev); - return 0; + putreg32((msg->am_data>>16)&0xfffff,LPC17_DAC_CR); + dac_txdone(&g_dacdev); + return 0; } /* All ioctl calls will be routed through this method */ static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg) { - dbg("Fix me:Not Implemented\n"); - return 0; + dbg("Fix me:Not Implemented\n"); + return 0; } static int dac_interrupt(int irq, void *context) @@ -181,7 +180,7 @@ static int dac_interrupt(int irq, void *context) ****************************************************************************/ /**************************************************************************** - * Name: up_dacinitialize + * Name: lpc17_dacinitialize * * Description: * Initialize the DAC @@ -191,9 +190,10 @@ static int dac_interrupt(int irq, void *context) * ****************************************************************************/ -FAR struct dac_dev_s *up_dacinitialize() +FAR struct dac_dev_s *lpc17_dacinitialize(void) { - return &g_dacdev; + return &g_dacdev; } -#endif + +#endif /* CONFIG_LPC17_DAC */ diff --git a/arch/arm/src/lpc17xx/lpc17_internal.h b/arch/arm/src/lpc17xx/lpc17_internal.h index aa2ddc4899..107200e4d3 100755 --- a/arch/arm/src/lpc17xx/lpc17_internal.h +++ b/arch/arm/src/lpc17xx/lpc17_internal.h @@ -609,7 +609,7 @@ EXTERN int lpc17_ssp1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bo #endif /**************************************************************************** - * Name: ssp_flush + * Name: spi_flush * * Description: * Flush and discard any words left in the RX fifo. This can be called @@ -756,6 +756,21 @@ EXTERN void lpc17_dmadump(DMA_HANDLE handle, const struct lpc17_dmaregs_s *regs, #endif #endif +/**************************************************************************** + * Name: lpc17_dacinitialize + * + * Description: + * Initialize the DAC + * + * Returned Value: + * Valid dac device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +#ifdef CONFIG_LPC17_DAC +EXTERN FAR struct dac_dev_s *lpc17_dacinitialize(void); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/stm32/chip/stm32f103ze_pinmap.h b/arch/arm/src/stm32/chip/stm32f103ze_pinmap.h index 3caf54279a..8446a24725 100644 --- a/arch/arm/src/stm32/chip/stm32f103ze_pinmap.h +++ b/arch/arm/src/stm32/chip/stm32f103ze_pinmap.h @@ -48,6 +48,65 @@ /* Alternate Pin Functions: */ +/* ADC */ + +#define GPIO_ADC1_IN0 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN1 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN2 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN3 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN4 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN5 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN6 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN7 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN8 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN9 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN10 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN11 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN12 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN13 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN14 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN15 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC2_IN0 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC2_IN1 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC2_IN2 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC2_IN3 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC2_IN4 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN5 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN6 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN7 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN8 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC2_IN9 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC2_IN10 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN11 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN12 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN13 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN14 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN15 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC3_IN0 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC3_IN1 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC3_IN2 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC3_IN3 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC3_IN4 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC3_IN5 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC3_IN6 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC3_IN7 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ADC3_IN8 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN10) +#define GPIO_ADC3_IN10 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC3_IN11 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC3_IN12 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC3_IN13 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTC|GPIO_PIN3) + +/* 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_DAC_OUT1 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PORTF|GPIO_PIN10) +#define GPIO_DAC_OUT2 (GPIO_ALT|GPIO_CNF_ANALOGIN|GPIO_MODE_INPUT|GPIO_PIN10) + /* TIMERS */ #if defined(CONFIG_STM32_TIM1_FULL_REMAP) diff --git a/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h index cd0dbd1960..50c49cdbc6 100644 --- a/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h +++ b/arch/arm/src/stm32/chip/stm32f40xxx_pinmap.h @@ -68,6 +68,58 @@ * pins in this file. */ +/* ADC */ + +#define GPIO_ADC1_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC2_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC2_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC2_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC2_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC2_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC2_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC2_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +#define GPIO_ADC3_IN0 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC3_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC3_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC3_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC3_IN4 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC3_IN5 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC3_IN6 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC3_IN7 (GPIO_ANALOG|GPIO_PORT |GPIO_PIN9) +#define GPIO_ADC3_IN9 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN3) +#define GPIO_ADC3_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC3_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC3_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC3_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC3_IN14 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN4) +#define GPIO_ADC3_IN15 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN5) + /* CAN */ #define GPIO_CAN1_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTA|GPIO_PIN11) @@ -84,6 +136,15 @@ #define GPIO_CAN2_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN13) #define GPIO_CAN2_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN6) +/* 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) + /* Digital Camera Interface (DCMI) */ #define GPIO_DCMI_D0_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN9) diff --git a/arch/arm/src/stm32/stm32_dac.c b/arch/arm/src/stm32/stm32_dac.c index a7d46707c4..09cdb76f1c 100644 --- a/arch/arm/src/stm32/stm32_dac.c +++ b/arch/arm/src/stm32/stm32_dac.c @@ -61,9 +61,8 @@ #ifdef CONFIG_DAC /**************************************************************************** - * Private Types + * Pre-processor Definitions ****************************************************************************/ - /* Configuration ************************************************************/ /* Up to 2 DAC interfaces are supported */ @@ -77,9 +76,33 @@ #if defined(CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure represents the internal state of the single STM32 DAC block */ + +struct stm32_dac_s +{ + uint8_t init : 1; /* True, the DAC block has been initialized */ +}; + +/* This structure represents the internal state of one STM32 DAC channel */ + +struct stm32_chan_s +{ + uint8_t inuse : 1; /* True, the driver is in use and not available */ + uint8_t intf; /* DAC zero-based interface number (0 or 1) */ +}; + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ +/* DAC Register access */ + +static uint32_t dac_getreg(struct stm32_chan_s *chan, int offset); +static void dac_putreg(struct stm32_chan_s *chan, int offset, uint32_t value); + /* Interrupt handler */ #ifdef CONFIG_STM32_STM32F40XX @@ -96,6 +119,11 @@ 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 */ + +static int dac_chaninit(struct stm32_chan_s *chan); +static int dac_blockinit(void); + /**************************************************************************** * Private Data ****************************************************************************/ @@ -110,15 +138,78 @@ static const struct dac_ops_s g_dacops = .ao_ioctl = dac_ioctl, }; -static struct dac_dev_s g_dacdev = +#ifdef CONFIG_STM32_DAC1 +static struct stm32_chan_s g_dac1priv = { - .ad_ops = &g_dacops, + .intf = 0; +} + +static struct dac_dev_s g_dac1dev = +{ + .ad_ops = &g_dacops, + .ad_priv = &g_dac1priv, }; +#endif + +#ifdef CONFIG_STM32_DAC2 +static struct stm32_chan_s g_dac2priv = +{ + .intf = 1; +} + +static struct dac_dev_s g_dac2dev = +{ + .ad_ops = &g_dacops, + .ad_priv = &g_dac2priv, +}; +#endif + +static struct stm32_dac_s g_dacblock; /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: dac_getreg + * + * Description: + * Read the value of an DAC register. + * + * Input Parameters: + * chan - A reference to the DAC block status + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t dac_getreg(struct stm32_chan_s *chan, int offset) +{ + return getreg32(chan->base + offset); +} + +/**************************************************************************** + * Name: dac_getreg + * + * Description: + * Read the value of an DAC register. + * + * Input Parameters: + * chan - A reference to the DAC block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void dac_putreg(struct stm32_chan_s *chan, int offset, uint32_t value) +{ + putreg32(value, chan->base + offset); +} + /**************************************************************************** * Name: dac_interrupt * @@ -129,6 +220,7 @@ static struct dac_dev_s g_dacdev = * Input Parameters: * * Returned Value: + * OK * ****************************************************************************/ @@ -143,12 +235,15 @@ static int dac_interrupt(int irq, void *context) * Name: dac_reset * * Description: - * Reset the DAC device. Called early to initialize the hardware. This + * Reset the DAC channel. Called early to initialize the hardware. This * is called, before dac_setup() and on error conditions. * + * NOTE: DAC reset will reset both DAC channels! + * * Input Parameters: * * Returned Value: + * None * ****************************************************************************/ @@ -156,11 +251,11 @@ static void dac_reset(FAR struct dac_dev_s *dev) { irqstate_t flags; uint32_t regval; - - flags = irqsave(); -# warning "Missing logic" - + flags = irqsave(); + +#warning "Missing logic" + irqrestore(flags); } @@ -176,6 +271,7 @@ static void dac_reset(FAR struct dac_dev_s *dev) * Input Parameters: * * Returned Value: + * Zero on success; a negated errno value on failure. * ****************************************************************************/ @@ -195,6 +291,7 @@ static int dac_setup(FAR struct dac_dev_s *dev) * Input Parameters: * * Returned Value: + * None * ****************************************************************************/ @@ -212,6 +309,7 @@ static void dac_shutdown(FAR struct dac_dev_s *dev) * Input Parameters: * * Returned Value: + * None * ****************************************************************************/ @@ -229,6 +327,7 @@ static void dac_txint(FAR struct dac_dev_s *dev, bool enable) * Input Parameters: * * Returned Value: + * Zero on success; a negated errno value on failure. * ****************************************************************************/ @@ -247,6 +346,7 @@ static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg) * Input Parameters: * * Returned Value: + * Zero on success; a negated errno value on failure. * ****************************************************************************/ @@ -255,6 +355,82 @@ static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg) return -ENOTTY; } +/**************************************************************************** + * Name: dac_ioctl + * + * Description: + * All ioctl calls will be routed through this method. + * + * Input Parameters: + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int dac_chaninit(struct stm32_chan_s *chan) +{ + /* Is the selected channel already in-use? */ + + if (chan->inuse) + { + /* Yes.. then return EBUSY */ + + return -EBUSY; + } + + /* Mark the DAC channel "in-use" */ + + chan->inuse = 1; + return OK; +} + +/**************************************************************************** + * Name: dac_ioctl + * + * Description: + * All ioctl calls will be routed through this method. + * + * Input Parameters: + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int dac_blockinit(void) +{ + irqstate_t flags; + uint32_t regval; + + /* Has the DMA block already been initialized? */ + + if (g_dacblock.init) + { + /* Yes.. then return success We only have to do this once */ + + return OK; + } + + /* Put the entire DAC block in reset state */ + + flags = irqsave(); + regval = getreg32(STM32_RCC_APB1RSTR); + regval |= RCC_APB1RSTR_DACRST + putreg32(regval, STM32_RCC_APB1RSTR); + + /* Take the DAC out of reset state */ + + regval &= ~RCC_APB1RSTR_DACRST + putreg32(regval, STM32_RCC_APB1RSTR); + irqrestore(flags); + + /* Mark the DAC block as initialized */ + + g_dacblock.init = 1; + return OK; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -263,19 +439,67 @@ static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg) * Name: stm32_dacinitialize * * Description: - * Initialize the DAC + * Initialize the DAC. * * Input Parameters: * intf - The DAC interface number. * * Returned Value: - * Valid dac device structure reference on succcess; a NULL on failure + * Valid dac device structure reference on succcess; a NULL on failure. + * + * Assumptions: + * 1. Clock to the DAC block has enabled, + * 2. Board-specific logic has already configured * ****************************************************************************/ FAR struct dac_dev_s *stm32_dacinitialize(int intf) { - return &g_dacdev; + FAR struct dac_dev_s *dev; + FAR struct stm32_chan_s *chan; + int ret; + +#ifdef CONFIG_STM32_DAC1 + if (intf == 1) + { + avdbg("DAC1 Selected\n"); + dev = &g_dacdev1; + } + else +#endif +#ifdef CONFIG_STM32_DAC2 + if (intf == 2) + { + avdbg("DAC2 Selected\n"); + dev = &g_dac2dev; + } + else +#endif + { + adbg("No such DAC interface: %d\n", intf); + return NULL; + } + + /* Make sure that the DAC block has been initialized */ + + ret = dac_blockinit(); + if (ret < 0) + { + adbg("Failed to initialize the DAC block: %d\n", ret); + return ret; + } + + /* Configure the selected DAC channel */ + + chan = dev->ad_priv; + ret = dac_chaninit(chan); + if (ret < 0) + { + adbg("Failed to initialize DAC channel %d: %d\n", intf, ret); + return ret; + } + + return dev; } #endif /* CONFIG_STM32_DAC1 || CONFIG_STM32_DAC2 */ diff --git a/arch/arm/src/stm32/stm32f10xxx_rcc.c b/arch/arm/src/stm32/stm32f10xxx_rcc.c index 07dda8a592..9976e4870c 100644 --- a/arch/arm/src/stm32/stm32f10xxx_rcc.c +++ b/arch/arm/src/stm32/stm32f10xxx_rcc.c @@ -298,7 +298,7 @@ static inline void rcc_enableapb1(void) regval |= RCC_APB1ENR_PWREN; #endif -#if CONFIG_STM32_DAC +#ifdefined (CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) /* DAC interface clock enable */ regval |= RCC_APB1ENR_DACEN; diff --git a/arch/arm/src/stm32/stm32f40xxx_rcc.c b/arch/arm/src/stm32/stm32f40xxx_rcc.c index e06a84d655..4b8a16790e 100644 --- a/arch/arm/src/stm32/stm32f40xxx_rcc.c +++ b/arch/arm/src/stm32/stm32f40xxx_rcc.c @@ -431,7 +431,7 @@ static inline void rcc_enableapb1(void) regval |= RCC_APB1ENR_PWREN; -#if CONFIG_STM32_DAC +#ifdefined (CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) /* DAC interface clock enable */ regval |= RCC_APB1ENR_DACEN;