source: rtems/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/dac_dma.c @ e1eeb883

5
Last change on this file since e1eeb883 was e1eeb883, checked in by Sebastian Huber <sebastian.huber@…>, on 01/12/16 at 14:34:31

bsp/atsam: Import SAM Software Package

Import selected files of the "SAM V71 / V70 / E70 / S70 Software
Package" obtained from the "SAMV71-XULT GNU Software Package 1.5".

Converted files via dos2unix before import.

Update #2529.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1/* ---------------------------------------------------------------------------- */
2/*                  Atmel Microcontroller Software Support                      */
3/*                       SAM Software Package License                           */
4/* ---------------------------------------------------------------------------- */
5/* Copyright (c) 2015, Atmel Corporation                                        */
6/*                                                                              */
7/* All rights reserved.                                                         */
8/*                                                                              */
9/* Redistribution and use in source and binary forms, with or without           */
10/* modification, are permitted provided that the following condition is met:    */
11/*                                                                              */
12/* - Redistributions of source code must retain the above copyright notice,     */
13/* this list of conditions and the disclaimer below.                            */
14/*                                                                              */
15/* Atmel's name may not be used to endorse or promote products derived from     */
16/* this software without specific prior written permission.                     */
17/*                                                                              */
18/* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
19/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
20/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
21/* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
22/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
23/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
24/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
25/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
26/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
27/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
28/* ---------------------------------------------------------------------------- */
29
30/** \addtogroup dacc_module Working with DACC
31 *  \ingroup peripherals_module
32 * The DACC driver provides the interface to configure and use the DACC
33 * peripheral.\n
34 *
35 * The DACC(Digital-to-Analog Converter Controller) converts digital code to
36 * analog output.
37 * The data to be converted are sent in a common register for all channels.
38 * It offers up to 2 analog outputs.The output voltage ranges from (1/6)ADVREF
39 * to (5/6)ADVREF.
40 *
41 * To Enable a DACC conversion,the user has to follow these few steps:
42 * <ul>
43 * <li> Select an appropriate reference voltage on ADVREF   </li>
44 * <li> Configure the DACC according to its requirements and special needs,
45 * which could be broken down into several parts:
46 * -#   Enable DACC in free running mode by clearing TRGEN in DACC_MR;
47 * -#   Configure Refresh Period through setting REFRESH fields
48 *      in DACC_MR; The refresh mechanism is used to protect the output analog
49 * value from
50 *      decreasing.
51 * -#   Enable channels and write digital code to DACC_CDR,in free running mode,
52 * the conversion is started right after at least one channel is enabled and
53 * data is written .
54 </li>
55 * </ul>
56 *
57 * For more accurate information, please look at the DACC section of the
58 * Datasheet.
59 *
60 * Related files :\n
61 * \ref dac_dma.c\n
62 * \ref dac_dma.h\n
63 */
64/*@{*/
65/*@}*/
66/**
67 * \file
68 *
69 * Implementation of Digital-to-Analog Converter Controller (DACC).
70 *
71 */
72
73/*----------------------------------------------------------------------------
74 *        Headers
75 *----------------------------------------------------------------------------*/
76
77#include "chip.h"
78
79#include <stdint.h>
80#include <assert.h>
81
82/*  DMA driver instance */
83static uint32_t dacDmaTxChannel;
84static LinkedListDescriporView1 dmaWriteLinkList[256];
85/*----------------------------------------------------------------------------
86 *        Local functions
87 *----------------------------------------------------------------------------*/
88
89/**
90 * \brief Configure the DMA Channels: 0 RX.
91 * Channels are disabled after configure.
92 * \returns 0 if the dma channel configuration successfully; otherwise returns
93 * DAC_ERROR_XXX.
94 */
95static uint8_t _DacConfigureDmaChannels(DacDma *pDacd)
96{
97
98        /* Driver initialize */
99        XDMAD_Initialize(pDacd->pXdmad, 0);
100
101        XDMAD_FreeChannel(pDacd->pXdmad, dacDmaTxChannel);
102
103        /* Allocate a DMA channel for DAC0/1 TX. */
104        dacDmaTxChannel =
105                XDMAD_AllocateChannel(pDacd->pXdmad, XDMAD_TRANSFER_MEMORY, ID_DACC);
106
107        if (dacDmaTxChannel == XDMAD_ALLOC_FAILED)
108                return DAC_ERROR;
109
110        if (XDMAD_PrepareChannel(pDacd->pXdmad, dacDmaTxChannel))
111                return DAC_ERROR;
112
113        return DAC_OK;
114}
115
116
117/**
118 * \brief Configure the DMA source and destination with Linker List mode.
119 *
120 * \param pBuffer Pointer to dac buffer
121 * \param size length of buffer
122 */
123
124static uint8_t _Dac_configureLinkList(Dacc *pDacHw, void *pXdmad,
125                                                                          DacCmd *pCommand)
126{
127        uint32_t xdmaCndc;
128        sXdmadCfg xdmadCfg;
129        uint32_t *pBuffer;
130        /* Setup TX Link List */
131        uint8_t i;
132        pBuffer = (uint32_t *)pCommand->pTxBuff;
133
134        for (i = 0; i < pCommand->TxSize; i++) {
135                dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
136                                                                          | XDMA_UBC_NDE_FETCH_EN
137                                                                          | XDMA_UBC_NSEN_UPDATED
138                                                                          | XDMAC_CUBC_UBLEN(4);
139                dmaWriteLinkList[i].mbr_sa = (uint32_t)pBuffer;
140                dmaWriteLinkList[i].mbr_da =
141                        (uint32_t) & (pDacHw->DACC_CDR[pCommand->dacChannel]);
142
143                if (i == (pCommand->TxSize - 1)) {
144                        if (pCommand->loopback)
145                                dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
146                        else
147                                dmaWriteLinkList[i].mbr_nda = 0;
148                } else
149                        dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i + 1];
150
151                pBuffer++;
152        }
153
154        xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
155                                           | XDMAC_CC_MBSIZE_SINGLE
156                                           | XDMAC_CC_DSYNC_MEM2PER
157                                           | XDMAC_CC_CSIZE_CHK_1
158                                           | XDMAC_CC_DWIDTH_WORD
159                                           | XDMAC_CC_SIF_AHB_IF1
160                                           | XDMAC_CC_DIF_AHB_IF1
161                                           | XDMAC_CC_SAM_INCREMENTED_AM
162                                           | XDMAC_CC_DAM_FIXED_AM
163                                           | XDMAC_CC_PERID(
164                                                        XDMAIF_Get_ChannelNumber(ID_DACC, XDMAD_TRANSFER_TX));
165        xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
166                           | XDMAC_CNDC_NDE_DSCR_FETCH_EN
167                           | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
168                           | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
169        XDMAD_ConfigureTransfer(pXdmad, dacDmaTxChannel, &xdmadCfg, xdmaCndc,
170                                                         (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE);
171        return DAC_OK;
172}
173
174/*----------------------------------------------------------------------------
175 *        Exported functions
176 *----------------------------------------------------------------------------*/
177/**
178 * \brief Initializes the DacDma structure and the corresponding DAC & DMA .
179 * hardware select value.
180 * The driver will uses DMA channel 0 for RX .
181 * The DMA channels are freed automatically when no DMA command processing.
182 *
183 * \param pDacd  Pointer to a DacDma instance.
184 * \param pDacHw Associated Dac peripheral.
185 * \param DacId  Dac peripheral identifier.
186 * \param pDmad  Pointer to a Dmad instance.
187 */
188uint32_t Dac_ConfigureDma(DacDma *pDacd ,
189                                                   Dacc *pDacHw ,
190                                                   uint8_t DacId,
191                                                   sXdmad *pXdmad)
192{
193        /* Initialize the Dac structure */
194        pDacd->pDacHw = pDacHw;
195        pDacd->dacId  = DacId;
196        pDacd->semaphore = 1;
197        pDacd->pCurrentCommand = 0;
198        pDacd->pXdmad = pXdmad;
199        return 0;
200}
201
202/**
203 * \brief Starts a DAC transfer. This is a non blocking function. It will
204 *  return as soon as the transfer is started.
205 *
206 * \param pDacd  Pointer to a DacDma instance.
207 * \param pCommand Pointer to the Dac command to execute.
208 * \returns 0 if the transfer has been started successfully; otherwise returns
209 * DAC_ERROR_LOCK is the driver is in use, or DAC_ERROR if the command is not
210 * valid.
211 */
212uint32_t Dac_SendData(DacDma *pDacd, DacCmd *pCommand)
213{
214        Dacc *pDacHw = pDacd->pDacHw;
215
216        /* Try to get the dataflash semaphore */
217        if (pDacd->semaphore == 0)
218                return DAC_ERROR_LOCK;
219
220        pDacd->semaphore--;
221
222        // Initialize the callback
223        pDacd->pCurrentCommand = pCommand;
224
225        /* Initialize DMA controller using channel 0 for RX. */
226        if (_DacConfigureDmaChannels(pDacd))
227                return DAC_ERROR_LOCK;
228
229        if (_Dac_configureLinkList(pDacHw, pDacd->pXdmad, pCommand))
230                return DAC_ERROR_LOCK;
231
232        SCB_CleanDCache();
233
234        /* Start DMA TX */
235        if (XDMAD_StartTransfer(pDacd->pXdmad, dacDmaTxChannel))
236                return DAC_ERROR_LOCK;
237
238        return DAC_OK;;
239}
Note: See TracBrowser for help on using the repository browser.