SAMV71 Xplained Ultra Software Package 1.5

main.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 /**
00031  *  \page xdma XDMA example
00032  *
00033  *  \section Purpose
00034  *
00035  *  The xdma example will help new users get familiar with Atmel's
00036  *  SAMV7 family of microcontrollers's XDMA peripheral.
00037  *
00038  *  \section Requirements
00039  *
00040  *  This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board.
00041  *
00042  *  \section Description
00043  *
00044  *  This example proposes different configuration possible by XDMA and after
00045  *  configuring it user
00046  *  can start memory to memory transfer.
00047  *  Memory transfer result varies according to configuration
00048  *
00049  *  \section Usage
00050  *
00051  *  -# Build the program and download it inside the board.
00052  *  Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00053  *  -# On the computer, open and configure a terminal application
00054  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00055  *    - 115200 baud rate
00056  *    - 8 bits of data
00057  *    - No parity
00058  *    - 1 stop bit
00059  *    - No flow control
00060  *  -# Start the application.
00061  *  -# The following text should appear (values depend on the board and chip used):
00062  *     \code
00063  *      -- XDMA example xxx --
00064  *      -- xxxxxx-xx
00065  *      -- Compiled: xxx xx xxxx xx:xx:xx --
00066  *     \endcode
00067  *
00068  *  \section References
00069  *  - xdma/main.c
00070  *  - xdmac.c
00071  *  - xdmad.c
00072  *  - xdma_hardware_interface.c
00073  */
00074 
00075 
00076 /** \file
00077  *
00078  *  This file contains all the specific code for the DMA example.
00079  *
00080  */
00081 
00082 
00083 /*----------------------------------------------------------------------------
00084  *        Headers
00085  *----------------------------------------------------------------------------*/
00086 
00087 #include <board.h>
00088 #include <string.h>
00089 
00090 /*----------------------------------------------------------------------------
00091  *         Local constants
00092  *----------------------------------------------------------------------------*/
00093 #define XDMA_SINGLE          1
00094 #define XDMA_MULTI           2
00095 #define XDMA_LLI             3
00096 
00097 /** Maximum size of Linked List Item  in this example*/
00098 #define MAX_LLI_SIZE         2
00099 /** Micro-block length for single transfer  */
00100 #define MICROBLOCK_LEN       16
00101 /** Buffer length */
00102 #define BUFFER_LEN         128
00103 /** Polling or interrupt mode */
00104 #define POLLING_MODE   0
00105 
00106 /*----------------------------------------------------------------------------
00107  *        Local variables
00108  *----------------------------------------------------------------------------*/
00109 /** Global DMA driver instance for all DMA transfers in application. */
00110 static sXdmad xdmad;
00111 static sXdmadCfg xdmadCfg;
00112 
00113 /** TX descriptors list */
00114 COMPILER_ALIGNED(32) static LinkedListDescriporView1 LLIview1[MAX_LLI_SIZE];
00115 
00116 /* DMA driver instance */
00117 static uint32_t dmaChannel;
00118 
00119 
00120 COMPILER_ALIGNED(32) static uint8_t sourceBuffer[512];
00121 
00122 COMPILER_ALIGNED(32) static uint8_t destinationBuffer[512];
00123 
00124 /* Current Programming DMAC mode for Multiple Buffer Transfers */
00125 static uint8_t dmaProgrammingMode = 0;
00126 static uint8_t ConfigFlag = 0;
00127 static uint8_t dmaDataWidth = 0;
00128 static uint8_t dmaSourceAddrMode = 0;
00129 static uint8_t dmaDestAddrMode = 0;
00130 static uint8_t dmaMemSet = 0;
00131 
00132 /*----------------------------------------------------------------------------
00133  *         Local functions
00134  *----------------------------------------------------------------------------*/
00135 
00136 /**
00137  * \brief Dump buffer to DBGU
00138  *
00139  */
00140 static void _DumpBufferInfo(uint8_t* pcBuffer)
00141 {
00142     uint32_t i = 0;
00143 
00144     while (i < BUFFER_LEN) {
00145         printf("%02x ", pcBuffer[i++]);
00146         if ((i % 16 == 0))
00147             printf("\n\r");
00148     }
00149     printf("\n\r");
00150 }
00151 
00152 /**
00153  * \brief Display main menu.
00154  */
00155 static void _displayMenu(void)
00156 {
00157     uint8_t ucChar[4];
00158 
00159     printf("\n\rxDMA Menu :\n\r");
00160     printf("\n\r|====== Channel Configuration ================================|\n\r");
00161     printf("| Press [a|b|c|d] to set Date width                           |\n\r");
00162     ucChar[0] = (dmaDataWidth == 0) ? 'X' : ' ';
00163     ucChar[1] = (dmaDataWidth == 1) ? 'X' : ' ';
00164     ucChar[2] = (dmaDataWidth == 2) ? 'X' : ' ';
00165     printf("|   a: BYTE[%c] b: HALFWORD[%c] c: WORD[%c]                      |\n\r",
00166             ucChar[0],ucChar[1],ucChar[2]);
00167     printf("| Press [0|1|2|3] to set Source Addressing Mode               |\n\r");
00168     ucChar[0] = (dmaSourceAddrMode == 0) ? 'X' : ' ';
00169     ucChar[1] = (dmaSourceAddrMode == 1) ? 'X' : ' ';
00170     ucChar[2] = (dmaSourceAddrMode == 2) ? 'X' : ' ';
00171     ucChar[3] = (dmaSourceAddrMode == 3) ? 'X' : ' ';
00172     printf("|   0: FIXED[%c] 1: INCR[%c] 2: AM[%c] 3: DS_AM[%c]               |\n\r",
00173             ucChar[0],ucChar[1],ucChar[2],ucChar[3]);
00174     printf("| Press [4|5|6|7] to set Destination Addressing Mode          |\n\r");
00175     ucChar[0] = (dmaDestAddrMode == 0) ? 'X' : ' ';
00176     ucChar[1] = (dmaDestAddrMode == 1) ? 'X' : ' ';
00177     ucChar[2] = (dmaDestAddrMode == 2) ? 'X' : ' ';
00178     ucChar[3] = (dmaDestAddrMode == 3) ? 'X' : ' ';
00179     printf("|   4: FIXED[%c] 5: INCR[%c] 6: AM[%c] 7: DS_AM[%c]               |\n\r",
00180             ucChar[0],ucChar[1],ucChar[2],ucChar[3]);
00181     printf("| Press [8|9| to set MEMSET Mode                              |\n\r");
00182     ucChar[0] = (dmaMemSet == 0) ? 'X' : ' ';
00183     ucChar[1] = (dmaMemSet == 1) ? 'X' : ' ';
00184     printf("|   8: NORMAL Mode[%c] 9: HW_MODE[%c]                           |\n\r",
00185             ucChar[0],ucChar[1]);
00186     printf("|=============================================================|\n\r");
00187     printf("\n\r- xDMA transfer type \n\r");
00188     printf("    S: Single Block with Single Micro-block transfer\n\r" );
00189     printf("    M: Single Block with Multiple Micro-block transfer  \n\r" );
00190     printf("    L: Linked List Master transfer\n\r" );
00191     printf("- t: Start DMA transfer\n\r");
00192     printf("- h: Display this menu\n\r");
00193     printf("\n\r");
00194 }
00195 
00196 /**
00197  * \brief Programming DMAC for Multiple Buffer Transfers.
00198  */
00199 static uint8_t _configureTransferMode(void)
00200 {
00201     uint32_t xdmaCndc, xdmaInt;
00202     uint8_t i;
00203 
00204     if (dmaProgrammingMode < XDMA_LLI) {
00205         xdmadCfg.mbr_ubc = MICROBLOCK_LEN;
00206         xdmadCfg.mbr_sa = (uint32_t)sourceBuffer;
00207         xdmadCfg.mbr_da = (uint32_t)destinationBuffer;
00208         xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN |
00209             XDMA_GET_CC_MEMSET(dmaMemSet) |
00210             XDMAC_CC_MEMSET_NORMAL_MODE |
00211             XDMAC_CC_CSIZE_CHK_1 |
00212             XDMA_GET_DATASIZE(dmaDataWidth) |
00213             XDMAC_CC_SIF_AHB_IF0 |
00214             XDMAC_CC_DIF_AHB_IF0 |
00215             XDMA_GET_CC_SAM(dmaSourceAddrMode) |
00216             XDMA_GET_CC_DAM(dmaDestAddrMode);
00217 
00218         xdmadCfg.mbr_bc = (dmaProgrammingMode == XDMA_SINGLE) ? 0 : 1;
00219         xdmadCfg.mbr_ds =  0;
00220         xdmadCfg.mbr_sus = 0;
00221         xdmadCfg.mbr_dus = 0;
00222 
00223         /* Put all interrupts on for non LLI list set-up of DMA */
00224         xdmaInt = (XDMAC_CIE_BIE   |
00225                    XDMAC_CIE_DIE   |
00226                    XDMAC_CIE_FIE   |
00227                    XDMAC_CIE_RBIE  |
00228                    XDMAC_CIE_WBIE  |
00229                    XDMAC_CIE_ROIE);
00230         XDMAD_ConfigureTransfer(&xdmad, dmaChannel, &xdmadCfg, 0, 0, xdmaInt);
00231         printf("- Set Micro-block length to [ %u ] \n\r",
00232                 (unsigned int)xdmadCfg.mbr_ubc);
00233         printf("- Set Block length [ %u ] \n\r", (unsigned int)xdmadCfg.mbr_bc );
00234         printf("- Set Data Stride/Pattern [ %u ] \n\r",
00235                 (unsigned int)xdmadCfg.mbr_ds );
00236         printf("- Set Source Micro-block Stride  [ %u ] \n\r",
00237                 (unsigned int) xdmadCfg.mbr_sus );
00238         printf("- Set Destination  Micro-block Stride [ %u ]\n\r",
00239                 (unsigned int)xdmadCfg.mbr_dus );
00240         printf("- Press 't' to perform xDMA transfer...\n\r");
00241 
00242     }
00243     if (dmaProgrammingMode == XDMA_LLI) {
00244         xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN |
00245             XDMAC_CC_MBSIZE_SINGLE |
00246             XDMA_GET_CC_MEMSET(dmaMemSet) |
00247             XDMAC_CC_CSIZE_CHK_1 |
00248             XDMA_GET_DATASIZE(dmaDataWidth) |
00249             XDMAC_CC_SIF_AHB_IF0 |
00250             XDMAC_CC_DIF_AHB_IF0 |
00251             XDMA_GET_CC_SAM(dmaSourceAddrMode) |
00252             XDMA_GET_CC_DAM(dmaDestAddrMode);
00253         xdmadCfg.mbr_bc = 0;
00254         for (i = 0; i < MAX_LLI_SIZE; i++) {
00255             LLIview1[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
00256                 ((i == 0) ? XDMA_UBC_NSEN_UPDATED : 0 ) |
00257                 ((i == 0) ? XDMA_UBC_NDEN_UPDATED : 0 ) |
00258                 ((i == MAX_LLI_SIZE- 1) ? 0 : XDMA_UBC_NDE_FETCH_EN) |
00259                 MICROBLOCK_LEN;
00260             LLIview1[i].mbr_sa =
00261                 ((i == 0) ? (uint32_t)sourceBuffer : \
00262                 ((uint32_t)sourceBuffer + (BUFFER_LEN >> 1)));
00263             LLIview1[i].mbr_da = ((i == 0) ? (uint32_t)destinationBuffer : \
00264                 ((uint32_t)destinationBuffer + (BUFFER_LEN >> 1)) );
00265             LLIview1[i].mbr_nda =
00266                 (i == ( MAX_LLI_SIZE - 1)) ? 0 : (uint32_t)&LLIview1[i + 1];
00267         }
00268         xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
00269             XDMAC_CNDC_NDE_DSCR_FETCH_EN |
00270             XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
00271             XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
00272         SCB_CleanDCache_by_Addr((uint32_t *)LLIview1, sizeof(LLIview1));
00273         xdmaInt = XDMAC_CIE_LIE;
00274         XDMAD_ConfigureTransfer(&xdmad, dmaChannel, &xdmadCfg, xdmaCndc,
00275                 (uint32_t)&LLIview1[0], xdmaInt);
00276         printf("- Press 't' to perform xDMA Master transfer...\n\r");
00277     }
00278     return 0;
00279 }
00280 
00281 /**
00282  * \brief Start DMAC Multiple Buffer Transfer.
00283  */
00284 static uint8_t _startDmaTransfer( void )
00285 {
00286     uint32_t i;
00287     /* Prepare source data to be transferred. */
00288     for (i = 0; i < BUFFER_LEN; i++) {
00289         sourceBuffer[i] = i;
00290         destinationBuffer[i] = 0xFF;
00291     }
00292 
00293     printf("-I- The Source Buffer 0 content before transfer\n\r");
00294     _DumpBufferInfo((uint8_t *)sourceBuffer);
00295     /* Start transfer */
00296     SCB_CleanDCache_by_Addr((uint32_t *)sourceBuffer, BUFFER_LEN);
00297     XDMAD_StartTransfer(&xdmad, dmaChannel);
00298     while (XDMAD_IsTransferDone(&xdmad, dmaChannel));
00299     SCB_InvalidateDCache_by_Addr((uint32_t *)destinationBuffer, BUFFER_LEN);
00300     printf("-I- The Destination Buffer content after transfer\n\r");
00301     _DumpBufferInfo((uint8_t *)destinationBuffer);
00302     return 0;
00303 }
00304 
00305 
00306 /**
00307  * \brief XDMA handler.
00308  */
00309 void XDMAC_Handler(void)
00310 {
00311     XDMAD_Handler(&xdmad);
00312 }
00313 
00314 /*----------------------------------------------------------------------------
00315  *         Global functions
00316  *----------------------------------------------------------------------------*/
00317 /**
00318  *  \brief XDMA Application entry point
00319  *
00320  *  \return Unused (ANSI-C compatibility)
00321  */
00322 extern int main( void )
00323 {
00324     uint8_t key;
00325 
00326     /* Disable watchdog */
00327     WDT_Disable(WDT);
00328 
00329     /* Enable I and D cache */
00330     SCB_EnableICache();
00331     SCB_EnableDCache();
00332 
00333     /* Output example information */
00334     printf("-- XDMA Example %s --\n\r", SOFTPACK_VERSION);
00335     printf("-- %s\n\r", BOARD_NAME);
00336     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME);
00337 
00338     /* Initialize XDMA driver instance with polling mode */
00339     XDMAD_Initialize(&xdmad, POLLING_MODE);
00340 
00341     /* Allocate a XDMA channel. */
00342     dmaChannel = XDMAD_AllocateChannel(&xdmad, XDMAD_TRANSFER_MEMORY,
00343             XDMAD_TRANSFER_MEMORY);
00344     if (dmaChannel == XDMAD_ALLOC_FAILED) {
00345         printf("-E- Can't allocate XDMA channel\n\r");
00346         return 0;
00347     }
00348     XDMAD_PrepareChannel(&xdmad, dmaChannel);
00349 
00350     /*Enable xDMA interrupt */
00351     NVIC_ClearPendingIRQ(XDMAC_IRQn);
00352     NVIC_SetPriority(XDMAC_IRQn ,1);
00353     NVIC_EnableIRQ(XDMAC_IRQn);
00354 
00355     /* Display menu */
00356     _displayMenu();
00357 
00358     for(;;) {
00359         key = DBG_GetChar();
00360         if ((key == 'a') || (key == 'b') || (key == 'c')) {
00361             dmaDataWidth = key - 'a';
00362             _displayMenu();
00363         }
00364         if ((key >= '0') && (key <= '3')) {
00365             dmaSourceAddrMode = key - '0';
00366             _displayMenu();
00367         }
00368         if ((key >= '4') && (key <= '7')) {
00369             dmaDestAddrMode = key - '4';
00370             _displayMenu();
00371         }
00372         if ((key >= '8') && (key <= '9')) {
00373             dmaMemSet = key - '8';
00374             _displayMenu();
00375         }
00376         if ((key == 'S') || (key == 's')){
00377             dmaProgrammingMode = 1;
00378             _configureTransferMode();
00379             ConfigFlag = 1;
00380         }
00381         if ((key == 'M') || (key == 'm')){
00382             dmaProgrammingMode = 2;
00383             _configureTransferMode();
00384             ConfigFlag = 1;
00385         }
00386         if ((key == 'L') || (key == 'l')){
00387             dmaProgrammingMode = 3;
00388             _configureTransferMode();
00389             ConfigFlag = 1;
00390         }
00391         if ((key == 'H') || (key == 'h'))
00392             _displayMenu();
00393         if ((key == 'T') || (key == 't')) {
00394             if (ConfigFlag) {
00395                 printf("-I- Start XDMA transfer\n\r");
00396                 _startDmaTransfer();
00397                 ConfigFlag = 0;
00398             }
00399         }
00400     }
00401 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines