text: /**************************************************************************//**
   * @file     main.c
   * @version  V3.00
   * @brief    Implement timer1 event counter function to count the external input event.
   *
   * SPDX-License-Identifier: Apache-2.0
   * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
   ******************************************************************************/
  #include <stdio.h>
  #include "NuMicro.h"
  
  /*---------------------------------------------------------------------------------------------------------*/
  /* Global Interface Variables Declarations                                                                 */
  /*---------------------------------------------------------------------------------------------------------*/
  volatile uint32_t g_au32TMRINTCount[4] = {0};
  
  
  /*---------------------------------------------------------------------------------------------------------*/
  /*  Generate Event Counter Source by specify GPIO pin                                                      */
  /*---------------------------------------------------------------------------------------------------------*/
  void GenerateEventCounterSource(uint32_t u32Port, uint32_t u32Pin, uint32_t u32Counts)
  {
      while (u32Counts--)
      {
          GPIO_PIN_DATA(u32Port, u32Pin) = 1;
          GPIO_PIN_DATA(u32Port, u32Pin) = 0;
      }
  }
  
  /**
   * @brief       Timer2 IRQ
   *
   * @param       None
   *
   * @return      None
   *
   * @details     The Timer2 default IRQ, declared in startup_M0564.s.
   */
  void TMR2_IRQHandler(void)
  {
      if (TIMER_GetIntFlag(TIMER2) == 1)
      {
          /* Clear Timer2 time-out interrupt flag */
          TIMER_ClearIntFlag(TIMER2);
  
          g_au32TMRINTCount[2]++;
      }
  }
  
  void SYS_Init(void)
  {
      /*---------------------------------------------------------------------------------------------------------*/
      /* Init System Clock                                                                                       */
      /*---------------------------------------------------------------------------------------------------------*/
      /* Enable HIRC clock */
      CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
  
      /* Waiting for HIRC clock ready */
      CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
  
      /* Switch HCLK clock source to HIRC */
      CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
  
      /*------------------------------------------------------------------------------------------------------*/
      /* Enable Module Clock                                                                                  */
      /*------------------------------------------------------------------------------------------------------*/
      /* Enable peripheral clock */
      CLK_EnableModuleClock(UART0_MODULE);
      CLK_EnableModuleClock(TMR2_MODULE);
  
      /* Peripheral clock source */
      CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HIRC_DIV2, CLK_CLKDIV0_UART(1));
      CLK_SetModuleClock(TMR2_MODULE, CLK_CLKSEL1_TMR2SEL_PCLK1, 0);
  
      /*---------------------------------------------------------------------------------------------------------*/
      /* Init I/O Multi-function                                                                                 */
      /*---------------------------------------------------------------------------------------------------------*/
      /* PB.0 is UART0_RX */
      SYS->GPB_MFPL &= ~SYS_GPB_MFPL_PB0MFP_Msk;
      SYS->GPB_MFPL |= (1 << SYS_GPB_MFPL_PB0MFP_Pos);
      /* PB.1 is UART0_TX */
      SYS->GPB_MFPL &= ~SYS_GPB_MFPL_PB1MFP_Msk;
      SYS->GPB_MFPL |= (1 << SYS_GPB_MFPL_PB1MFP_Pos);
      /* set PC.0 as TM2 */
      SYS->GPC_MFPL &= ~SYS_GPC_MFPL_PC0MFP_Msk;
      SYS->GPC_MFPL |= (5 << SYS_GPC_MFPL_PC0MFP_Pos);
  }
  
  void UART0_Init(void)
  {
      /*---------------------------------------------------------------------------------------------------------*/
      /* Init UART                                                                                               */
      /*---------------------------------------------------------------------------------------------------------*/
      /* Reset UART module */
      SYS_ResetModule(UART0_RST);
  
      /* Configure UART0 and set UART0 Baudrate */
      UART_Open(UART0, 115200);
  }
  
  /*---------------------------------------------------------------------------------------------------------*/
  /*  MAIN function                                                                                          */
  /*---------------------------------------------------------------------------------------------------------*/
  int main(void)
  {
      /* 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("|    Timer2 Event Counter Input Sample Code    |\n");
      printf("+----------------------------------------------+\n\n");
  
      printf("# Timer2 Settings:\n");
      printf("    - Clock source is HCLK      \n");
      printf("    - Continuous counting mode  \n");
      printf("    - Interrupt enable          \n");
      printf("    - Event counter mode enable \n");
      printf("    - Compared value is 56789   \n");
      printf("# Connect PA.11 pin to event counter pin T2(PC.0) and pull PA.11 High/Low to generate T2 event input source.\n\n");
  
      /* Configure PA.11 as GPIO output pin and pull initial pin status to Low */
      SYS->GPA_MFPH &= ~SYS_GPA_MFPH_PA11MFP_Msk;
  
      /* Enable Timer2 NVIC */
      NVIC_EnableIRQ(TMR2_IRQn);
  
      /* Clear Timer2 interrupt counts to 0 */
      g_au32TMRINTCount[2] = 0;
  
      /* Configure Timer2 settings and for event counter application */
      TIMER_Open(TIMER2, TIMER_CONTINUOUS_MODE, 1);
      TIMER_SET_PRESCALE_VALUE(TIMER2, 0);
      TIMER_SET_CMP_VALUE(TIMER2, 56789);
      TIMER_EnableEventCounter(TIMER2, TIMER_COUNTER_FALLING_EDGE);
      TIMER_EnableInt(TIMER2);
  
      /* Start Timer2 counting */
      TIMER_Start(TIMER2);
  
      /* To check if counter value of Timer2 should be 0 while event counter mode is enabled */
      if (TIMER_GetCounter(TIMER2) != 0)
      {
          printf("Default counter value is not 0. (%d)\n", TIMER_GetCounter(TIMER2));
  
          /* Stop Timer2 counting */
          TIMER_Close(TIMER2);
  
          while (1);
      }
  
      printf("Start to check Timer2 counter value ......\n\n");
  
      /* To generate one counter event from PA.11 to T2 pin */
      GenerateEventCounterSource(0, 11, 1);
  
      /* To check if counter value of Timer2 should be 1 */
      while (TIMER_GetCounter(TIMER2) == 0);
  
      if (TIMER_GetCounter(TIMER2) != 1)
      {
          printf("Get unexpected counter value. (%d)\n", TIMER_GetCounter(TIMER2));
  
          /* Stop Timer2 counting */
          TIMER_Close(TIMER2);
  
          while (1);
      }
  
      /* To generate remains counts to T2 pin */
      GenerateEventCounterSource(0, 11, (56789 - 1));
  
      while (1)
      {
          if (g_au32TMRINTCount[2] == 1)
          {
              printf("# Timer2 interrupt event occurred.\n");
              break;
          }
      }
  
      printf("# Get Timer2 event counter value is %d .... ", TIMER_GetCounter(TIMER2));
  
      if (TIMER_GetCounter(TIMER2) == 56789)
      {
          printf("PASS.\n");
      }
      else
      {
          printf("FAIL.\n");
      }
  
      /* Stop Timer2 counting */
      TIMER_Close(TIMER2);
  
      while (1);
  }
  
  /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
  