SAMV71 Xplained Ultra Software Package 1.5

dac_dma.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \addtogroup dacc_module Working with DACC
00031  *  \ingroup peripherals_module
00032  * The DACC driver provides the interface to configure and use the DACC
00033  * peripheral.\n
00034  *
00035  * The DACC(Digital-to-Analog Converter Controller) converts digital code to
00036  * analog output.
00037  * The data to be converted are sent in a common register for all channels.
00038  * It offers up to 2 analog outputs.The output voltage ranges from (1/6)ADVREF
00039  * to (5/6)ADVREF.
00040  *
00041  * To Enable a DACC conversion,the user has to follow these few steps:
00042  * <ul>
00043  * <li> Select an appropriate reference voltage on ADVREF   </li>
00044  * <li> Configure the DACC according to its requirements and special needs,
00045  * which could be broken down into several parts:
00046  * -#   Enable DACC in free running mode by clearing TRGEN in DACC_MR;
00047  * -#   Configure Refresh Period through setting REFRESH fields
00048  *      in DACC_MR; The refresh mechanism is used to protect the output analog
00049  * value from
00050  *      decreasing.
00051  * -#   Enable channels and write digital code to DACC_CDR,in free running mode,
00052  * the conversion is started right after at least one channel is enabled and
00053  * data is written .
00054  </li>
00055  * </ul>
00056  *
00057  * For more accurate information, please look at the DACC section of the
00058  * Datasheet.
00059  *
00060  * Related files :\n
00061  * \ref dac_dma.c\n
00062  * \ref dac_dma.h\n
00063  */
00064 /*@{*/
00065 /*@}*/
00066 /**
00067  * \file
00068  *
00069  * Implementation of Digital-to-Analog Converter Controller (DACC).
00070  *
00071  */
00072 
00073 /*----------------------------------------------------------------------------
00074  *        Headers
00075  *----------------------------------------------------------------------------*/
00076 
00077 #include "chip.h"
00078 
00079 #include <stdint.h>
00080 #include <assert.h>
00081 
00082 /*  DMA driver instance */
00083 static uint32_t dacDmaTxChannel;
00084 static LinkedListDescriporView1 dmaWriteLinkList[256];
00085 /*----------------------------------------------------------------------------
00086  *        Local functions
00087  *----------------------------------------------------------------------------*/
00088 
00089 /**
00090  * \brief Configure the DMA Channels: 0 RX.
00091  * Channels are disabled after configure.
00092  * \returns 0 if the dma channel configuration successfully; otherwise returns
00093  * DAC_ERROR_XXX.
00094  */
00095 static uint8_t _DacConfigureDmaChannels(DacDma *pDacd)
00096 {
00097 
00098     /* Driver initialize */
00099     XDMAD_Initialize(pDacd->pXdmad, 0);
00100 
00101     XDMAD_FreeChannel(pDacd->pXdmad, dacDmaTxChannel);
00102 
00103     /* Allocate a DMA channel for DAC0/1 TX. */
00104     dacDmaTxChannel =
00105         XDMAD_AllocateChannel(pDacd->pXdmad, XDMAD_TRANSFER_MEMORY, ID_DACC);
00106 
00107     if (dacDmaTxChannel == XDMAD_ALLOC_FAILED)
00108         return DAC_ERROR;
00109 
00110     if (XDMAD_PrepareChannel(pDacd->pXdmad, dacDmaTxChannel))
00111         return DAC_ERROR;
00112 
00113     return DAC_OK;
00114 }
00115 
00116 
00117 /**
00118  * \brief Configure the DMA source and destination with Linker List mode.
00119  *
00120  * \param pBuffer Pointer to dac buffer
00121  * \param size length of buffer
00122  */
00123 
00124 static uint8_t _Dac_configureLinkList(Dacc *pDacHw, void *pXdmad,
00125                                       DacCmd *pCommand)
00126 {
00127     uint32_t xdmaCndc;
00128     sXdmadCfg xdmadCfg;
00129     uint32_t *pBuffer;
00130     /* Setup TX Link List */
00131     uint8_t i;
00132     pBuffer = (uint32_t *)pCommand->pTxBuff;
00133 
00134     for (i = 0; i < pCommand->TxSize; i++) {
00135         dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
00136                                       | XDMA_UBC_NDE_FETCH_EN
00137                                       | XDMA_UBC_NSEN_UPDATED
00138                                       | XDMAC_CUBC_UBLEN(4);
00139         dmaWriteLinkList[i].mbr_sa = (uint32_t)pBuffer;
00140         dmaWriteLinkList[i].mbr_da =
00141             (uint32_t) & (pDacHw->DACC_CDR[pCommand->dacChannel]);
00142 
00143         if (i == (pCommand->TxSize - 1)) {
00144             if (pCommand->loopback)
00145                 dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
00146             else
00147                 dmaWriteLinkList[i].mbr_nda = 0;
00148         } else
00149             dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i + 1];
00150 
00151         pBuffer++;
00152     }
00153 
00154     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00155                        | XDMAC_CC_MBSIZE_SINGLE
00156                        | XDMAC_CC_DSYNC_MEM2PER
00157                        | XDMAC_CC_CSIZE_CHK_1
00158                        | XDMAC_CC_DWIDTH_WORD
00159                        | XDMAC_CC_SIF_AHB_IF1
00160                        | XDMAC_CC_DIF_AHB_IF1
00161                        | XDMAC_CC_SAM_INCREMENTED_AM
00162                        | XDMAC_CC_DAM_FIXED_AM
00163                        | XDMAC_CC_PERID(
00164                             XDMAIF_Get_ChannelNumber(ID_DACC, XDMAD_TRANSFER_TX));
00165     xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
00166                | XDMAC_CNDC_NDE_DSCR_FETCH_EN
00167                | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00168                | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
00169     XDMAD_ConfigureTransfer(pXdmad, dacDmaTxChannel, &xdmadCfg, xdmaCndc,
00170                              (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE);
00171     return DAC_OK;
00172 }
00173 
00174 /*----------------------------------------------------------------------------
00175  *        Exported functions
00176  *----------------------------------------------------------------------------*/
00177 /**
00178  * \brief Initializes the DacDma structure and the corresponding DAC & DMA .
00179  * hardware select value.
00180  * The driver will uses DMA channel 0 for RX .
00181  * The DMA channels are freed automatically when no DMA command processing.
00182  *
00183  * \param pDacd  Pointer to a DacDma instance.
00184  * \param pDacHw Associated Dac peripheral.
00185  * \param DacId  Dac peripheral identifier.
00186  * \param pDmad  Pointer to a Dmad instance.
00187  */
00188 uint32_t Dac_ConfigureDma(DacDma *pDacd ,
00189                            Dacc *pDacHw ,
00190                            uint8_t DacId,
00191                            sXdmad *pXdmad)
00192 {
00193     /* Initialize the Dac structure */
00194     pDacd->pDacHw = pDacHw;
00195     pDacd->dacId  = DacId;
00196     pDacd->semaphore = 1;
00197     pDacd->pCurrentCommand = 0;
00198     pDacd->pXdmad = pXdmad;
00199     return 0;
00200 }
00201 
00202 /**
00203  * \brief Starts a DAC transfer. This is a non blocking function. It will
00204  *  return as soon as the transfer is started.
00205  *
00206  * \param pDacd  Pointer to a DacDma instance.
00207  * \param pCommand Pointer to the Dac command to execute.
00208  * \returns 0 if the transfer has been started successfully; otherwise returns
00209  * DAC_ERROR_LOCK is the driver is in use, or DAC_ERROR if the command is not
00210  * valid.
00211  */
00212 uint32_t Dac_SendData(DacDma *pDacd, DacCmd *pCommand)
00213 {
00214     Dacc *pDacHw = pDacd->pDacHw;
00215 
00216     /* Try to get the dataflash semaphore */
00217     if (pDacd->semaphore == 0)
00218         return DAC_ERROR_LOCK;
00219 
00220     pDacd->semaphore--;
00221 
00222     // Initialize the callback
00223     pDacd->pCurrentCommand = pCommand;
00224 
00225     /* Initialize DMA controller using channel 0 for RX. */
00226     if (_DacConfigureDmaChannels(pDacd))
00227         return DAC_ERROR_LOCK;
00228 
00229     if (_Dac_configureLinkList(pDacHw, pDacd->pXdmad, pCommand))
00230         return DAC_ERROR_LOCK;
00231 
00232     SCB_CleanDCache();
00233 
00234     /* Start DMA TX */
00235     if (XDMAD_StartTransfer(pDacd->pXdmad, dacDmaTxChannel))
00236         return DAC_ERROR_LOCK;
00237 
00238     return DAC_OK;;
00239 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines