source: rtems/bsps/arm/atsam/contrib/libraries/libchip/source/dac_dma.c @ 54aabb7

5
Last change on this file since 54aabb7 was 54aabb7, checked in by Sebastian Huber <sebastian.huber@…>, on 04/22/18 at 13:11:43

bsp/atsam: Move libraries to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • 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_FreeChannel(pDacd->pXdmad, dacDmaTxChannel);
100
101        /* Allocate a DMA channel for DAC0/1 TX. */
102        dacDmaTxChannel =
103                XDMAD_AllocateChannel(pDacd->pXdmad, XDMAD_TRANSFER_MEMORY, ID_DACC);
104
105        if (dacDmaTxChannel == XDMAD_ALLOC_FAILED)
106                return DAC_ERROR;
107
108        if (XDMAD_PrepareChannel(pDacd->pXdmad, dacDmaTxChannel))
109                return DAC_ERROR;
110
111        return DAC_OK;
112}
113
114
115/**
116 * \brief Configure the DMA source and destination with Linker List mode.
117 *
118 * \param pBuffer Pointer to dac buffer
119 * \param size length of buffer
120 */
121
122static uint8_t _Dac_configureLinkList(Dacc *pDacHw, void *pXdmad,
123                                                                          DacCmd *pCommand)
124{
125        uint32_t xdmaCndc;
126        sXdmadCfg xdmadCfg;
127        uint32_t *pBuffer;
128        /* Setup TX Link List */
129        uint8_t i;
130        pBuffer = (uint32_t *)pCommand->pTxBuff;
131
132        for (i = 0; i < pCommand->TxSize; i++) {
133                dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
134                                                                          | XDMA_UBC_NDE_FETCH_EN
135                                                                          | XDMA_UBC_NSEN_UPDATED
136                                                                          | XDMAC_CUBC_UBLEN(4);
137                dmaWriteLinkList[i].mbr_sa = (uint32_t)pBuffer;
138                dmaWriteLinkList[i].mbr_da =
139                        (uint32_t) & (pDacHw->DACC_CDR[pCommand->dacChannel]);
140
141                if (i == (pCommand->TxSize - 1)) {
142                        if (pCommand->loopback)
143                                dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
144                        else
145                                dmaWriteLinkList[i].mbr_nda = 0;
146                } else
147                        dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i + 1];
148
149                pBuffer++;
150        }
151
152        xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
153                                           | XDMAC_CC_MBSIZE_SINGLE
154                                           | XDMAC_CC_DSYNC_MEM2PER
155                                           | XDMAC_CC_CSIZE_CHK_1
156                                           | XDMAC_CC_DWIDTH_WORD
157                                           | XDMAC_CC_SIF_AHB_IF1
158                                           | XDMAC_CC_DIF_AHB_IF1
159                                           | XDMAC_CC_SAM_INCREMENTED_AM
160                                           | XDMAC_CC_DAM_FIXED_AM
161                                           | XDMAC_CC_PERID(
162                                                        XDMAIF_Get_ChannelNumber(ID_DACC, XDMAD_TRANSFER_TX));
163        xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
164                           | XDMAC_CNDC_NDE_DSCR_FETCH_EN
165                           | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
166                           | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
167        XDMAD_ConfigureTransfer(pXdmad, dacDmaTxChannel, &xdmadCfg, xdmaCndc,
168                                                         (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE);
169        return DAC_OK;
170}
171
172/*----------------------------------------------------------------------------
173 *        Exported functions
174 *----------------------------------------------------------------------------*/
175/**
176 * \brief Initializes the DacDma structure and the corresponding DAC & DMA .
177 * hardware select value.
178 * The driver will uses DMA channel 0 for RX .
179 * The DMA channels are freed automatically when no DMA command processing.
180 *
181 * \param pDacd  Pointer to a DacDma instance.
182 * \param pDacHw Associated Dac peripheral.
183 * \param DacId  Dac peripheral identifier.
184 * \param pDmad  Pointer to a Dmad instance.
185 */
186uint32_t Dac_ConfigureDma(DacDma *pDacd ,
187                                                   Dacc *pDacHw ,
188                                                   uint8_t DacId,
189                                                   sXdmad *pXdmad)
190{
191        /* Initialize the Dac structure */
192        pDacd->pDacHw = pDacHw;
193        pDacd->dacId  = DacId;
194        pDacd->semaphore = 1;
195        pDacd->pCurrentCommand = 0;
196        assert(pXdmad == &XDMAD_Instance);
197        pDacd->pXdmad = pXdmad;
198        return 0;
199}
200
201/**
202 * \brief Starts a DAC transfer. This is a non blocking function. It will
203 *  return as soon as the transfer is started.
204 *
205 * \param pDacd  Pointer to a DacDma instance.
206 * \param pCommand Pointer to the Dac command to execute.
207 * \returns 0 if the transfer has been started successfully; otherwise returns
208 * DAC_ERROR_LOCK is the driver is in use, or DAC_ERROR if the command is not
209 * valid.
210 */
211uint32_t Dac_SendData(DacDma *pDacd, DacCmd *pCommand)
212{
213        Dacc *pDacHw = pDacd->pDacHw;
214
215        /* Try to get the dataflash semaphore */
216        if (pDacd->semaphore == 0)
217                return DAC_ERROR_LOCK;
218
219        pDacd->semaphore--;
220
221        // Initialize the callback
222        pDacd->pCurrentCommand = pCommand;
223
224        /* Initialize DMA controller using channel 0 for RX. */
225        if (_DacConfigureDmaChannels(pDacd))
226                return DAC_ERROR_LOCK;
227
228        if (_Dac_configureLinkList(pDacHw, pDacd->pXdmad, pCommand))
229                return DAC_ERROR_LOCK;
230
231        SCB_CleanDCache();
232
233        /* Start DMA TX */
234        if (XDMAD_StartTransfer(pDacd->pXdmad, dacDmaTxChannel))
235                return DAC_ERROR_LOCK;
236
237        return DAC_OK;;
238}
Note: See TracBrowser for help on using the repository browser.