SAMV71 Xplained Ultra Software Package 1.3

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