mirror of
https://github.com/arduino/Arduino.git
synced 2024-12-04 15:24:12 +01:00
184 lines
6.2 KiB
C
184 lines
6.2 KiB
C
/* ----------------------------------------------------------------------------
|
|
* ATMEL Microcontroller Software Support
|
|
* ----------------------------------------------------------------------------
|
|
* Copyright (c) 2009, Atmel Corporation
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are 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.
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
/** \addtogroup dacc_module Working with DACC
|
|
* The DACC driver provides the interface to configure and use the DACC peripheral.\n
|
|
*
|
|
* The DACC(Digital-to-Analog Converter Controller) converts digital code to analog output.
|
|
* The data to be converted are sent in a common register for all channels. It offers up to 2
|
|
* analog outputs.The output voltage ranges from (1/6)ADVREF to (5/6)ADVREF.
|
|
*
|
|
* To Enable a DACC conversion,the user has to follow these few steps:
|
|
* <ul>
|
|
* <li> Select an appropriate reference voltage on ADVREF </li>
|
|
* <li> Configure the DACC according to its requirements and special needs,which could be
|
|
broken down into several parts:
|
|
* -# Enable DACC in free running mode by clearing TRGEN in DACC_MR;
|
|
* -# Configure Startup Time and Refresh Period through setting STARTUP and REFRESH fields
|
|
* in DACC_MR; The refresh mechanism is used to protect the output analog value from
|
|
* decreasing.
|
|
* -# Enable channels and write digital code to DACC_CDR,in free running mode, the conversion
|
|
* is started right after at least one channel is enabled and data is written .
|
|
</li>
|
|
* </ul>
|
|
*
|
|
* For more accurate information, please look at the DACC section of the
|
|
* Datasheet.
|
|
*
|
|
* Related files :\n
|
|
* \ref DACC.c\n
|
|
* \ref DACC.h\n
|
|
*/
|
|
/*@{*/
|
|
/*@}*/
|
|
/**
|
|
* \file
|
|
*
|
|
* Implementation of Digital-to-Analog Converter Controller (DACC).
|
|
*
|
|
*/
|
|
/*----------------------------------------------------------------------------
|
|
* Headers
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
#include "chip.h"
|
|
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Exported functions
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* \brief Initialize the DACC controller
|
|
* \param pDACC Pointer to an DACC instance.
|
|
* \param idDACC identifier of DAC peripheral
|
|
* \param trgEn trigger mode, free running mode or external Hardware trigger
|
|
* \param word transfer size,word or half word
|
|
* \param trgSel hardware trigger selection
|
|
* \param sleepMode sleep mode selection
|
|
* \param mck value of MCK in Hz
|
|
* \param refresh refresh period
|
|
* \param user_sel user channel selection ,0 or 1
|
|
* \param tag_mode tag for channel number
|
|
* \param startup value of the start up time (in DACCClock) (see datasheet)
|
|
*/
|
|
extern void DACC_Initialize( Dacc* pDACC,
|
|
uint8_t idDACC,
|
|
uint8_t trgEn,
|
|
uint8_t trgSel,
|
|
uint8_t word,
|
|
uint8_t sleepMode,
|
|
uint32_t mck,
|
|
uint8_t refresh, /* refresh period */
|
|
uint8_t user_sel, /* user channel selection */
|
|
uint32_t tag_mode, /* using tag for channel number */
|
|
uint32_t startup
|
|
)
|
|
{
|
|
assert( 1024*refresh*1000/(mck>>1) < 20 ) ;
|
|
|
|
/* Enable peripheral clock*/
|
|
PMC->PMC_PCER0 = 1 << idDACC;
|
|
|
|
/* Reset the controller */
|
|
DACC_SoftReset(pDACC);
|
|
|
|
/* Write to the MR register */
|
|
DACC_CfgModeReg( pDACC,
|
|
( (trgEn<<0) & DACC_MR_TRGEN)
|
|
| DACC_MR_TRGSEL(trgSel)
|
|
| ( (word<<4) & DACC_MR_WORD)
|
|
| ( (sleepMode<<5) & DACC_MR_SLEEP)
|
|
| DACC_MR_REFRESH(refresh)
|
|
| ( (user_sel<<DACC_MR_USER_SEL_Pos)& DACC_MR_USER_SEL_Msk)
|
|
| ( (tag_mode<<20) & DACC_MR_TAG)
|
|
| ( (startup<<DACC_MR_STARTUP_Pos) & DACC_MR_STARTUP_Msk));
|
|
}
|
|
|
|
|
|
/**
|
|
* Set the Conversion Data
|
|
* \param pDACC Pointer to an Dacc instance.
|
|
* \param data date to be converted.
|
|
*/
|
|
extern void DACC_SetConversionData( Dacc* pDACC, uint32_t dwData )
|
|
{
|
|
uint32_t dwMR = pDACC->DACC_MR ;
|
|
|
|
if ( dwMR & DACC_MR_WORD )
|
|
{
|
|
pDACC->DACC_CDR = dwData ;
|
|
}
|
|
else
|
|
{
|
|
pDACC->DACC_CDR = (dwData&0xFFFF) ;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* \brief Write converted data through PDC channel
|
|
* \param pDACC the pointer of DACC peripheral
|
|
* \param pBuffer the destination buffer
|
|
* \param size the size of the buffer
|
|
*/
|
|
extern uint32_t DACC_WriteBuffer( Dacc* pDACC, uint16_t *pwBuffer, uint32_t dwSize )
|
|
{
|
|
|
|
/* Check if the first PDC bank is free*/
|
|
if ( (pDACC->DACC_TCR == 0) && (pDACC->DACC_TNCR == 0) )
|
|
{
|
|
pDACC->DACC_TPR = (uint32_t)pwBuffer ;
|
|
pDACC->DACC_TCR = dwSize ;
|
|
pDACC->DACC_PTCR = DACC_PTCR_TXTEN ;
|
|
|
|
return 1 ;
|
|
}
|
|
/* Check if the second PDC bank is free*/
|
|
else
|
|
{
|
|
if (pDACC->DACC_TNCR == 0)
|
|
{
|
|
pDACC->DACC_TNPR = (uint32_t)pwBuffer ;
|
|
pDACC->DACC_TNCR = dwSize ;
|
|
|
|
return 1 ;
|
|
}
|
|
else
|
|
{
|
|
return 0 ;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|