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