SAMV71 Xplained Ultra Software Package 1.4

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
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 SAM V71 Xplained Ultra 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 SAM V71 Xplained Ultra board. 
00052  *     Please refer to the Getting Started with SAM V71 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 rates
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_WORD_ALIGNED static LinkedListDescriporView1 LLIview1[MAX_LLI_SIZE];
00115 
00116 /* DMA driver instance */
00117 static uint32_t dmaChannel;
00118 
00119 
00120 COMPILER_ALIGNED(8) static uint8_t sourceBuffer[512];
00121 
00122 COMPILER_ALIGNED(8) 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     while (i < BUFFER_LEN) {
00144         printf( "%02x ", pcBuffer[i++] ) ;
00145         if((i % 16 == 0)) printf("\n\r");
00146     }
00147     printf("\n\r");
00148 }
00149 
00150 /**
00151  * \brief Display main menu.
00152  */
00153 static void _displayMenu(void)
00154 {
00155     uint8_t ucChar[4];
00156     printf("\n\rxDMA Menu :\n\r");
00157     printf("\n\r|====== Channel Configuration ================================|\n\r");
00158     printf("| Press [a|b|c|d] to set Date width                           |\n\r");
00159     ucChar[0] = (dmaDataWidth == 0) ? 'X' : ' ';
00160     ucChar[1] = (dmaDataWidth == 1) ? 'X' : ' ';
00161     ucChar[2] = (dmaDataWidth == 2) ? 'X' : ' ';
00162     printf("|   a: BYTE[%c] b: HALFWORD[%c] c: WORD[%c]                      |\n\r", 
00163             ucChar[0],ucChar[1],ucChar[2]);
00164     printf("| Press [0|1|2|3] to set Source Addressing Mode               |\n\r");
00165     ucChar[0] = (dmaSourceAddrMode == 0) ? 'X' : ' ';
00166     ucChar[1] = (dmaSourceAddrMode == 1) ? 'X' : ' ';
00167     ucChar[2] = (dmaSourceAddrMode == 2) ? 'X' : ' ';
00168     ucChar[3] = (dmaSourceAddrMode == 3) ? 'X' : ' ';
00169     printf("|   0: FIXED[%c] 1: INCR[%c] 2: AM[%c] 3: DS_AM[%c]               |\n\r", 
00170             ucChar[0],ucChar[1],ucChar[2],ucChar[3]);
00171     printf("| Press [4|5|6|7] to set Destination Addressing Mode          |\n\r");
00172     ucChar[0] = (dmaDestAddrMode == 0) ? 'X' : ' ';
00173     ucChar[1] = (dmaDestAddrMode == 1) ? 'X' : ' ';
00174     ucChar[2] = (dmaDestAddrMode == 2) ? 'X' : ' ';
00175     ucChar[3] = (dmaDestAddrMode == 3) ? 'X' : ' ';
00176     printf("|   4: FIXED[%c] 5: INCR[%c] 6: AM[%c] 7: DS_AM[%c]               |\n\r", 
00177             ucChar[0],ucChar[1],ucChar[2],ucChar[3]);
00178     printf("| Press [8|9| to set MEMSET Mode                              |\n\r");
00179     ucChar[0] = (dmaMemSet == 0) ? 'X' : ' ';
00180     ucChar[1] = (dmaMemSet == 1) ? 'X' : ' ';
00181     printf("|   8: NORMAL Mode[%c] 9: HW_MODE[%c]                           |\n\r", 
00182             ucChar[0],ucChar[1]);
00183     printf("|=============================================================|\n\r");
00184     printf("\n\r- xDMA transfer type \n\r");
00185     printf("    S: Single Block with Single Micro-block transfer\n\r" );
00186     printf("    M: Single Block with Multiple Micro-block transfer  \n\r" );
00187     printf("    L: Linked List Master transfer\n\r" );
00188     printf("- t: Start DMA transfer\n\r");
00189     printf("- h: Display this menu\n\r");
00190     printf("\n\r");
00191 }
00192 
00193 /**
00194  * \brief Programming DMAC for Multiple Buffer Transfers.
00195  */
00196 static uint8_t _configureTransferMode(void)
00197 {
00198     uint32_t xdmaCndc, xdmaInt;
00199     uint8_t i;
00200     if (dmaProgrammingMode < XDMA_LLI) {
00201         xdmadCfg.mbr_ubc = MICROBLOCK_LEN;
00202         xdmadCfg.mbr_sa = (uint32_t)sourceBuffer;
00203         xdmadCfg.mbr_da = (uint32_t)destinationBuffer;
00204         xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN |
00205             XDMA_GET_CC_MEMSET(dmaMemSet) |
00206             XDMAC_CC_MEMSET_NORMAL_MODE |
00207             XDMAC_CC_CSIZE_CHK_1 |
00208             XDMA_GET_DATASIZE(dmaDataWidth) |
00209             XDMAC_CC_SIF_AHB_IF0 |
00210             XDMAC_CC_DIF_AHB_IF0 |
00211             XDMA_GET_CC_SAM(dmaSourceAddrMode) |
00212             XDMA_GET_CC_DAM(dmaDestAddrMode);
00213 
00214         xdmadCfg.mbr_bc = (dmaProgrammingMode== XDMA_SINGLE)? 0: 1 ;
00215         xdmadCfg.mbr_ds =  0;
00216         xdmadCfg.mbr_sus = 0;
00217         xdmadCfg.mbr_dus = 0; 
00218         
00219         /* Put all interrupts on for non LLI list set-up of DMA */
00220         xdmaInt =  (XDMAC_CIE_BIE   |
00221                    XDMAC_CIE_DIE   |
00222                    XDMAC_CIE_FIE   |
00223                    XDMAC_CIE_RBIE  |
00224                    XDMAC_CIE_WBIE  |
00225                    XDMAC_CIE_ROIE);
00226         XDMAD_ConfigureTransfer( &xdmad, dmaChannel, &xdmadCfg, 0, 0, xdmaInt);
00227         printf("- Set Micro-block length to [ %u ] \n\r",
00228                 (unsigned int)xdmadCfg.mbr_ubc);
00229         printf("- Set Block length [ %u ] \n\r", (unsigned int)xdmadCfg.mbr_bc );
00230         printf("- Set Data Stride/Pattern [ %u ] \n\r", 
00231                 (unsigned int)xdmadCfg.mbr_ds );
00232         printf("- Set Source Micro-block Stride  [ %u ] \n\r", 
00233                 (unsigned int) xdmadCfg.mbr_sus );
00234         printf("- Set Destination  Micro-block Stride [ %u ]\n\r", 
00235                 (unsigned int)xdmadCfg.mbr_dus );
00236         printf("- Press 't' to perform xDMA transfer...\n\r");
00237 
00238     }
00239     if (dmaProgrammingMode == XDMA_LLI) {
00240         xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN |
00241             XDMAC_CC_MBSIZE_SINGLE |
00242             XDMA_GET_CC_MEMSET(dmaMemSet) |
00243             XDMAC_CC_CSIZE_CHK_1 |
00244             XDMA_GET_DATASIZE(dmaDataWidth) |
00245             XDMAC_CC_SIF_AHB_IF0 |
00246             XDMAC_CC_DIF_AHB_IF0 |
00247             XDMA_GET_CC_SAM(dmaSourceAddrMode) |
00248             XDMA_GET_CC_DAM(dmaDestAddrMode);
00249         xdmadCfg.mbr_bc = 0;
00250         for (i = 0; i < MAX_LLI_SIZE; i++) {
00251             LLIview1[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
00252                 ((i==0) ? XDMA_UBC_NSEN_UPDATED : 0 ) | 
00253                 ((i==0) ? XDMA_UBC_NDEN_UPDATED : 0 ) |
00254                 ((i== MAX_LLI_SIZE- 1)? 0:  XDMA_UBC_NDE_FETCH_EN) |
00255                 MICROBLOCK_LEN;
00256             LLIview1[i].mbr_sa = 
00257                 ((i==0) ? (uint32_t)sourceBuffer : \
00258                 ((uint32_t)sourceBuffer + (BUFFER_LEN >> 1)));
00259             LLIview1[i].mbr_da = ((i==0) ? (uint32_t)destinationBuffer : \
00260                 ((uint32_t)destinationBuffer + (BUFFER_LEN >> 1)) );
00261             LLIview1[i].mbr_nda = 
00262                 (i == ( MAX_LLI_SIZE - 1))?0:(uint32_t)&LLIview1[ i + 1 ];
00263         } 
00264         xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | 
00265             XDMAC_CNDC_NDE_DSCR_FETCH_EN |
00266             XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
00267             XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00268         
00269         xdmaInt = XDMAC_CIE_LIE;
00270         XDMAD_ConfigureTransfer( &xdmad, dmaChannel, &xdmadCfg, xdmaCndc, 
00271                 (uint32_t)&LLIview1[0], xdmaInt);
00272         printf("- Press 't' to perform xDMA Master transfer...\n\r");
00273     }
00274     return 0;
00275 }
00276 
00277 /**
00278  * \brief Start DMAC Multiple Buffer Transfer.
00279  */
00280 static uint8_t _startDmaTransfer( void )
00281 {
00282     uint32_t i;
00283     /* Prepare source data to be transferred. */
00284     for ( i = 0; i < BUFFER_LEN; i++) {
00285         sourceBuffer[i] = i;
00286         destinationBuffer[i] = 0xFF;
00287     }
00288 
00289     printf("-I- The Source Buffer 0 content before transfer\n\r");
00290     _DumpBufferInfo((uint8_t *)sourceBuffer);
00291     /* Start transfer */
00292     SCB_CleanInvalidateDCache();
00293     XDMAD_StartTransfer( &xdmad, dmaChannel );
00294     while (XDMAD_IsTransferDone( &xdmad, dmaChannel ));
00295     printf("-I- The Destination Buffer content after transfer\n\r");
00296     _DumpBufferInfo((uint8_t *)destinationBuffer);
00297     return 0;
00298 }
00299 
00300 
00301 /**
00302  * \brief XDMA handler.
00303  */
00304 void XDMAC_Handler(void)
00305 {
00306     XDMAD_Handler(&xdmad);
00307 }
00308 
00309 /*----------------------------------------------------------------------------
00310  *         Global functions
00311  *----------------------------------------------------------------------------*/
00312 /**
00313  *  \brief XDMA Application entry point
00314  *
00315  *  \return Unused (ANSI-C compatibility)
00316  */
00317 extern int main( void )
00318 {
00319     uint8_t key;
00320     
00321     /* Disable watchdog */
00322     WDT_Disable( WDT ) ;
00323     
00324     /* Enable I and D cache */
00325     SCB_EnableICache();
00326     SCB_EnableDCache();
00327 
00328     /* Output example information */
00329     printf("-- XDMA Example %s --\n\r", SOFTPACK_VERSION);
00330     printf("-- %s\n\r", BOARD_NAME);
00331     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME);
00332 
00333     /* Initialize XDMA driver instance with polling mode */
00334     XDMAD_Initialize( &xdmad, POLLING_MODE );
00335 
00336     /* Allocate a XDMA channel. */
00337     dmaChannel = XDMAD_AllocateChannel( &xdmad, XDMAD_TRANSFER_MEMORY, 
00338             XDMAD_TRANSFER_MEMORY);
00339     if ( dmaChannel == XDMAD_ALLOC_FAILED ) {
00340         printf("-E- Can't allocate XDMA channel\n\r");
00341         return 0;
00342     }
00343     XDMAD_PrepareChannel(&xdmad, dmaChannel );
00344 
00345     /*Enable xDMA interrupt */ 
00346     NVIC_ClearPendingIRQ(XDMAC_IRQn);
00347     NVIC_SetPriority( XDMAC_IRQn ,1);
00348     NVIC_EnableIRQ(XDMAC_IRQn);
00349 
00350     /* Display menu */
00351     _displayMenu();
00352 
00353     for(;;) {
00354         key = DBG_GetChar();
00355         if ((key == 'a') || (key == 'b') || (key == 'c')) {
00356             dmaDataWidth = key - 'a';
00357             _displayMenu();
00358         }
00359         if ((key >= '0') && (key <= '3')) {
00360             dmaSourceAddrMode = key - '0';
00361             _displayMenu();
00362         }
00363         if ((key >= '4') && (key <= '7')) {
00364             dmaDestAddrMode = key - '4';
00365             _displayMenu();
00366         }
00367         if ((key >= '8') && (key <= '9')) {
00368             dmaMemSet = key - '8';
00369             _displayMenu();
00370         }
00371         if ((key == 'S') || (key == 's')){
00372             dmaProgrammingMode = 1;
00373             _configureTransferMode();
00374             ConfigFlag = 1;
00375         }
00376         if ((key == 'M') || (key == 'm')){
00377             dmaProgrammingMode = 2;
00378             _configureTransferMode();
00379             ConfigFlag = 1;
00380         }
00381         if ((key == 'L') || (key == 'l')){
00382             dmaProgrammingMode = 3;
00383             _configureTransferMode();
00384             ConfigFlag = 1;
00385         }
00386         if ((key == 'H') || (key == 'h')) _displayMenu();
00387         if ((key == 'T') || (key == 't')) {
00388             if(ConfigFlag) {
00389                 printf("-I- Start XDMA transfer\n\r");
00390                 _startDmaTransfer();
00391                 ConfigFlag = 0;
00392             }
00393         }
00394     }
00395 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines