From a1d6cb43a5097414e8933e8d75d8690ee3311f94 Mon Sep 17 00:00:00 2001 From: Thibault RICHARD Date: Wed, 13 Jun 2012 13:30:43 +0200 Subject: [PATCH] [sam] added support for DACC in analogWrite --- .../arduino/sam/cores/arduino/wiring_analog.c | 44 ++ hardware/arduino/sam/system/libsam/chip.h | 1 + .../arduino/sam/system/libsam/include/dacc.h | 102 ++++ .../arduino/sam/system/libsam/source/dacc.c | 481 ++++++++++++++++++ .../arduino_due_x/libsam_sam3x8e_gcc_rel.a | Bin 81662 -> 86236 bytes .../libsam_sam3x8e_gcc_rel.a.txt | 81 +-- .../sam/variants/arduino_due_x/variant.h | 14 +- 7 files changed, 690 insertions(+), 33 deletions(-) create mode 100644 hardware/arduino/sam/system/libsam/include/dacc.h create mode 100644 hardware/arduino/sam/system/libsam/source/dacc.c diff --git a/hardware/arduino/sam/cores/arduino/wiring_analog.c b/hardware/arduino/sam/cores/arduino/wiring_analog.c index bd7ec2d8f..0cdc7893d 100644 --- a/hardware/arduino/sam/cores/arduino/wiring_analog.c +++ b/hardware/arduino/sam/cores/arduino/wiring_analog.c @@ -183,6 +183,50 @@ void analogOutputInit(void) { void analogWrite(uint32_t ulPin, uint32_t ulValue) { uint32_t attr = g_APinDescription[ulPin].ulPinAttribute; + if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) { + EAnalogChannel channel = g_APinDescription[ulPin].ulADCChannelNumber; + if (channel == DAC0 || channel == DAC1) { + uint32_t chDACC = ((channel == DAC0) ? 0 : 1); + if ((dacc_get_channel_status(DACC_INTERFACE) & (1 << chDACC)) == 0) { + /* Enable clock for DACC_INTERFACE */ + pmc_enable_periph_clk(DACC_INTERFACE_ID); + + /* Reset DACC registers */ + dacc_reset(DACC_INTERFACE); + + /* Half word transfer mode */ + dacc_set_transfer_mode(DACC_INTERFACE, 0); + + /* Power save: + * sleep mode - 0 (disabled) + * fast wakeup - 0 (disabled) + */ + dacc_set_power_save(DACC_INTERFACE, 0, 0); + /* Timing: + * refresh - 0x08 (1024*8 dacc clocks) + * max speed mode - 0 (disabled) + * startup time - 0x10 (1024 dacc clocks) + */ + dacc_set_timing(DACC_INTERFACE, 0x08, 0, 0x10); + + /* Disable TAG and select output channel chDACC */ + dacc_set_channel_selection(DACC_INTERFACE, chDACC); + + /* Enable output channel chDACC */ + dacc_enable_channel(DACC_INTERFACE, chDACC); + + /* Set up analog current */ + dacc_set_analog_control(DACC_INTERFACE, DACC_ACR_IBCTLCH0(0x02) | + DACC_ACR_IBCTLCH1(0x02) | + DACC_ACR_IBCTLDACCORE(0x01)); + } + + // Write user value + dacc_write_conversion_data(DACC_INTERFACE, ulValue); + return; + } + } + if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) { if (!PWMEnabled) { // PWM Startup code diff --git a/hardware/arduino/sam/system/libsam/chip.h b/hardware/arduino/sam/system/libsam/chip.h index 31f76f10b..0d90c7f19 100644 --- a/hardware/arduino/sam/system/libsam/chip.h +++ b/hardware/arduino/sam/system/libsam/chip.h @@ -42,6 +42,7 @@ * Peripherals */ #include "include/adc.h" +#include "include/dacc.h" #include "include/interrupt_sam_nvic.h" #include "include/pio.h" #include "include/pmc.h" diff --git a/hardware/arduino/sam/system/libsam/include/dacc.h b/hardware/arduino/sam/system/libsam/include/dacc.h new file mode 100644 index 000000000..81342d198 --- /dev/null +++ b/hardware/arduino/sam/system/libsam/include/dacc.h @@ -0,0 +1,102 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#ifndef DACC_H_INCLUDED +#define DACC_H_INCLUDED + +#include "../chip.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +//! DACC return codes +typedef enum dacc_rc { + DACC_RC_OK = 0, //!< Operation OK + DACC_RC_INVALID_PARAM //!< Invalid parameter +} dacc_rc_t; + +#if SAM3N_SERIES +//! DACC resolution in number of data bits +# define DACC_RESOLUTION 10 +#else +//! DACC resolution in number of data bits +# define DACC_RESOLUTION 12 +#endif +//! DACC max data value +#define DACC_MAX_DATA ((1 << DACC_RESOLUTION) - 1) + +void dacc_reset(Dacc *p_dacc); +uint32_t dacc_set_trigger(Dacc *p_dacc, uint32_t ul_trigger); +void dacc_disable_trigger(Dacc *p_dacc); +uint32_t dacc_set_transfer_mode(Dacc *p_dacc, uint32_t ul_mode); +void dacc_enable_interrupt(Dacc *p_dacc, uint32_t ul_interrupt_mask); +void dacc_disable_interrupt(Dacc *p_dacc, uint32_t ul_interrupt_mask); +uint32_t dacc_get_interrupt_mask(Dacc *p_dacc); +uint32_t dacc_get_interrupt_status(Dacc *p_dacc); +void dacc_write_conversion_data(Dacc *p_dacc, uint32_t ul_data); +void dacc_set_writeprotect(Dacc *p_dacc, uint32_t ul_enable); +uint32_t dacc_get_writeprotect_status(Dacc *p_dacc); +Pdc *dacc_get_pdc_base(Dacc *p_dacc); + +#if (SAM3N_SERIES) || defined(__DOXYGEN__) +void dacc_enable(Dacc *p_dacc); +void dacc_disable(Dacc *p_dacc); +uint32_t dacc_set_timing(Dacc *p_dacc, uint32_t ul_startup, + uint32_t ul_clock_divider); +#endif /* (SAM3N_SERIES) */ + +#if (SAM3S_SERIES) || (SAM3XA_SERIES) || (SAM4S_SERIES) || defined(__DOXYGEN__) +uint32_t dacc_set_channel_selection(Dacc *p_dacc, uint32_t ul_channel); +void dacc_enable_flexible_selection(Dacc *p_dacc); + +uint32_t dacc_set_power_save(Dacc *p_dacc, uint32_t ul_sleep_mode, + uint32_t ul_fast_wakeup_mode); +uint32_t dacc_set_timing(Dacc *p_dacc, uint32_t ul_refresh, uint32_t ul_maxs, + uint32_t ul_startup); +uint32_t dacc_enable_channel(Dacc *p_dacc, uint32_t ul_channel); +uint32_t dacc_disable_channel(Dacc *p_dacc, uint32_t ul_channel); +uint32_t dacc_get_channel_status(Dacc *p_dacc); +uint32_t dacc_set_analog_control(Dacc *p_dacc, uint32_t ul_analog_control); +uint32_t dacc_get_analog_control(Dacc *p_dacc); +#endif /* (SAM3S_SERIES) || (SAM3XA_SERIES) */ + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* DACC_H_INCLUDED */ diff --git a/hardware/arduino/sam/system/libsam/source/dacc.c b/hardware/arduino/sam/system/libsam/source/dacc.c new file mode 100644 index 000000000..aa8f9fe93 --- /dev/null +++ b/hardware/arduino/sam/system/libsam/source/dacc.c @@ -0,0 +1,481 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#include "dacc.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \defgroup sam_drivers_dacc_group Digital-to-Analog Converter Controller (DACC) + * + * \par Purpose + * + * Driver for the Digital-to-Analog Converter Controller. It provides access to the main + * features of the DAC controller. + * + * \par Usage + * + * -# DACC clock should be enabled before using it. + * - \ref pmc_enable_periph_clk() can be used to enable the clock. + * -# Reset DACC with \ref dacc_reset(). + * -# If DACC can be enabled/disabled, uses \ref dacc_enable() and + * \ref dacc_disable(). + * -# Initialize DACC timing with \ref dacc_set_timing() (different DAC + * peripheral may require different parameters). + * -# Write conversion data with \ref dacc_write_conversion_data(). + * -# Configure trigger with \ref dacc_set_trigger() + * and \ref dacc_disable_trigger(). + * -# Configure FIFO transfer mode with \ref dacc_set_transfer_mode(). + * -# Control interrupts with \ref dacc_enable_interrupt(), + * \ref dacc_disable_interrupt(), \ref dacc_get_interrupt_mask() and + * \ref dacc_get_interrupt_status(). + * -# DACC registers support write protect with \ref dacc_set_writeprotect() + * and \ref dacc_get_writeprotect_status(). + * -# If the DACC can work with PDC, use \ref dacc_get_pdc_base() to get + * PDC register base for the DAC controller. + * -# If the DACC has several channels to process, the following functions can + * be used: + * - Enable/Disable TAG and select output channel selection by + * \ref dacc_set_channel_selection(), + * \ref dacc_enable_flexible_channel_selection(). + * - Enable/disable channel by \ref dacc_enable_channel() / + * \ref dacc_disable_channel(), get channel status by + * \ref dacc_get_channel_status(). + * + * \section dependencies Dependencies + * This driver does not depend on other modules. + * + * @{ + */ + +//! Max channel number +#if (SAM3N_SERIES) +# define MAX_CH_NB 0 +#else +# define MAX_CH_NB 1 +#endif + +//! DACC Write Protect Key "DAC" in ASCII +#define DACC_WP_KEY (0x444143) + +/** + * \brief Reset DACC. + * + * \param p_dacc Pointer to a DACC instance. + */ +void dacc_reset(Dacc *p_dacc) +{ + p_dacc->DACC_CR = DACC_CR_SWRST; +} + +/** + * \brief Enable trigger and set the trigger source. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_trigger Trigger source number. + * + * \return \ref DACC_RC_OK for OK. + */ +uint32_t dacc_set_trigger(Dacc *p_dacc, uint32_t ul_trigger) +{ + uint32_t mr = p_dacc->DACC_MR & (~(DACC_MR_TRGSEL_Msk)); +#if (SAM3N_SERIES) + p_dacc->DACC_MR = mr + | DACC_MR_TRGEN + | ((ul_trigger << DACC_MR_TRGSEL_Pos) & DACC_MR_TRGSEL_Msk); +#else + p_dacc->DACC_MR = mr | DACC_MR_TRGEN_EN | DACC_MR_TRGSEL(ul_trigger); +#endif + return DACC_RC_OK; +} + +/** + * \brief Disable trigger (free run mode). + * + * \param p_dacc Pointer to a DACC instance. + */ +void dacc_disable_trigger(Dacc *p_dacc) +{ + p_dacc->DACC_MR &= ~DACC_MR_TRGEN; +} + +/** + * \brief Set the transfer mode. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_mode Transfer mode configuration. + * + * \return \ref DACC_RC_OK for OK. + */ +uint32_t dacc_set_transfer_mode(Dacc *p_dacc, uint32_t ul_mode) +{ + if (ul_mode) { +#if (SAM3N_SERIES) + p_dacc->DACC_MR |= DACC_MR_WORD; +#else + p_dacc->DACC_MR |= DACC_MR_WORD_WORD; +#endif + } else { +#if (SAM3N_SERIES) + p_dacc->DACC_MR &= (~DACC_MR_WORD); +#else + p_dacc->DACC_MR &= (~DACC_MR_WORD_WORD); +#endif + } + return DACC_RC_OK; +} + +/** + * \brief Enable DACC interrupts. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_interrupt_mask The interrupt mask. + */ +void dacc_enable_interrupt(Dacc *p_dacc, uint32_t ul_interrupt_mask) +{ + p_dacc->DACC_IER = ul_interrupt_mask; +} + +/** + * \brief Disable DACC interrupts. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_interrupt_mask The interrupt mask. + */ +void dacc_disable_interrupt(Dacc *p_dacc, uint32_t ul_interrupt_mask) +{ + p_dacc->DACC_IDR = ul_interrupt_mask; +} + +/** + * \brief Get the interrupt mask. + * + * \param p_dacc Pointer to a DACC instance. + * + * \return The interrupt mask. + */ +uint32_t dacc_get_interrupt_mask(Dacc *p_dacc) +{ + return p_dacc->DACC_IMR; +} + +/** + * \brief Get the interrupt status. + * + * \param p_dacc Pointer to a DACC instance. + * + * \return The interrupt status. + */ +uint32_t dacc_get_interrupt_status(Dacc *p_dacc) +{ + return p_dacc->DACC_ISR; +} + +/** + * \brief Write data to conversion register. + * + * \note The \a ul_data could be output data or data with channel TAG when + * flexible mode is used. + * + * In flexible mode the 2 bits, DACC_CDR[13:12] which are otherwise unused, + * are employed to select the channel in the same way as with the USER_SEL + * field. Finally, if the WORD field is set, the 2 bits, DACC_CDR[13:12] are + * used for channel selection of the first data and the 2 bits, + * DACC_CDR[29:28] for channel selection of the second data. + * + * \see dacc_enable_flexible_selection() + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_data The data to be transferred to analog value. + */ +void dacc_write_conversion_data(Dacc *p_dacc, uint32_t ul_data) +{ + p_dacc->DACC_CDR = ul_data; +} + +/** + * \brief Enable or disable write protect of DACC registers. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_enable 1 to enable, 0 to disable. + */ +void dacc_set_writeprotect(Dacc *p_dacc, uint32_t ul_enable) +{ + if (ul_enable) { + p_dacc->DACC_WPMR = DACC_WPMR_WPKEY(DACC_WP_KEY) + | DACC_WPMR_WPEN; + } else { + p_dacc->DACC_WPMR = DACC_WPMR_WPKEY(DACC_WP_KEY); + } +} + +/** + * \brief Get the write protect status. + * + * \param p_dacc Pointer to a DACC instance. + * + * \return Write protect status. + */ +uint32_t dacc_get_writeprotect_status(Dacc *p_dacc) +{ + return p_dacc->DACC_WPSR; +} + +/** + * \brief Get PDC registers base address. + * + * \param p_dacc Pointer to a DACC instance. + * + * \return DACC PDC register base address. + */ +Pdc *dacc_get_pdc_base(Dacc *p_dacc) +{ + p_dacc = p_dacc; + return PDC_DACC; +} + +#if (SAM3N_SERIES) || defined(__DOXYGEN__) +/** + * \brief Enable DACC. + * + * \param p_dacc Pointer to a DACC instance. + */ +void dacc_enable(Dacc *p_dacc) +{ + p_dacc->DACC_MR |= DACC_MR_DACEN; +} + +/** + * \brief Disable DACC. + * + * \param p_dacc Pointer to a DACC instance. + * + * \return \ref DACC_RC_OK for OK. + */ +void dacc_disable(Dacc *p_dacc) +{ + p_dacc->DACC_MR &= (~DACC_MR_DACEN); +} + +/** + * \brief Set the DACC timing. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_startup Startup time selection. + * \param ul_clock_divider Clock divider for internal trigger. + * + * \return \ref DACC_RC_OK for OK. + */ +uint32_t dacc_set_timing(Dacc *p_dacc, uint32_t ul_startup, + uint32_t ul_clock_divider) +{ + uint32_t mr = p_dacc->DACC_MR + & ~(DACC_MR_STARTUP_Msk | DACC_MR_CLKDIV_Msk); + p_dacc->DACC_MR = mr | DACC_MR_STARTUP(ul_startup) + | DACC_MR_CLKDIV(ul_clock_divider); + return DACC_RC_OK; +} +#endif /* #if (SAM3N_SERIES) */ + +#if (SAM3S_SERIES) || (SAM3XA_SERIES) || (SAM4S_SERIES) || defined(__DOXYGEN__) +/** + * \brief Disable flexible (TAG) mode and select a channel for DAC outputs. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_channel Channel to select. + * + * \return \ref DACC_RC_OK if successful. + */ +uint32_t dacc_set_channel_selection(Dacc *p_dacc, uint32_t ul_channel) +{ + uint32_t mr = p_dacc->DACC_MR & (~DACC_MR_USER_SEL_Msk); + if (ul_channel > MAX_CH_NB) { + return DACC_RC_INVALID_PARAM; + } + mr &= ~(DACC_MR_TAG); + mr |= ul_channel << DACC_MR_USER_SEL_Pos; + p_dacc->DACC_MR = mr; + return DACC_RC_OK; +} + +/** + * \brief Enable the flexible channel selection mode (TAG). + * + * In this mode the 2 bits, DACC_CDR[13:12] which are otherwise unused, are + * employed to select the channel in the same way as with the USER_SEL field. + * Finally, if the WORD field is set, the 2 bits, DACC_CDR[13:12] are used + * for channel selection of the first data and the 2 bits, DACC_CDR[29:28] + * for channel selection of the second data. + * + * \param p_dacc Pointer to a DACC instance. + */ +void dacc_enable_flexible_selection(Dacc *p_dacc) +{ + p_dacc->DACC_MR |= DACC_MR_TAG; +} + +/** + * \brief Set the power save mode. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_sleep_mode Sleep mode configuration. + * \param ul_fast_wakeup_mode Fast wakeup mode configuration. + * + * \return \ref DACC_RC_OK if successful. + */ +uint32_t dacc_set_power_save(Dacc *p_dacc, + uint32_t ul_sleep_mode, uint32_t ul_fast_wakeup_mode) +{ + if (ul_sleep_mode) { + p_dacc->DACC_MR |= DACC_MR_SLEEP; + } else { + p_dacc->DACC_MR &= (~DACC_MR_SLEEP); + } + if (ul_fast_wakeup_mode) { + p_dacc->DACC_MR |= DACC_MR_FASTWKUP; + } else { + p_dacc->DACC_MR &= (~DACC_MR_FASTWKUP); + } + return DACC_RC_OK; +} + +/** + * \brief Set DACC timings. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_refresh Refresh period setting value. + * \param ul_maxs Max speed mode configuration. + * \param ul_startup Startup time selection. + * + * \return \ref DACC_RC_OK for OK. + */ +uint32_t dacc_set_timing(Dacc *p_dacc, + uint32_t ul_refresh, uint32_t ul_maxs, uint32_t ul_startup) +{ + uint32_t mr = p_dacc->DACC_MR + & (~(DACC_MR_REFRESH_Msk | DACC_MR_STARTUP_Msk)); + mr |= DACC_MR_REFRESH(ul_refresh); + if (ul_maxs) { + mr |= DACC_MR_MAXS; + } else { + mr &= ~DACC_MR_MAXS; + } + mr |= (DACC_MR_STARTUP_Msk & ((ul_startup) << DACC_MR_STARTUP_Pos)); + p_dacc->DACC_MR = mr; + return DACC_RC_OK; +} + +/** + * \brief Enable DACC channel. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_channel The output channel to enable. + * + * \return \ref DACC_RC_OK for OK. + */ +uint32_t dacc_enable_channel(Dacc *p_dacc, uint32_t ul_channel) +{ + if (ul_channel > MAX_CH_NB) + return DACC_RC_INVALID_PARAM; + + p_dacc->DACC_CHER = DACC_CHER_CH0 << ul_channel; + return DACC_RC_OK; +} + +/** + * \brief Disable DACC channel. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_channel The output channel to disable. + * + * \return \ref DACC_RC_OK for OK. + */ +uint32_t dacc_disable_channel(Dacc *p_dacc, uint32_t ul_channel) +{ + if (ul_channel > MAX_CH_NB) { + return DACC_RC_INVALID_PARAM; + } + p_dacc->DACC_CHDR = DACC_CHDR_CH0 << ul_channel; + return DACC_RC_OK; +} + +/** + * \brief Get the channel status. + * + * \param p_dacc Pointer to a DACC instance. + * + * \return DACC channel status. + */ +uint32_t dacc_get_channel_status(Dacc *p_dacc) +{ + return p_dacc->DACC_CHSR; +} + +/** + * \brief Set the analog control value. + * + * \param p_dacc Pointer to a DACC instance. + * \param ul_analog_control Analog control configuration. + * + * \return \ref DACC_RC_OK for OK. + */ +uint32_t dacc_set_analog_control(Dacc *p_dacc, uint32_t ul_analog_control) +{ + p_dacc->DACC_ACR = ul_analog_control; + return DACC_RC_OK; +} + +/** + * \brief Get the analog control value. + * + * \param p_dacc Pointer to a DACC instance. + * + * \return Current setting of analog control. + */ +uint32_t dacc_get_analog_control(Dacc *p_dacc) +{ + return p_dacc->DACC_ACR; +} +#endif /* (SAM3S_SERIES) || (SAM3XA_SERIES) */ + +//@} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a b/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a index dfca5a266e7cafba1ee74d2828eb21f423a9f195..1a9194c141417260bde5d987aaaf7258f4aa13d8 100644 GIT binary patch delta 6685 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 Qtygn1aAv2vxc_AEA7#C_3IG5A delta 4069 zcmcgv3v3is6uobz+h3sFrMul0`Wdj&B2C-@waJMRhs6+^kf^1CShm5#syQW=!ng2k=j1?L~k{dG-f@fynk104N%}ad~kyK%~5y3vjD)+zW7X z!TR4Q=+ps#NI5qZz$jn725{S={ToScBZn5bgYU5%|D$NPGZ~4`0WJxPfLQu&MJfh9 z=&lh!1}6GgQ@mBm&!@wOjn*d(E0twrIeM@%Rev+%TN4Kvtq8IP#WN6Sj3z1i=Xqb` zgixyfVdcIk+8IBTw)j%?Pi9{u^sFzQw#6sX<8#w!-Mj?4Wwwp3*|}S9@mXZq>2*=d z{3O{~R1nmzLi*^55wg>*GAub&dgY*1c6r=%?+aGRE22D3y6wU_J)vfWi438`)060~ zI)Rdjd&f?l>lhs7#R(uDFD+1t`K@A(-?;=$m0$%T?Wu8@H;{u zWg6pp1wJA4N2oP6;b~zQ%XAFDc!5ipo)NJSOoW`xC*<)M6c&&Eum#=^Fk8e|30=c9 z#*N3fB~QdB!kUKd7y}eBAdBhg067BZGL8Nw|NOkA`N6Lbc6Yd3MTPyn+PD0&Y%Zy5 zuAWz4JIN2_6%%|D8}y%7?IRL4dRXJR>9!Lkfku^V(%YZxkm#CDE1lJ1mM+P(aYM4c zrbUrS0`;A;$Bn|N*)>>ye{CYkaIpgSAEEGL;&#w$>#ovY)+f;q)+;o+)fQro6kTn# zO0v^c6yyQ72RnR1;POPWQFlHwCdz`Iu)H4n)TY<@=9>XabWeNc_3dA1e?BIJQuVfuC342Z22t~h%1OS;raFIZ@k)O! zF!VsJpE?rL74|#Whs&C3XVh0O54!u03mvup?CA2^>YDzM{PFT+p+sfX%}Z))(C%N> zOnnJ9ea?YllB^c0blX8ID*#h!Au1aQ0tZ)w@w`oPczI=1CyTI3&LXbd$o3c?& z&I7vZb~t))};~%WT>n1(3+ee`L3r zyh455cKyNb-(=HZoSXz68%dJr+{3ZhKno9N;=K*;$+Y8e=AB6_0Pev1^-IP>fSkjx z1iX^~!8gF*YGI1wCI^}VHQ9Iu^Ny6761k1NDCp)RvBatej?5(**1^z2YS=+lRU^Ht zVHB=9j7M4xBYV~1HRg1NWpNsNR?To5sX_G^JA;)K&kOB1c1^=~TNSQfLY}N)8u22b z>zPL4=Usz#-ZdV3FM0>fY>YI zLQjD6ODL}B@8iNYgr6M>lmvGWdQ|)oVj_i2fIe(BM}$&#}GJGUgr>GMvGi(!Vc#5d^FGws1p{o0w`Ch>FY`N|kW0_p3n1V(B6YxMk& zyV64ZmeTWdG`S*OhwI|VRf&)E(%yD^&)PvGD@qJa>3Ppgo{)vNvBTc;h?T^q2#gEu KS)EG`SpNhSjE*k= diff --git a/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a.txt b/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a.txt index 8996b7b37..86c0b679d 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a.txt +++ b/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a.txt @@ -99,14 +99,14 @@ pwmc.o: 00000000 T PWMC_SetSyncChannelUpdateUnlock 00000000 T PWMC_WriteBuffer U __assert_func -00000000 r __func__.3235 -00000000 r __func__.3246 -00000000 r __func__.3261 -00000000 r __func__.3272 -00000000 r __func__.3283 -00000000 r __func__.3290 -00000000 r __func__.3374 -00000000 r __func__.3380 +00000000 r __func__.3296 +00000000 r __func__.3307 +00000000 r __func__.3322 +00000000 r __func__.3333 +00000000 r __func__.3344 +00000000 r __func__.3351 +00000000 r __func__.3435 +00000000 r __func__.3441 rtc.o: 00000000 T RTC_ClearSCCR @@ -122,9 +122,9 @@ rtc.o: 00000000 T RTC_SetTime 00000000 T RTC_SetTimeAlarm U __assert_func -00000000 r __func__.3232 -00000000 r __func__.3241 -00000000 r __func__.3246 +00000000 r __func__.3293 +00000000 r __func__.3302 +00000000 r __func__.3307 rtt.o: 00000000 T RTT_EnableIT @@ -133,8 +133,8 @@ rtt.o: 00000000 T RTT_SetAlarm 00000000 T RTT_SetPrescaler U __assert_func -00000000 r __func__.3239 -00000000 r __func__.3247 +00000000 r __func__.3300 +00000000 r __func__.3308 spi.o: 00000000 T SPI_Configure @@ -155,9 +155,9 @@ tc.o: 00000000 T TC_Start 00000000 T TC_Stop U __assert_func -00000000 r __func__.3234 -00000000 r __func__.3240 -00000000 r __func__.3246 +00000000 r __func__.3295 +00000000 r __func__.3301 +00000000 r __func__.3307 timetick.o: 00000000 T GetTickCount @@ -184,18 +184,18 @@ twi.o: 00000000 T TWI_TransferComplete 00000000 T TWI_WriteByte U __assert_func -00000000 r __func__.3599 -00000000 r __func__.3614 -00000000 r __func__.3618 -00000000 r __func__.3625 -00000000 r __func__.3629 -00000000 r __func__.3634 -00000000 r __func__.3642 -00000000 r __func__.3656 -00000000 r __func__.3661 -00000000 r __func__.3665 -00000000 r __func__.3670 -00000000 r __func__.3674 +00000000 r __func__.3660 +00000000 r __func__.3675 +00000000 r __func__.3679 +00000000 r __func__.3686 +00000000 r __func__.3690 +00000000 r __func__.3695 +00000000 r __func__.3703 +00000000 r __func__.3717 +00000000 r __func__.3722 +00000000 r __func__.3726 +00000000 r __func__.3731 +00000000 r __func__.3735 usart.o: 00000000 T USART_Configure @@ -214,7 +214,7 @@ usart.o: 00000000 T USART_Write 00000000 T USART_WriteBuffer U __assert_func -00000000 r __func__.3520 +00000000 r __func__.3581 wdt.o: 00000000 T WDT_Disable @@ -404,3 +404,26 @@ uotghs_host.o: U pmc_enable_upll_clock U pmc_switch_udpck_to_upllck 00000000 b uhd_state + +dacc.o: +00000000 T dacc_disable_channel +00000000 T dacc_disable_interrupt +00000000 T dacc_disable_trigger +00000000 T dacc_enable_channel +00000000 T dacc_enable_flexible_selection +00000000 T dacc_enable_interrupt +00000000 T dacc_get_analog_control +00000000 T dacc_get_channel_status +00000000 T dacc_get_interrupt_mask +00000000 T dacc_get_interrupt_status +00000000 T dacc_get_pdc_base +00000000 T dacc_get_writeprotect_status +00000000 T dacc_reset +00000000 T dacc_set_analog_control +00000000 T dacc_set_channel_selection +00000000 T dacc_set_power_save +00000000 T dacc_set_timing +00000000 T dacc_set_transfer_mode +00000000 T dacc_set_trigger +00000000 T dacc_set_writeprotect +00000000 T dacc_write_conversion_data diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.h b/hardware/arduino/sam/variants/arduino_due_x/variant.h index 283751fb5..884a4d01f 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.h +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.h @@ -148,10 +148,16 @@ static const uint8_t A8 = 62; static const uint8_t A9 = 63; static const uint8_t A10 = 64; static const uint8_t A11 = 65; -static const uint8_t A12 = 66; -static const uint8_t A13 = 67; -static const uint8_t A14 = 68; -static const uint8_t A15 = 69; +static const uint8_t DA0 = 66; +static const uint8_t DA1 = 67; +static const uint8_t CANRX0 = 68; +static const uint8_t CANTX0 = 69; + +/* + * DACC + */ +#define DACC_INTERFACE DACC +#define DACC_INTERFACE_ID ID_DACC /* * PWM