text: /**************************************************************************//**
   * @file     main.c
   * @version  V2.00
   * $Revision: 3 $
   * $Date: 15/04/10 6:02p $
   * @brief    M071R_M071S Series Timer Driver Sample Code
   *
   * @note
   * Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
   ******************************************************************************/
  #include <stdio.h>
  #include "NuMicro.h"
  
  #define PLL_CLOCK           72000000
  
  
  /*---------------------------------------------------------------------------------------------------------*/
  /* Global Interface Variables Declarations                                                                 */
  /*---------------------------------------------------------------------------------------------------------*/
  volatile uint32_t g_au32TMRINTCount[4] = {0};
  
  
  /**
   * @brief       Timer0 IRQ
   *
   * @param       None
   *
   * @return      None
   *
   * @details     The Timer0 default IRQ, declared in startup_NUC2201.s.
   */
  void TMR0_IRQHandler(void)
  {
      /* Clear Timer0 time-out interrupt flag */
      TIMER_ClearIntFlag(TIMER0);
  
      g_au32TMRINTCount[0]++;
  }
  
  /**
   * @brief       Timer1 IRQ
   *
   * @param       None
   *
   * @return      None
   *
   * @details     The Timer1 default IRQ, declared in startup_NUC2201.s.
   */
  void TMR1_IRQHandler(void)
  {
      /* Clear Timer1 time-out interrupt flag */
      TIMER_GetIntFlag(TIMER1);
  
      g_au32TMRINTCount[1]++;
  }
  
  /**
   * @brief       Timer2 IRQ
   *
   * @param       None
   *
   * @return      None
   *
   * @details     The Timer2 default IRQ, declared in startup_NUC2201.s.
   */
  void TMR2_IRQHandler(void)
  {
      if(TIMER_GetCaptureIntFlag(TIMER2) == 1) {
          /* Clear Timer2 capture interrupt flag */
          TIMER_ClearCaptureIntFlag(TIMER2);
  
          g_au32TMRINTCount[2]++;
      }
  }
  
  /**
   * @brief       Timer3 IRQ
   *
   * @param       None
   *
   * @return      None
   *
   * @details     The Timer3 default IRQ, declared in startup_NUC2201.s.
   */
  void TMR3_IRQHandler(void)
  {
      /* Clear Timer3 time-out interrupt flag */
      TIMER_GetIntFlag(TIMER3);
  
      g_au32TMRINTCount[3]++;
  }
  
  void SYS_Init(void)
  {
      /*---------------------------------------------------------------------------------------------------------*/
      /* Init System Clock                                                                                       */
      /*---------------------------------------------------------------------------------------------------------*/
      /* Enable Internal RC 22.1184MHz clock */
      CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
  
      /* Waiting for Internal RC clock ready */
      CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
  
      /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
      CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
  
      /* Enable external XTAL 12MHz clock */
      CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
  
      /* Waiting for clock ready */
      CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
  
      /* Set core clock as PLL_CLOCK from PLL */
      CLK_SetCoreClock(PLL_CLOCK);
      
      /* Enable UART module clock */
      CLK_EnableModuleClock(UART0_MODULE);    
      
      /* Select UART module clock source */
      CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
  
      /* Enable Timer 0~3 module clock */
      CLK_EnableModuleClock(TMR0_MODULE);    
      CLK_EnableModuleClock(TMR2_MODULE);    
      CLK_EnableModuleClock(TMR3_MODULE);    
  
      /* Select Timer 0~3 module clock source */
      CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HXT, NULL);
      CLK_SetModuleClock(TMR2_MODULE, CLK_CLKSEL1_TMR2_S_HCLK, NULL);
      CLK_SetModuleClock(TMR3_MODULE, CLK_CLKSEL1_TMR3_S_HXT, NULL);
  
      /*---------------------------------------------------------------------------------------------------------*/
      /* Init I/O Multi-function                                                                                 */
      /*---------------------------------------------------------------------------------------------------------*/
      /* Set PB multi-function pins for UART0 RXD, TXD */
      SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
      SYS->GPB_MFP |= (SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD);
  
      /* Set PB multi-function pins for TM0, TM2, TM3 and TM2_EXT */
      SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB8_Msk | SYS_GPB_MFP_PB10_Msk | 
                        SYS_GPB_MFP_PB11_Msk | SYS_GPB_MFP_PB2_Msk);
      SYS->GPB_MFP |= (SYS_GPB_MFP_PB8_TM0 | SYS_GPB_MFP_PB10_TM2 | 
                       SYS_GPB_MFP_PB11_TM3 | SYS_GPB_MFP_PB2_TM2_EXT);
  
      SYS->ALT_MFP  &= ~( SYS_ALT_MFP_PB8_Msk | SYS_ALT_MFP_PB10_Msk | SYS_ALT_MFP_PB11_Msk |
                          SYS_ALT_MFP_PB2_Msk);
      SYS->ALT_MFP  |= (SYS_ALT_MFP_PB8_TM0 | SYS_ALT_MFP_PB10_TM2 |SYS_ALT_MFP_PB11_TM3 |
                        SYS_ALT_MFP_PB2_TM2_EXT);
      SYS->ALT_MFP2 &= ~SYS_ALT_MFP2_PB2_TM2_Msk;
      SYS->ALT_MFP2 |= SYS_ALT_MFP2_PB2_TM2_EXT;
  }
  
  void UART0_Init(void)
  {
      /*---------------------------------------------------------------------------------------------------------*/
      /* Init UART                                                                                               */
      /*---------------------------------------------------------------------------------------------------------*/
      /* Reset UART0 */
      SYS_ResetModule(UART0_RST);
  
      /* Configure UART0 and set UART0 Baudrate */
      UART_Open(UART0, 115200);
  }
  
  /*---------------------------------------------------------------------------------------------------------*/
  /*  MAIN function                                                                                          */
  /*---------------------------------------------------------------------------------------------------------*/
  int main(void)
  {
      volatile uint32_t u32InitCount;
      uint32_t au32CAPValus[10];
  
      /* Unlock protected registers */
      SYS_UnlockReg();
  
      /* Init System, peripheral clock and multi-function I/O */
      SYS_Init();
  
      /* Lock protected registers */
      SYS_LockReg();
  
      /* Init UART0 for printf */
      UART0_Init();
  
      printf("\n\nCPU @ %d Hz\n", SystemCoreClock);
      printf("+---------------------------------------------------+\n");
      printf("|    Timer External Capture Function Sample Code    |\n");
      printf("+---------------------------------------------------+\n\n");
  
      printf("# Timer Settings:\n");
      printf("  Timer0: Clock source is 12 MHz; Toggle-output mode and frequency is 500 Hz.\n");
      printf("  Timer3: Clock source is 12 MHz; Toggle-output mode and frequency is 1 Hz.\n");
      printf("  Timer2: Clock source is HCLK(72 MHz); Continuous counting mode; TCMP is 0xFFFFFF;\n");
      printf("          Counter pin enable; Capture pin and capture interrupt enable;\n");
      printf("# Generate 500 Hz frequency from TM0 and connect TM0 pin to Timer2 counter pin.\n");
      printf("# Generate 1 Hz frequency from TM3 and connect TM3 pin to TM2_EXT capture pin.\n");
      printf("# Get 500 event counts from Timer2 counter pin when each TM2_EXT pin interrupt occurred.\n\n");
  
      /* Initial Timer0 and Timer3 default setting */
      TIMER_Open(TIMER0, TIMER_TOGGLE_MODE, 1000);
      TIMER_Open(TIMER3, TIMER_TOGGLE_MODE, 2);
  
      /* Initial Timer2 default setting */
      TIMER_Open(TIMER2, TIMER_CONTINUOUS_MODE, 1);
  
      /* Configure Timer2 setting for external counter input and capture function */
      TIMER_SET_PRESCALE_VALUE(TIMER2, 0);
      TIMER_SET_CMP_VALUE(TIMER2, 0xFFFFFF);
      TIMER_EnableEventCounter(TIMER2, TIMER_COUNTER_FALLING_EDGE);
      TIMER_EnableCapture(TIMER2, TIMER_CAPTURE_FREE_COUNTING_MODE, TIMER_CAPTURE_FALLING_EDGE);
      TIMER_EnableCaptureInt(TIMER2);
  
      /* Enable Timer2 NVIC */
      NVIC_EnableIRQ(TMR2_IRQn);
  
      /* Clear Timer2 interrupt counts to 0 */
      u32InitCount = g_au32TMRINTCount[2] = 0;
  
      /* Start Timer0, Timer2 and Timer3 counting */
      TIMER_Start(TIMER0);
      TIMER_Start(TIMER2);
      TIMER_Start(TIMER3);
  
      /* Check TM2_EXT interrupt counts */
      while(1) {
          if(g_au32TMRINTCount[2] != u32InitCount) {
              au32CAPValus[u32InitCount] = TIMER_GetCaptureData(TIMER2);
              printf("[%2d] - %4d\n", g_au32TMRINTCount[2], au32CAPValus[u32InitCount]);
              if(u32InitCount > 1) {
                  if((au32CAPValus[u32InitCount] - au32CAPValus[u32InitCount - 1]) != 500) {
                      printf("*** FAIL ***\n");
                      while(1);
                  }
              }
              u32InitCount = g_au32TMRINTCount[2];
          }
          
          if(u32InitCount == 10)
              break;
      }
  
      /* Stop Timer0, Timer2 and Timer3 counting */
      TIMER_Close(TIMER0);
      TIMER_Close(TIMER2);
      TIMER_Close(TIMER3);
  
      printf("*** PASS ***\n");
  
      while(1);
  }
  
  /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
  