diff --git a/hardware/arduino/sam/cores/arduino/libsam_sam3x8e_gcc_dbg.a b/hardware/arduino/sam/cores/arduino/libsam_sam3x8e_gcc_dbg.a deleted file mode 100644 index ad30b43b3..000000000 Binary files a/hardware/arduino/sam/cores/arduino/libsam_sam3x8e_gcc_dbg.a and /dev/null differ diff --git a/hardware/arduino/sam/cores/arduino/libsam_sam3x8e_gcc_dbg.a.txt b/hardware/arduino/sam/cores/arduino/libsam_sam3x8e_gcc_dbg.a.txt deleted file mode 100644 index d5c0cf942..000000000 --- a/hardware/arduino/sam/cores/arduino/libsam_sam3x8e_gcc_dbg.a.txt +++ /dev/null @@ -1,418 +0,0 @@ - -adc.o: -00000000 T adc_configure_power_save -00000000 T adc_configure_sequence -00000000 T adc_configure_timing -00000000 T adc_configure_trigger -00000000 T adc_disable_all_channel -00000000 T adc_disable_anch -00000000 T adc_disable_channel -00000000 T adc_disable_channel_differential_input -00000000 T adc_disable_channel_input_offset -00000000 T adc_disable_interrupt -00000000 T adc_disable_tag -00000000 T adc_disable_ts -00000000 T adc_enable_all_channel -00000000 T adc_enable_anch -00000000 T adc_enable_channel -00000000 T adc_enable_channel_differential_input -00000000 T adc_enable_channel_input_offset -00000000 T adc_enable_interrupt -00000000 T adc_enable_tag -00000000 T adc_enable_ts -00000000 T adc_get_actual_adc_clock -00000000 T adc_get_channel_status -00000000 T adc_get_channel_value -00000000 T adc_get_comparison_mode -00000000 T adc_get_interrupt_mask -00000000 T adc_get_latest_value -00000000 T adc_get_overrun_status -00000000 T adc_get_pdc_base -00000000 T adc_get_status -00000000 T adc_get_tag -00000000 T adc_get_writeprotect_status -00000000 T adc_init -00000000 T adc_set_bias_current -00000000 T adc_set_channel_input_gain -00000000 T adc_set_comparison_channel -00000000 T adc_set_comparison_mode -00000000 T adc_set_comparison_window -00000000 T adc_set_resolution -00000000 T adc_set_writeprotect -00000000 T adc_start -00000000 T adc_start_sequencer -00000000 T adc_stop -00000000 T adc_stop_sequencer - -adc12_sam3u.o: - -interrupt_sam_nvic.o: -00000000 D g_interrupt_enabled - -pio.o: -00000000 T PIO_Clear -00000000 T PIO_Configure -00000000 T PIO_DisableInterrupt -00000000 T PIO_Get -00000000 T PIO_GetOutputDataStatus -00000000 T PIO_PullUp -00000000 T PIO_Set -00000000 T PIO_SetDebounceFilter -00000000 T PIO_SetInput -00000000 T PIO_SetOutput -00000000 T PIO_SetPeripheral - -pmc.o: -00000000 T pmc_clr_fast_startup_input -00000000 T pmc_disable_all_pck -00000000 T pmc_disable_all_periph_clk -00000000 T pmc_disable_interrupt -00000000 T pmc_disable_pck -00000000 T pmc_disable_periph_clk -00000000 T pmc_disable_pllack -00000000 T pmc_disable_udpck -00000000 T pmc_disable_upll_clock -00000000 T pmc_enable_all_pck -00000000 T pmc_enable_all_periph_clk -00000000 T pmc_enable_backupmode -00000000 T pmc_enable_interrupt -00000000 T pmc_enable_pck -00000000 T pmc_enable_periph_clk -00000000 T pmc_enable_pllack -00000000 T pmc_enable_sleepmode -00000000 T pmc_enable_udpck -00000000 T pmc_enable_upll_clock -00000000 T pmc_enable_waitmode -00000000 T pmc_get_interrupt_mask -00000000 T pmc_get_status -00000000 T pmc_get_writeprotect_status -00000000 T pmc_is_locked_pllack -00000000 T pmc_is_locked_upll -00000000 T pmc_is_pck_enabled -00000000 T pmc_is_periph_clk_enabled -00000000 T pmc_mck_set_prescaler -00000000 T pmc_mck_set_source -00000000 T pmc_osc_disable_fastrc -00000000 T pmc_osc_disable_xtal -00000000 T pmc_osc_enable_fastrc -00000000 T pmc_osc_is_ready_32kxtal -00000000 T pmc_osc_is_ready_mainck -00000000 T pmc_pck_set_prescaler -00000000 T pmc_pck_set_source -00000000 T pmc_set_fast_startup_input -00000000 T pmc_set_writeprotect -00000000 T pmc_switch_mainck_to_fastrc -00000000 T pmc_switch_mainck_to_xtal -00000000 T pmc_switch_mck_to_mainck -00000000 T pmc_switch_mck_to_pllack -00000000 T pmc_switch_mck_to_sclk -00000000 T pmc_switch_mck_to_upllck -00000000 T pmc_switch_pck_to_mainck -00000000 T pmc_switch_pck_to_pllack -00000000 T pmc_switch_pck_to_sclk -00000000 T pmc_switch_pck_to_upllck -00000000 T pmc_switch_sclk_to_32kxtal -00000000 T pmc_switch_udpck_to_pllack -00000000 T pmc_switch_udpck_to_upllck - -pwmc.o: -00000024 r .LC0 -00000000 r .LC1 -0000016c r .LC10 -0000019c r .LC11 -000001cc r .LC12 -000001fc r .LC13 -00000204 r .LC14 -00000014 r .LC2 -00000050 r .LC3 -0000007c r .LC4 -000000a8 r .LC5 -000000dc r .LC6 -00000108 r .LC7 -00000134 r .LC8 -00000160 r .LC9 -00000000 t FindClockConfiguration -00000000 T PWMC_ConfigureChannel -00000000 T PWMC_ConfigureChannelExt -00000000 T PWMC_ConfigureClocks -00000000 T PWMC_ConfigureComparisonUnit -00000000 T PWMC_ConfigureEventLineMode -00000000 T PWMC_ConfigureSyncChannel -00000000 T PWMC_DisableChannel -00000000 T PWMC_DisableChannelIt -00000000 T PWMC_DisableIt -00000000 T PWMC_DisableOverrideOutput -00000000 T PWMC_EnableChannel -00000000 T PWMC_EnableChannelIt -00000000 T PWMC_EnableFaultProtection -00000000 T PWMC_EnableIt -00000000 T PWMC_EnableOverrideOutput -00000000 T PWMC_FaultClear -00000000 T PWMC_SetDeadTime -00000000 T PWMC_SetDutyCycle -00000000 T PWMC_SetFaultMode -00000000 T PWMC_SetFaultProtectionValue -00000000 T PWMC_SetOverrideValue -00000000 T PWMC_SetPeriod -00000000 T PWMC_SetSyncChannelUpdatePeriod -00000000 T PWMC_SetSyncChannelUpdateUnlock -00000000 T PWMC_WriteBuffer - U __assert_func -00000000 r __func__.3192 -00000000 r __func__.3203 -00000000 r __func__.3218 -00000000 r __func__.3229 -00000000 r __func__.3240 -00000000 r __func__.3247 -00000000 r __func__.3331 -00000000 r __func__.3337 - -rtc.o: -00000000 r .LC0 -00000010 r .LC1 -0000002c r .LC2 -00000000 T RTC_ClearSCCR -00000000 T RTC_DisableIt -00000000 T RTC_EnableIt -00000000 T RTC_GetDate -00000000 T RTC_GetHourMode -00000000 T RTC_GetSR -00000000 T RTC_GetTime -00000000 T RTC_SetDate -00000000 T RTC_SetDateAlarm -00000000 T RTC_SetHourMode -00000000 T RTC_SetTime -00000000 T RTC_SetTimeAlarm - U __assert_func -00000000 r __func__.3189 -00000000 r __func__.3198 -00000000 r __func__.3203 - -rtt.o: -00000000 r .LC0 -00000010 r .LC1 -0000002c r .LC2 -00000000 T RTT_EnableIT -00000000 T RTT_GetStatus -00000000 T RTT_GetTime -00000000 T RTT_SetAlarm -00000000 T RTT_SetPrescaler - U __assert_func -00000000 r __func__.3196 -00000000 r __func__.3204 - -spi.o: -00000000 T SPI_Configure -00000000 T SPI_ConfigureNPCS -00000000 T SPI_Disable -00000000 T SPI_DisableIt -00000000 T SPI_Enable -00000000 T SPI_EnableIt -00000000 T SPI_GetStatus -00000000 T SPI_IsFinished -00000000 T SPI_Read -00000000 T SPI_Write - U pmc_enable_periph_clk - -tc.o: -00000000 r .LC0 -00000010 r .LC1 -00000000 T TC_Configure -00000000 T TC_FindMckDivisor -00000000 T TC_Start -00000000 T TC_Stop - U __assert_func -00000000 r __func__.3191 -00000000 r __func__.3197 -00000000 r __func__.3203 - -timetick.o: -00000000 T GetTickCount -00000000 t NVIC_SetPriority -00000000 T Sleep -00000000 t SysTick_Config -00000000 T TimeTick_Configure -00000000 T TimeTick_Increment -00000000 T Wait -00000000 b _dwTickCount - -twi.o: -00000000 r .LC0 -00000010 r .LC1 -00000018 r .LC2 -00000024 r .LC3 -00000054 r .LC4 -00000064 r .LC5 -0000007c r .LC6 -0000009c r .LC7 -000000a8 r .LC8 -00000000 T TWI_ByteReceived -00000000 T TWI_ByteSent -00000000 T TWI_ConfigureMaster -00000000 T TWI_ConfigureSlave -00000000 T TWI_DisableIt -00000000 T TWI_EnableIt -00000000 T TWI_GetMaskedStatus -00000000 T TWI_GetStatus -00000000 T TWI_ReadByte -00000000 T TWI_SendSTOPCondition -00000000 T TWI_StartRead -00000000 T TWI_StartWrite -00000000 T TWI_Stop -00000000 T TWI_TransferComplete -00000000 T TWI_WriteByte - U __assert_func -00000000 r __func__.3556 -00000000 r __func__.3571 -00000000 r __func__.3575 -00000000 r __func__.3582 -00000000 r __func__.3586 -00000000 r __func__.3591 -00000000 r __func__.3599 -00000000 r __func__.3613 -00000000 r __func__.3618 -00000000 r __func__.3622 -00000000 r __func__.3627 -00000000 r __func__.3631 - -udp.o: - -udphs.o: - -uotghs.o: -00000000 t NVIC_EnableIRQ -00000000 t NVIC_SetPriority -00000000 T UDD_Attach -00000000 T UDD_ClearIN -00000000 T UDD_ClearOUT -00000000 T UDD_ClearSetupInt -00000000 T UDD_Detach -00000000 T UDD_FifoByteCount -00000000 T UDD_GetFrameNumber -00000000 T UDD_Init -00000000 T UDD_InitEP -00000000 T UDD_InitEndpoints -00000000 T UDD_ReadWriteAllowed -00000000 T UDD_ReceivedSetupInt -00000000 T UDD_Recv -00000000 T UDD_Recv8 -00000000 T UDD_ReleaseRX -00000000 T UDD_ReleaseTX -00000000 T UDD_Send -00000000 T UDD_Send8 -00000000 T UDD_SetAddress -00000000 T UDD_SetStack -00000000 T UDD_Stall -00000000 T UDD_WaitForINOrOUT -00000000 T UDD_WaitIN -00000000 T UDD_WaitOUT -00000000 T UOTGHS_Handler -00000000 t cpu_irq_is_enabled_flags -00000000 t cpu_irq_restore -00000000 t cpu_irq_save - U g_interrupt_enabled -00000000 b gpf_isr - U pmc_enable_periph_clk - U pmc_enable_udpck - U pmc_enable_upll_clock - U pmc_switch_udpck_to_upllck -00000000 b ul_recv_fifo_ptr -00000000 b ul_send_fifo_ptr - -usart.o: -00000000 r .LC0 -00000014 r .LC1 -00000000 T USART_Configure -00000000 T USART_DisableIt -00000000 T USART_EnableIt -00000000 T USART_GetChar -00000000 T USART_GetStatus -00000000 T USART_IsDataAvailable -00000000 T USART_IsRxReady -00000000 T USART_PutChar -00000000 T USART_Read -00000000 T USART_ReadBuffer -00000000 T USART_SetIrdaFilter -00000000 T USART_SetReceiverEnabled -00000000 T USART_SetTransmitterEnabled -00000000 T USART_Write -00000000 T USART_WriteBuffer - U __assert_func -00000000 r __func__.3477 - -wdt.o: -00000000 T WDT_Disable -00000000 T WDT_Enable -00000000 T WDT_GetPeriod -00000000 T WDT_GetStatus -00000000 T WDT_Restart - -system_sam3xa.o: -00000000 D SystemCoreClock -00000000 T SystemCoreClockUpdate -00000000 T SystemInit -00000000 T system_init_flash - -startup_sam3xa.o: -00000000 W ADC_Handler -00000000 W BusFault_Handler -00000000 W CAN0_Handler -00000000 W CAN1_Handler -00000000 W DACC_Handler -00000000 W DMAC_Handler -00000000 W DebugMon_Handler -00000000 T Dummy_Handler -00000000 W EFC0_Handler -00000000 W EFC1_Handler -00000000 W EMAC_Handler -00000000 W HSMCI_Handler -00000000 W HardFault_Handler -00000000 W MemManage_Handler -00000000 W NMI_Handler -00000000 W PIOA_Handler -00000000 W PIOB_Handler -00000000 W PIOC_Handler -00000000 W PIOD_Handler -00000000 W PMC_Handler -00000000 W PWM_Handler -00000000 W PendSV_Handler -00000000 W RSTC_Handler -00000000 W RTC_Handler -00000000 W RTT_Handler -00000000 T Reset_Handler -00000000 W SMC_Handler -00000000 W SPI0_Handler -00000000 W SSC_Handler -00000000 W SUPC_Handler -00000000 W SVC_Handler -00000000 W SysTick_Handler -00000000 W TC0_Handler -00000000 W TC1_Handler -00000000 W TC2_Handler -00000000 W TC3_Handler -00000000 W TC4_Handler -00000000 W TC5_Handler -00000000 W TC6_Handler -00000000 W TC7_Handler -00000000 W TC8_Handler -00000000 W TRNG_Handler -00000000 W TWI0_Handler -00000000 W TWI1_Handler -00000000 W UART_Handler -00000000 W UOTGHS_Handler -00000000 W USART0_Handler -00000000 W USART1_Handler -00000000 W USART2_Handler -00000000 W USART3_Handler -00000000 W UsageFault_Handler -00000000 W WDT_Handler - U __libc_init_array - U _erelocate - U _estack - U _etext - U _ezero - U _sfixed - U _srelocate - U _szero -00000000 R exception_table - U main diff --git a/hardware/arduino/sam/cores/arduino/wiring_analog.c b/hardware/arduino/sam/cores/arduino/wiring_analog.c index 3d5c0ce70..d5bf6dd2b 100644 --- a/hardware/arduino/sam/cores/arduino/wiring_analog.c +++ b/hardware/arduino/sam/cores/arduino/wiring_analog.c @@ -193,6 +193,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 fa0f9eb40..10032f4f3 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 00960209f..a36253ea4 100644 Binary files a/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a and b/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a differ 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 7447be8ba..1ed7a440f 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 @@ -72,6 +72,7 @@ pmc.o: 00000000 T pmc_switch_udpck_to_upllck pwmc.o: +00000000 r C.9.7204 00000000 t FindClockConfiguration 00000000 T PWMC_ConfigureChannel 00000000 T PWMC_ConfigureChannelExt @@ -99,14 +100,14 @@ pwmc.o: 00000000 T PWMC_SetSyncChannelUpdateUnlock 00000000 T PWMC_WriteBuffer U __assert_func -00000000 r __func__.3192 -00000000 r __func__.3203 -00000000 r __func__.3218 -00000000 r __func__.3229 -00000000 r __func__.3240 -00000000 r __func__.3247 -00000000 r __func__.3331 -00000000 r __func__.3337 +00000000 r __func__.5914 +00000000 r __func__.5925 +00000000 r __func__.5940 +00000000 r __func__.5951 +00000000 r __func__.5962 +00000000 r __func__.5969 +00000000 r __func__.6053 +00000000 r __func__.6059 rtc.o: 00000000 T RTC_ClearSCCR @@ -122,9 +123,9 @@ rtc.o: 00000000 T RTC_SetTime 00000000 T RTC_SetTimeAlarm U __assert_func -00000000 r __func__.3189 -00000000 r __func__.3198 -00000000 r __func__.3203 +00000000 r __func__.5911 +00000000 r __func__.5920 +00000000 r __func__.5925 rtt.o: 00000000 T RTT_EnableIT @@ -133,8 +134,8 @@ rtt.o: 00000000 T RTT_SetAlarm 00000000 T RTT_SetPrescaler U __assert_func -00000000 r __func__.3196 -00000000 r __func__.3204 +00000000 r __func__.5918 +00000000 r __func__.5926 spi.o: 00000000 T SPI_Configure @@ -155,9 +156,9 @@ tc.o: 00000000 T TC_Start 00000000 T TC_Stop U __assert_func -00000000 r __func__.3191 -00000000 r __func__.3197 -00000000 r __func__.3203 +00000000 r __func__.5913 +00000000 r __func__.5919 +00000000 r __func__.5925 timetick.o: 00000000 T GetTickCount @@ -184,18 +185,18 @@ twi.o: 00000000 T TWI_TransferComplete 00000000 T TWI_WriteByte U __assert_func -00000000 r __func__.3556 -00000000 r __func__.3571 -00000000 r __func__.3575 -00000000 r __func__.3582 -00000000 r __func__.3586 -00000000 r __func__.3591 -00000000 r __func__.3599 -00000000 r __func__.3613 -00000000 r __func__.3618 -00000000 r __func__.3622 -00000000 r __func__.3627 -00000000 r __func__.3631 +00000000 r __func__.6286 +00000000 r __func__.6301 +00000000 r __func__.6305 +00000000 r __func__.6312 +00000000 r __func__.6316 +00000000 r __func__.6321 +00000000 r __func__.6329 +00000000 r __func__.6343 +00000000 r __func__.6348 +00000000 r __func__.6352 +00000000 r __func__.6357 +00000000 r __func__.6361 usart.o: 00000000 T USART_Configure @@ -214,7 +215,7 @@ usart.o: 00000000 T USART_Write 00000000 T USART_WriteBuffer U __assert_func -00000000 r __func__.3477 +00000000 r __func__.6207 wdt.o: 00000000 T WDT_Disable @@ -379,3 +380,26 @@ uotghs.o: interrupt_sam_nvic.o: 00000000 D g_interrupt_enabled + +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 2ba898ca0..a99f7807a 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.h +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.h @@ -161,10 +161,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