SAM3S8/SD8 Software Package: examples/tc_capture_waveform/main.c Source File

SAM3S8/SD8 Software Package 1.2

# main.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------------
    00002  *         ATMEL Microcontroller Software Support
    00003  * ----------------------------------------------------------------------------
    00004  * Copyright (c) 2010, 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 tc_capture_waveform TC Capture Waveform Example
    00032  *
    00033  * \section Purpose
    00034  *
    00035  * This example indicate how to use TC in capture mode to measure the pulse frequency
    00036  * and count the total pulse number of an external signal injected on TIOA pin.
    00037  *
    00038  * \section Requirements
    00039  *
    00040  * This package can be used with SAM3S evaluation kits.
    00041  * It generates a waveform on TC0 channel 1 TIOA1 {PIO_PA15), and it capture wave
    00042  * from channel 2 TIOA2 (PIO_PA26). These 2 pins could be found on board extension
    00043  * header. To measure the wavefrom on TIOA1, you shall connect PIO_PA15 to PIO_PA26,
    00044  * configure PIO_PA15 as output pin and PIO_PA26 as input pin.
    00045  *
    00046  * \section Descriptions
    00047  *
    00048  * This example shows how to configure TC in waveform and capture mode.
    00049  * In capture mode, pulse signal (from TIOA1) is set as an input to TIOA2, RA and RB will be
    00050  * loaded when 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 pulse frequency
    00052  * and total pulse number are output on UART.
    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 1 as waveform output.
    00058  * <li>Configure TC channel 2 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  * -# Compile the application.
    00069  * -# Connect the UART port of the evaluation board to the computer and open
    00070  * it in a terminal.
    00071  *    - Settings: 115200 bauds, 8 bits, 1 stop bit, no parity, no flow control.
    00072  * -# Download the program inside the evaluation board and run it. Please refer to
    00073  *    <a href="http://www.atmel.com/dyn/resources/prod_documents/6421B.pdf">
    00074  *    SAM-BA User Guide</a>, the
    00075  *    <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6310.pdf">
    00076  *    GNU-Based Software Development</a> application note or to the
    00077  *    <a href="http://www.iar.com/website1/1.0.1.0/78/1/">
    00078  *    IAR EWARM User and reference guides</a>, depending on your chosen solution.
    00079  * -# Upon startup, the application will output the following line on the terminal:
    00080  *    \code
    00081  *     -- TC capture waveform example  xxx --
    00082  *     -- xxxxxx-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 =  120 Hz, Duty Cycle = 30%
    00091  *       1: Set Frequency =  375 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 0 channel 2
    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 /**
    00107  * \file
    00108  *
    00109  * This file contains all the specific code for the tc capture waveform example.
    00110  */
    00111
    00112
    00113 /*----------------------------------------------------------------------------
    00114  *        Headers
    00115  *----------------------------------------------------------------------------*/
    00116
    00117 #include "board.h"
    00118
    00119 #include <stdio.h>
    00120
    00121 /*----------------------------------------------------------------------------
    00122  *        Local definitions
    00123  *----------------------------------------------------------------------------*/
    00124 #define PIN_TC0_TIOA1    {PIO_PA15, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
    00125 #define PIN_TC0_TIOA2    {PIO_PA26, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
    00126
    00127 /*----------------------------------------------------------------------------
    00128  *        Types
    00129  *----------------------------------------------------------------------------*/
    00130 /** Describes a possible Timer configuration as waveform mode */
    00131 struct WaveformConfiguration {
    00132     /** Internal clock signals selection. */
    00133     uint32_t clockSelection;
    00134     /** Waveform frequency (in Hz). */
    00135     uint16_t frequency;
    00136     /** Duty cycle in percent (positive)*/
    00137     uint16_t dutyCycle;
    00138 };
    00139
    00140 /*----------------------------------------------------------------------------
    00141  *        Local variables
    00142  *----------------------------------------------------------------------------*/
    00143
    00144 /** PIOs for TC0 */
    00145 static const Pin pTcPins[] = {PIN_TC0_TIOA1, PIN_TC0_TIOA2};
    00146
    00147 /** TC waveform configurations */
    00148 static const struct WaveformConfiguration waveformConfigurations[] = {
    00149     {TC_CMR_TCCLKS_TIMER_CLOCK4, 178, 30},
    00150     {TC_CMR_TCCLKS_TIMER_CLOCK3, 375, 50},
    00151     {TC_CMR_TCCLKS_TIMER_CLOCK3, 800, 75},
    00152     {TC_CMR_TCCLKS_TIMER_CLOCK2, 1000, 80},
    00153     {TC_CMR_TCCLKS_TIMER_CLOCK1, 4000, 55}
    00154 };
    00155
    00156 /** Current wave configuration*/
    00157 static uint8_t configuration = 0;
    00158
    00159 /** Number of available wave configurations */
    00160 const uint8_t numConfigurations = sizeof(waveformConfigurations)
    00161                                         / sizeof(struct WaveformConfiguration);
    00162 /** Capture status*/
    00163 static uint32_t _dwCaptured_pulses;
    00164 static uint32_t _dwCaptured_ra ;
    00165 static uint32_t _dwCaptured_rb ;
    00166
    00167 /*----------------------------------------------------------------------------
    00168  *        Local functions
    00169  *----------------------------------------------------------------------------*/
    00170
    00171 /**
    00172  * \brief Displays the user menu on the terminal.
    00173  */
    00174 static void DisplayMenu(void)
    00175 {
    00176     uint8_t i;
    00177     printf("\n\rMenu :\n\r");
    00178     printf("------\n\r");
    00179
    00180     printf("  Output waveform property:\n\r");
    00181     for (i = 0; i < numConfigurations; i++) {
    00182         printf("  %d: Set Frequency = %4u Hz, Duty Cycle = %2u%%\n\r",
    00183                    i,
    00184                    (unsigned int)waveformConfigurations[i].frequency,
    00185                    (unsigned int)waveformConfigurations[i].dutyCycle);
    00186     }
    00187     printf("  -------------------------------------------\n\r");
    00188     printf("  c: Capture waveform from TC 0 channel 2\n\r");
    00189     printf("  s: Stop capture and display informations what have been captured \n\r");
    00190     printf("  h: Display menu \n\r");
    00191     printf("------\n\r\n\r");
    00192 }
    00193
    00194
    00195 /**
    00196  * \brief Interrupt handler for the TC0 channel 2.
    00197  */
    00198 void TC2_IrqHandler( void )
    00199 {
    00200     uint32_t status ;
    00201     status = REG_TC0_SR2 ;
    00202
    00203     if ( (status & TC_SR_LDRBS) == TC_SR_LDRBS )
    00204     {
    00205         _dwCaptured_pulses++ ;
    00206         _dwCaptured_ra = REG_TC0_RA2 ;
    00207         _dwCaptured_rb = REG_TC0_RB2 ;
    00208     }
    00209 }
    00210
    00211 /**
    00212  * \brief Configure clock, frequency and dutyclcle in wave mode.
    00213  */
    00214 static void TcWaveformConfigure(void)
    00215 {
    00216     const uint32_t divisors[5] = {2, 8, 32, 128, BOARD_MCK / 32768};
    00217     uint32_t ra, rc;
    00218     /*  Set channel 1 as waveform mode*/
    00219     REG_TC0_CMR1 = waveformConfigurations[configuration].clockSelection  /* Waveform Clock Selection */
    00220                    | TC_CMR_WAVE                                        /* Waveform mode is enabled */
    00221                    | TC_CMR_ACPA_SET                                    /* RA Compare Effect: set */
    00222                    | TC_CMR_ACPC_CLEAR                                  /* RC Compare Effect: clear */
    00223                    | TC_CMR_CPCTRG;                                     /* UP mode with automatic trigger on RC Compare */
    00224     rc = (BOARD_MCK / divisors[waveformConfigurations[configuration].clockSelection]) / waveformConfigurations[configuration].frequency;
    00225     REG_TC0_RC1 = rc;
    00226     ra = (100 - waveformConfigurations[configuration].dutyCycle) * rc / 100;
    00227     REG_TC0_RA1 = ra;
    00228 }
    00229
    00230 /**
    00231  * \brief Configure TC0 channel 1 as waveform operating mode.
    00232  */
    00233 static void TcWaveformInitialize(void)
    00234 {
    00235     volatile uint32_t dummy;
    00236     /* Configure the PMC to enable the Timer Counter clock for TC0 channel 1. */
    00237     PMC_EnablePeripheral(ID_TC1);
    00238     /*  Disable TC clock */
    00239     REG_TC0_CCR1 = TC_CCR_CLKDIS;
    00240     /*  Disable interrupts */
    00241     REG_TC0_IDR1 = 0xFFFFFFFF;
    00242     /*  Clear status register */
    00243     dummy = REG_TC0_SR1;
    00244     /* Configure waveform frequency and duty cycle */
    00245     TcWaveformConfigure();
    00246     /* Enable TC0 channel 1 */
    00247     REG_TC0_CCR1 =  TC_CCR_CLKEN | TC_CCR_SWTRG ;
    00248     printf ("Start waveform: Frequency = %d Hz,Duty Cycle = %2d%%\n\r",
    00249             waveformConfigurations[configuration].frequency,
    00250             waveformConfigurations[configuration].dutyCycle);
    00251 }
    00252
    00253 /**
    00254  * \brief Configure TC0 channel 2 as capture operating mode.
    00255  */
    00256 static void TcCaptureInitialize(void)
    00257 {
    00258     volatile uint32_t dummy;
    00259     /* Configure the PMC to enable the Timer Counter clock TC0 channel 2.*/
    00260     PMC_EnablePeripheral(ID_TC2);
    00261     /*  Disable TC clock */
    00262     REG_TC0_CCR2 = TC_CCR_CLKDIS;
    00263     /*  Disable interrupts */
    00264     REG_TC0_IDR2 = 0xFFFFFFFF;
    00265     /*  Clear status register */
    00266     dummy = REG_TC0_SR2;
    00267     /*  Set channel 2 as capture mode */
    00268     REG_TC0_CMR2 = (TC_CMR_TCCLKS_TIMER_CLOCK2    /* Clock Selection */
    00269                    | TC_CMR_LDRA_RISING           /* RA Loading Selection: rising edge of TIOA */
    00270                    | TC_CMR_LDRB_FALLING          /* RB Loading Selection: falling edge of TIOA */
    00271                    | TC_CMR_ABETRG                /* External Trigger Selection: TIOA */
    00272                    | TC_CMR_ETRGEDG_FALLING );    /* External Trigger Edge Selection: Falling edge */
    00273 }
    00274
    00275 /*----------------------------------------------------------------------------
    00276  *         Global functions
    00277  *----------------------------------------------------------------------------*/
    00278 /**
    00279  * \brief Application entry point for tc_capture_waveform example.
    00280  *
    00281  * \return Unused (ANSI-C compatibility).
    00282  */
    00283 int main(void)
    00284 {
    00285     uint8_t ucKey ;
    00286     uint16_t frequence, dutyCycle ;
    00287
    00288     /* Disable watchdog */
    00289     WDT_Disable( WDT ) ;
    00290
    00291     /* Output example information */
    00292     printf( "-- TC capture waveform example %s --\n\r", SOFTPACK_VERSION ) ;
    00293     printf( "-- %s\n\r", BOARD_NAME ) ;
    00294     printf( "-- Compiled: %s %s --\n\r", __DATE__, __TIME__ ) ;
    00295
    00296     /* Configure PIO Pins for TC0 */
    00297     PIO_Configure( pTcPins, PIO_LISTSIZE( pTcPins ) ) ;
    00298
    00299     /* Configure TC0 channel 1 as waveform operating mode */
    00300     printf("Configure TC0 channel 1 as waveform operating mode \n\r");
    00301     TcWaveformInitialize() ;
    00302     /* Configure TC0 channel 2 as capture operating mode */
    00303     printf("Configure TC0 channel 2 as capture operating mode \n\r");
    00304     TcCaptureInitialize() ;
    00305
    00306     printf("Please Connect PA15 to PA26 on SAM3S-EK for wave capture test.\n\r");
    00307
    00308     /* Configure TC interrupts for TC0 channel 2 only */
    00309     NVIC_DisableIRQ( TC2_IRQn ) ;
    00310     NVIC_ClearPendingIRQ( TC2_IRQn ) ;
    00311     NVIC_SetPriority( TC2_IRQn, 0 ) ;
    00312     NVIC_EnableIRQ( TC2_IRQn ) ;
    00313
    00314     /* Display menu */
    00315     DisplayMenu() ;
    00316
    00317     while ( 1 )
    00318     {
    00319         ucKey = UART_GetChar() ;
    00320
    00321         switch ( ucKey )
    00322         {
    00323             case 'h' :
    00324                 DisplayMenu() ;
    00325             break ;
    00326
    00327             case 's' :
    00328                 if ( _dwCaptured_pulses )
    00329                 {
    00330                     REG_TC0_IDR2 = TC_IER_LDRBS ;
    00331                     printf( "Captured %u pulses from TC0 channel 2, RA = %u, RB = %u \n\r",
    00332                             (unsigned int)_dwCaptured_pulses, (unsigned int)_dwCaptured_ra, (unsigned int)_dwCaptured_rb ) ;
    00333
    00334                     frequence = (BOARD_MCK / 8) / _dwCaptured_rb;
    00335                     dutyCycle = (_dwCaptured_rb - _dwCaptured_ra) * 100 / _dwCaptured_rb;
    00336                     printf( "Captured wave frequency = %d Hz, Duty cycle = %d%% \n\r", frequence, dutyCycle ) ;
    00337
    00338                     _dwCaptured_pulses = 0 ;
    00339                     _dwCaptured_ra = 0 ;
    00340                     _dwCaptured_rb = 0 ;
    00341                 }
    00342                 else
    00343                 {
    00344                     printf( "No waveform has been captured\n\r" ) ;
    00345                 }
    00346                 printf( "\n\rPress 'h' to display menu\n\r" ) ;
    00347             break ;
    00348
    00349             case 'c' :
    00350                 printf ("Start capture, press 's' to stop \n\r");
    00351                 REG_TC0_IER2 = TC_IER_LDRBS;
    00352                 /* Reset and enable the tiimer counter for TC0 channel 2 */
    00353                 REG_TC0_CCR2 =  TC_CCR_CLKEN | TC_CCR_SWTRG;
    00354             break ;
    00355             default :
    00356                 /* Set waveform configuration #n */
    00357                 if ( (ucKey >= '0') && (ucKey <= ('0' + numConfigurations - 1)) )
    00358                 {
    00359                     if ( !_dwCaptured_pulses )
    00360                     {
    00361                         configuration = ucKey - '0' ;
    00362                         TcWaveformInitialize() ;
    00363                     }
    00364                     else
    00365                     {
    00366                         printf( "In capturing ... , press 's' to stop capture first \n\r" ) ;
    00367                     }
    00368                 }
    00369             break ;
    00370         }
    00371     }
    00372 }

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines