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 pwm PWM with DMA Example
00032  *
00033  * \section Purpose
00034  *
00035  * This example demonstrates a simple configuration of three PWM channels to
00036  * generate variable duty cycle signals. The update of the duty cycle values
00037  * is made automatically by the Peripheral DMA Controller .
00038  * This will cause LED on the evaluation kit to glow repeatedly.
00039  *
00040  * \section Requirements
00041  *
00042  * This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board.
00043  *
00044  * \section Description
00045  *
00046  * Three PWM channels (channel #0) are configured to generate
00047  * a 50Hz PWM signal. The update of the duty cycle values is made
00048  * automatically by the DMA.
00049  *
00050  * \section Usage
00051  *
00052  *  -# Build the program and download it inside the board.
00053  *     Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00054  * -# Optionally, on the computer, open and configure a terminal application
00055  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00056  *   - 115200 baud rate
00057  *   - 8 bits of data
00058  *   - No parity
00059  *   - 1 stop bit
00060  *   - No flow control
00061  * -# Start the application.
00062  * \if document_SAMV71_XULT
00063  * -# Depending on the board being used, the LED will start glowing repeatedly.
00064  * \elseif document_SAME70_XPRO
00065  * -# due to the LED is not connected to the PWM output pin, the PWM signal can
00066  * be measured on J507 PIN24, if the pin is connected to the LED, the LED will
00067  * start glowing repeatedly.
00068  * \endif
00069  * -# Select one or more options to set the configuration of PWM channel.
00070  *
00071  * \section References
00072  * - pwm_pdc/main.c
00073  * - pwm.c
00074  * - pwm.h
00075  */
00076 
00077 /**
00078  * \file
00079  *
00080  * This file contains all the specific code for the pwm_pdc example.
00081  */
00082 
00083 /*----------------------------------------------------------------------------
00084  *        Headers
00085  *----------------------------------------------------------------------------*/
00086 
00087 #include "board.h"
00088 
00089 #include <stdint.h>
00090 #include <stdio.h>
00091 
00092 /*----------------------------------------------------------------------------
00093  *        Local definitions
00094  *----------------------------------------------------------------------------*/
00095 
00096 /** PWM frequency in Hz. */
00097 #define PWM_FREQUENCY               50
00098 
00099 /** Maximum duty cycle value. */
00100 #define MAX_DUTY_CYCLE              100
00101 /** Minimum duty cycle value. */
00102 #define MIN_DUTY_CYCLE              0
00103 
00104 /** Duty cycle buffer length for three channels */
00105 #define DUTY_BUFFER_LENGTH          (MAX_DUTY_CYCLE - MIN_DUTY_CYCLE )
00106 
00107 /*----------------------------------------------------------------------------
00108  *        Local variables
00109  *----------------------------------------------------------------------------*/
00110 
00111 /** PIO pins to configure. */
00112 
00113 #define PIN_PWM_LED   { PIO_PA23B_PWMC0_PWMH0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
00114 #define CHANNEL_PWM_LED0  0
00115 //
00116 static const Pin pinPwm[] = {PIN_PWM_LED};
00117 
00118 /** duty cycle buffer*/
00119 COMPILER_ALIGNED(32) static uint16_t dwDutys[DUTY_BUFFER_LENGTH];
00120 
00121 /** Global DMA driver for all transfer */
00122 static sXdmad dmad;
00123 
00124 /** DMA channel for TX */
00125 static uint32_t pwmDmaTxChannel;
00126 COMPILER_ALIGNED(32) static LinkedListDescriporView1 dmaWriteLinkList[DUTY_BUFFER_LENGTH];
00127 
00128 /*----------------------------------------------------------------------------
00129  *        Local functions
00130  *----------------------------------------------------------------------------*/
00131 
00132 /**
00133  * Interrupt handler for the XDMAC.
00134  */
00135 void XDMAC_Handler(void)
00136 {
00137     XDMAD_Handler(&dmad );
00138 }
00139 
00140 /**
00141  * Interrupt handler for the PWMC.
00142  */
00143 void PWM0_Handler(void)
00144 {
00145     volatile uint32_t dummySt;
00146     /* WRDY: this flag is set to'1' when the PWM Controller is ready to receive
00147     new duty-cycle values and a new update period value. It is reset to '0'
00148     when the PWM_ISR2 is read.*/
00149     dummySt = PWMC_GetStatus2(PWM0);
00150 }
00151 
00152 /**
00153  * \brief xDMA driver configuration
00154  */
00155 static void _ConfigureDma(void)
00156 {
00157     sXdmad *pDmad = &dmad;
00158     /* Driver initialize */
00159     XDMAD_Initialize( pDmad, 0 );
00160     /* Allocate DMA channels for PWM */
00161     pwmDmaTxChannel = XDMAD_AllocateChannel(pDmad, XDMAD_TRANSFER_MEMORY, ID_PWM0);
00162     if (pwmDmaTxChannel == XDMAD_ALLOC_FAILED) {
00163         printf("xDMA channel allocation error\n\r");
00164         while (1);
00165     }
00166     XDMAD_PrepareChannel(pDmad, pwmDmaTxChannel);
00167     /* Configure interrupt for DMA transfer */
00168     NVIC_ClearPendingIRQ(XDMAC_IRQn);
00169     NVIC_SetPriority( XDMAC_IRQn ,1);
00170     NVIC_EnableIRQ(XDMAC_IRQn);
00171 }
00172 
00173 /**
00174  * \brief xDMA transfer PWM duty
00175  */
00176 static void _PwmDmaTransfer(void)
00177 {
00178     sXdmadCfg xdmadCfg;
00179     uint32_t xdmaCndc;
00180     uint32_t i;
00181 
00182     for (i = 0; i < DUTY_BUFFER_LENGTH; i++) {
00183         dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
00184             | XDMA_UBC_NDE_FETCH_EN
00185             | XDMA_UBC_NSEN_UPDATED
00186             | XDMAC_CUBC_UBLEN(1);
00187         dmaWriteLinkList[i].mbr_sa = (uint32_t)(&dwDutys[i]);
00188         dmaWriteLinkList[i].mbr_da = (uint32_t)(&(PWM0->PWM_DMAR));
00189         if (i == (DUTY_BUFFER_LENGTH - 1))
00190             dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
00191         else
00192             dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i+1];
00193     }
00194 
00195     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00196         | XDMAC_CC_MBSIZE_SINGLE
00197         | XDMAC_CC_DSYNC_MEM2PER
00198         | XDMAC_CC_CSIZE_CHK_1
00199         | XDMAC_CC_DWIDTH_HALFWORD
00200         | XDMAC_CC_SIF_AHB_IF1
00201         | XDMAC_CC_DIF_AHB_IF1
00202         | XDMAC_CC_SAM_FIXED_AM
00203         | XDMAC_CC_DAM_FIXED_AM
00204         | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_PWM0, XDMAD_TRANSFER_TX ));
00205     xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
00206         | XDMAC_CNDC_NDE_DSCR_FETCH_EN
00207         | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00208         | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
00209     XDMAD_ConfigureTransfer( &dmad, pwmDmaTxChannel, &xdmadCfg, xdmaCndc,
00210             (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE);
00211     SCB_CleanDCache_by_Addr((uint32_t *)dwDutys, sizeof(dwDutys));
00212     SCB_CleanDCache_by_Addr((uint32_t *)dmaWriteLinkList, sizeof(dmaWriteLinkList));
00213     XDMAD_StartTransfer(&dmad, pwmDmaTxChannel);
00214 }
00215 
00216 /*----------------------------------------------------------------------------
00217  *         Global functions
00218  *----------------------------------------------------------------------------*/
00219 
00220 /**
00221  * \brief Application entry point for PWM with PDC example.
00222  *
00223  * Outputs a PWM on LED1.
00224  * Channel #0 is configured as synchronous channels.
00225  * The update of the duty cycle values is made automatically by the Peripheral
00226  * DMA Controller.
00227  *
00228  * \return Unused (ANSI-C compatibility).
00229  */
00230 int main(void)
00231 {
00232     uint32_t i;
00233 
00234     /* Disable watchdog */
00235     WDT_Disable(WDT);
00236 
00237     /* Enable I and D cache */
00238     SCB_EnableICache();
00239     SCB_EnableDCache();
00240 
00241     /* Output example information */
00242     printf("-- PWM with DMA Example %s --\n\r", SOFTPACK_VERSION);
00243     printf("-- %s\n\r", BOARD_NAME);
00244     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME);
00245 
00246     /* PIO configuration */
00247     PIO_Configure(pinPwm, PIO_LISTSIZE(pinPwm));
00248     for (i = 0; i < DUTY_BUFFER_LENGTH; i++)
00249         dwDutys[i] = i / 2;
00250 
00251     /* Enable PWMC peripheral clock */
00252     PMC_EnablePeripheral(ID_PWM0);
00253 
00254     /* Configure interrupt for PWM transfer */
00255     NVIC_DisableIRQ(PWM0_IRQn);
00256     NVIC_ClearPendingIRQ(PWM0_IRQn);
00257     NVIC_SetPriority(PWM0_IRQn, 0);
00258 
00259     /* Configure DMA channel for PWM transfer */
00260     _ConfigureDma();
00261 
00262     /* Set clock A to run at PWM_FREQUENCY * MAX_DUTY_CYCLE (clock B is not
00263         used) */
00264     PWMC_ConfigureClocks(PWM0, PWM_FREQUENCY * MAX_DUTY_CYCLE , 0, BOARD_MCK);
00265 
00266     /* Configure PWMC channel for LED0 (left-aligned, enable dead time
00267         generator) */
00268     PWMC_ConfigureChannel( PWM0,
00269             0,  /* channel */
00270             PWM_CMR_CPRE_CLKA,  /* prescaler, CLKA  */
00271             0,                  /* alignment */
00272             0                   /* polarity */
00273             );
00274 
00275     PWMC_ConfigureSyncChannel(PWM0,
00276             /* Define the synchronous channels by the bits SYNCx */
00277             (1 << CHANNEL_PWM_LED0),
00278             /* Select the manual write of duty-cycle values and the automatic
00279                 update by setting the field UPDM  */
00280             PWM_SCM_UPDM_MODE2,
00281             0,
00282             0);
00283 
00284     /* Configure channel 0 period */
00285     PWMC_SetPeriod(PWM0, 0, DUTY_BUFFER_LENGTH);
00286     /* Configure channel 0 duty cycle */
00287     PWMC_SetDutyCycle(PWM0, 0, MIN_DUTY_CYCLE);
00288     /* Define the update period by the field UPR in the PWM_SCUP register*/
00289     PWMC_SetSyncChannelUpdatePeriod(PWM0, 8);
00290     /* Enable the synchronous channels by writing CHID0 in the PWM_ENA register */
00291     PWMC_EnableChannel(PWM0, 0);
00292     /* Enable PWM interrupt */
00293     PWMC_EnableIt(PWM0, 0, PWM_IER2_WRDY);
00294     NVIC_EnableIRQ(PWM0_IRQn);
00295     _PwmDmaTransfer();
00296     while (1);
00297 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines