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  * \page tc_capture_waveform TC Capture Waveform Example
00031  *
00032  * \section Purpose
00033  *
00034  * This example indicates how to use TC in capture mode to measure the pulse 
00035  * frequency and count the total pulse number of an external signal injected 
00036  * on TIOA pin.
00037  *
00038  * \section Requirements
00039  *
00040  * This package can be used with SAM V71 Xplained Ultra board.
00041  * It generates a waveform from one channel TIOAx , and it capture wave from another 
00042  * channel TIOAy. To measure the waveform on TIOAx, you shall connect TIOAx to
00043  * TIOAy, configure TIOAx as output pin and TIOAy as input pin.
00044  *
00045  *
00046  * \section Descriptions
00047  *
00048  * This example shows how to configure TC in waveform and capture mode.
00049  * In capture mode, pulse signal is set as an input, RA and RB will be loaded when 
00050  * programmed event occurs. When TC interrupt happens, we could read RA and RB
00051  * value for calculating pulse frequency and pulse number be increased. The current 
00052  * pulse frequency and total pulse number is output on DBGU.
00053  *
00054  * The code can be roughly broken down as follows:
00055  * <ul>
00056  * <li>Select pre-defined waveform frequency and duty cycle to be generated.
00057  * <li>Configure TC channel a as waveform output.
00058  * <li>Configure TC channel b as capture input.
00059  * <li>Configure capture Register A be loaded when rising edge of TIOA occurs.
00060  * <li>Configure capture Register B be loaded when failing edge of TIOA occurs.
00061  * <li>Configure an interrupt for TC and enable the RB load interrupt.
00062  * <li> 'c' start capture.
00063  * <li> 's' will stop capture,and dump the informations what have been captured.
00064  * </ul>
00065  *
00066  * \section Usage
00067  *
00068  * -# Connect Pin07 with Pin16 on EXT1 on the board.
00069  * -# Connect the DBGU port of the evaluation board to the computer.
00070  * -# Open and configure a terminal application on PC
00071  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00072  *   - 115200 baud rate
00073  *   - 8 bits of data
00074  *   - No parity
00075  *   - 1 stop bit
00076  *   - No flow control
00077  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00078  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00079  * -# Upon startup, the application will output the following line on the DBGU:
00080  *    \code
00081  *     -- TC Capture Waveform Example  xxx --
00082  *     -- SAMxxxxx-xx
00083  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00084  *    \endcode
00085  * -# Choose the item in the following menu to test.
00086  *    \code
00087  *     Menu :
00088  *     ------
00089  *       Output waveform property:
00090  *       0: Set Frequency =  400 Hz, Duty Cycle = 30%
00091  *       1: Set Frequency =  500 Hz, Duty Cycle = 50%
00092  *       2: Set Frequency =  800 Hz, Duty Cycle = 75%
00093  *       3: Set Frequency =  1000 Hz, Duty Cycle = 80%
00094  *       4: Set Frequency =  4000 Hz, Duty Cycle = 55%
00095 *       -------------------------------------------
00096 *       c: Capture waveform from TC capture channel 
00097 *       s: Stop capture and display informations what have been captured
00098 *       h: Display menu
00099 *     ------
00100 *    \endcode
00101 *
00102 * \section References
00103 * - tc_capture_waveform/main.c
00104 */
00105 /**
00106  * \file
00107  *
00108  * This file contains all the specific code for the tc capture waveform example.
00109  */
00110 
00111 
00112 /*----------------------------------------------------------------------------
00113  *        Headers
00114  *----------------------------------------------------------------------------*/
00115 
00116 #include "board.h"
00117 #include <stdio.h>
00118 
00119 /*----------------------------------------------------------------------------
00120  *        Local definitions
00121  *----------------------------------------------------------------------------*/
00122 #define PIN_TC_TIOA_OUT   {PIO_PA0B_TIOA0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}  
00123 #define PIN_TC_TIOA_IN    {PIO_PD21C_TIOA11, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT} 
00124 
00125 #define TC_WAVE_BASE       TC0
00126 #define TC_WAVE_ID         ID_TC0
00127 #define TC_WAVE_CHANNEL    0
00128 
00129 #define TC_CAPTURE_BASE    TC3
00130 #define TC_CAPTURE_ID      ID_TC11
00131 #define TC_CAPTURE_CHANNEL 2
00132 #define TC_Handler         TC11_Handler
00133 #define TC_IRQn            TC11_IRQn
00134 /*----------------------------------------------------------------------------
00135  *        Types
00136  *----------------------------------------------------------------------------*/
00137 /** Describes a possible Timer configuration as waveform mode */
00138 struct WaveformConfiguration {
00139     /** Internal clock signals selection. */
00140     uint32_t clockSelection;
00141     /** Waveform frequency (in Hz). */
00142     uint16_t frequency;
00143     /** Duty cycle in percent (positive)*/
00144     uint16_t dutyCycle;
00145 };
00146 
00147 /*----------------------------------------------------------------------------
00148  *        Local variables
00149  *----------------------------------------------------------------------------*/
00150 
00151 /** PIOs for TC0 */
00152 static const Pin pTcPins[] = {PIN_TC_TIOA_OUT, PIN_TC_TIOA_IN};
00153 
00154 static const struct WaveformConfiguration waveformConfigurations[] = {
00155 
00156     {TC_CMR_TCCLKS_TIMER_CLOCK4, 400, 30},
00157     {TC_CMR_TCCLKS_TIMER_CLOCK3, 500, 50},
00158     {TC_CMR_TCCLKS_TIMER_CLOCK3, 800, 75},
00159     {TC_CMR_TCCLKS_TIMER_CLOCK2, 1000, 80},
00160     {TC_CMR_TCCLKS_TIMER_CLOCK2, 4000, 55}
00161 };
00162 
00163 /** Current wave configuration*/
00164 static uint8_t configuration = 0;
00165 
00166 /** Number of available wave configurations */
00167 const uint8_t numConfigurations = sizeof(waveformConfigurations) / 
00168         sizeof(struct WaveformConfiguration);
00169 /** Capture status*/
00170 static uint32_t _dwCaptured_pulses;
00171 static uint32_t _dwCaptured_ra ;
00172 static uint32_t _dwCaptured_rb ;
00173 const uint32_t divisors[5] = {2, 8, 32, 128, BOARD_MCK / 32768};
00174 
00175 /*----------------------------------------------------------------------------
00176  *        Local functions
00177  *----------------------------------------------------------------------------*/
00178 
00179 /**
00180  * \brief Displays the user menu on the DBGU.
00181  */
00182 static void DisplayMenu(void)
00183 {
00184     uint8_t i;
00185     printf("\n\rMenu :\n\r");
00186     printf("------\n\r");
00187 
00188     printf("  Output waveform property:\n\r");
00189     for (i = 0; i < numConfigurations; i++) {
00190         printf("  %d: Set Frequency = %4u Hz, Duty Cycle = %2u%%\n\r",
00191                 i,
00192                 (unsigned int)waveformConfigurations[i].frequency,
00193                 (unsigned int)waveformConfigurations[i].dutyCycle);
00194     }
00195     printf("  -------------------------------------------\n\r");
00196     printf("  c: Capture waveform from TC capture channel \n\r");
00197     printf("  s: Stop capture and display informations what have been captured \n\r");
00198     printf("  h: Display menu \n\r");
00199     printf("------\n\r\n\r");
00200 }
00201 
00202 
00203 /**
00204  * \brief Interrupt handler for the TC capture.
00205  */
00206 void TC_Handler( void )
00207 {    
00208     uint32_t status ;
00209     status = TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_SR;
00210 
00211     if ( (status & TC_SR_LDRBS) == TC_SR_LDRBS ) {
00212         _dwCaptured_pulses++ ;
00213         _dwCaptured_ra = TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_RA ;
00214         _dwCaptured_rb = TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_RB ;
00215     }
00216 }
00217 
00218 /**
00219  * \brief Configure clock, frequency and dutycycle for TC0 channel 1 in waveform mode.
00220  */
00221 static void TcWaveformConfigure(void)
00222 {
00223     uint32_t ra, rc;
00224     /*  Set channel 1 as waveform mode*/
00225     TC_WAVE_BASE->TC_CHANNEL[TC_WAVE_CHANNEL].TC_CMR =
00226         waveformConfigurations[configuration].clockSelection/* Waveform Clock Selection */
00227         | TC_CMR_WAVE                                    /* Waveform mode is enabled */
00228         | TC_CMR_ACPA_SET                                /* RA Compare Effect: set */
00229         | TC_CMR_ACPC_CLEAR                              /* RC Compare Effect: clear */
00230         | TC_CMR_CPCTRG;                                 /* UP mode with automatic trigger on RC Compare */
00231     rc = (BOARD_MCK / divisors[waveformConfigurations[configuration].clockSelection]) \
00232          / waveformConfigurations[configuration].frequency;
00233     TC_WAVE_BASE->TC_CHANNEL[TC_WAVE_CHANNEL].TC_RC = rc;
00234     ra = (100 - waveformConfigurations[configuration].dutyCycle) * rc / 100;
00235     TC_WAVE_BASE->TC_CHANNEL[TC_WAVE_CHANNEL].TC_RA = ra;
00236 }
00237 
00238 /**
00239  * \brief Configure TC with waveform operating mode.
00240  */
00241 static void TcWaveformInitialize(void)
00242 {
00243     /* Configure the PMC to enable the Timer Counter clock for TC wave */
00244     PMC_EnablePeripheral(TC_WAVE_ID);
00245     /*  Disable TC clock */
00246     TC_WAVE_BASE->TC_CHANNEL[TC_WAVE_CHANNEL].TC_CCR = TC_CCR_CLKDIS;
00247     /*  Disable interrupts */
00248     TC_WAVE_BASE->TC_CHANNEL[TC_WAVE_CHANNEL].TC_IDR = 0xFFFFFFFF;
00249     /*  Clear status register */
00250     TC_WAVE_BASE->TC_CHANNEL[TC_WAVE_CHANNEL].TC_SR;
00251     /* Configure waveform frequency and duty cycle */
00252     TcWaveformConfigure();
00253     /* Enable TC0 channel 0 */
00254     TC_WAVE_BASE->TC_CHANNEL[TC_WAVE_CHANNEL].TC_CCR =  TC_CCR_CLKEN | TC_CCR_SWTRG ;
00255     printf ("Start waveform: Frequency = %d Hz,Duty Cycle = %2d%%\n\r",
00256             waveformConfigurations[configuration].frequency,
00257             waveformConfigurations[configuration].dutyCycle);
00258 }
00259 
00260 /**
00261  * \brief Configure TC with capture operating mode.
00262  */
00263 static void TcCaptureInitialize(void)
00264 {
00265     /* Configure the PMC to enable the Timer Counter clock */
00266     PMC_EnablePeripheral(TC_CAPTURE_ID);
00267     /*  Disable TC clock */
00268     TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_CCR = TC_CCR_CLKDIS;
00269     /*  Disable interrupts */
00270     TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_IDR = 0xFFFFFFFF;
00271     /*  Clear status register */
00272     TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_SR;
00273     /*  Set channel 2 as capture mode */
00274     TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_CMR = \
00275         ( TC_CMR_TCCLKS_TIMER_CLOCK2 /* Clock Selection */
00276         | TC_CMR_LDRA_RISING        /* RA Loading Selection: rising edge of TIOA */
00277         | TC_CMR_LDRB_FALLING       /* RB Loading Selection: falling edge of TIOA */
00278         | TC_CMR_ABETRG            /* External Trigger Selection: TIOA */
00279         | TC_CMR_ETRGEDG_FALLING    /* External Trigger Edge Selection: Falling edge */
00280         );
00281 }
00282 
00283 /*----------------------------------------------------------------------------
00284  *         Global functions
00285  *----------------------------------------------------------------------------*/
00286 /**
00287  * \brief Application entry point for tc_capture_waveform example.
00288  *
00289  * \return Unused (ANSI-C compatibility).
00290  */
00291 int main( void )
00292 {
00293     uint8_t ucKey ;
00294     uint16_t frequence, dutyCycle ;
00295 
00296     /* Disable watchdog */
00297     WDT_Disable( WDT ) ;
00298    
00299     /* Enable I and D cache */
00300     SCB_EnableICache();
00301     SCB_EnableDCache();
00302 
00303     /* Output example information */
00304     printf( "-- TC capture waveform example %s --\n\r", SOFTPACK_VERSION ) ;
00305     printf( "-- %s\n\r", BOARD_NAME ) ;
00306     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00307 
00308     /* Configure PIO Pins for TC0 */
00309     PIO_Configure( pTcPins, PIO_LISTSIZE( pTcPins ) ) ;
00310     /* Configure one TC as waveform operating mode */
00311     printf("Configure TC channel %d as waveform operating mode \n\r", 
00312             TC_WAVE_CHANNEL);
00313     TcWaveformInitialize() ;
00314     /* Configure one TC channel as capture operating mode */
00315     printf("Configure TC channel %d as capture operating mode \n\r", 
00316             TC_CAPTURE_CHANNEL);
00317     TcCaptureInitialize() ;
00318 
00319     /* Configure TC interrupts */
00320     NVIC_ClearPendingIRQ(TC_IRQn);
00321     NVIC_EnableIRQ(TC_IRQn);
00322 
00323     /* Display menu */
00324     DisplayMenu() ;
00325 
00326     while ( 1 ) {
00327         ucKey = DBG_GetChar() ;
00328 
00329         switch ( ucKey ) {
00330         case 'h' :
00331             DisplayMenu() ;
00332             break ;
00333 
00334         case 's' :
00335             if ( _dwCaptured_pulses ) {
00336                 TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_IDR = TC_IDR_LDRBS ;
00337                 printf( "Captured %u pulses from TC capture channel , RA = %u, RB = %u \n\r",
00338                         (unsigned int)_dwCaptured_pulses, 
00339                         (unsigned int)_dwCaptured_ra, 
00340                         (unsigned int)_dwCaptured_rb ) ;
00341 
00342                 frequence = (BOARD_MCK / 8)/ _dwCaptured_rb;
00343                 dutyCycle = (_dwCaptured_rb - _dwCaptured_ra) * 100 / _dwCaptured_rb;
00344                 printf( "Captured wave frequency = %d Hz, Duty cycle = %d%% \n\r", 
00345                         frequence, dutyCycle ) ;
00346                 _dwCaptured_pulses = 0 ;
00347                 _dwCaptured_ra = 0 ;
00348                 _dwCaptured_rb = 0 ;
00349             } else {
00350                 printf( "No waveform has been captured\n\r" ) ;
00351             }
00352             printf( "\n\rPress 'h' to display menu\n\r" ) ;
00353             break ;
00354 
00355         case 'c' :
00356             printf ("Start capture, press 's' to stop \n\r");
00357             TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_IER = TC_IER_LDRBS;
00358             /* Reset and enable the timer counter for TC capture channel  */
00359             TC_CAPTURE_BASE->TC_CHANNEL[TC_CAPTURE_CHANNEL].TC_CCR =  TC_CCR_CLKEN | 
00360                         TC_CCR_SWTRG;
00361             break ;
00362         default :
00363             /* Set waveform configuration #n */
00364             if ( (ucKey >= '0') && (ucKey <= ('0' + numConfigurations - 1 )) ) {
00365                 if ( !_dwCaptured_pulses ) {
00366                     configuration = ucKey - '0' ;
00367                     TcWaveformInitialize() ;
00368                 } else {
00369                     printf( "In capturing ... , press 's' to stop capture first \n\r" ) ;
00370                 }
00371             }
00372             break ;
00373         }
00374     }
00375 }
00376 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines