#include "lisoc_test.h"
#include "timer.h"
#include "timer_test.h"
#include "rcc.h"

#define TIMER0_MS_COUNT  100u
#define TIMER1_MS_COUNT  200u
#define TIMER2_MS_COUNT  300u


#define INT_TIMEOUT 1000 

void timer0_test(uint32_t mode)
{
  uint32_t int_tmo;
  uint16_t i = 0;
  uint8_t mode_test = SUCCESS;  
  // disable the timer, configure timer mode as userdefine,
  timer_StopTimer(LISOC_TIMER0);
  timer_SetMode(LISOC_TIMER0, mode);
  // disable the timer clock
  rcc_PerDisable(TIMER0_RCC_PERn);
  // configure the initial value of counter
  timer_Setload(LISOC_TIMER0, LISOC_TIMER_CLK / 1000u * TIMER0_MS_COUNT);
  // enable timer
  timer_StartTimer(LISOC_TIMER0);
  // enable the timer clock
  rcc_PerEnable(TIMER0_RCC_PERn);

  SysTick1msStart = SysTick1msCount;
  // wating the interrup when counter down to zero
  int_tmo = SysTick1msCount + INT_TIMEOUT + 50;
  while (IS_TIME_NOT_REACHED(int_tmo)) {
    if ((timer_StatusIRQ(LISOC_TIMER0) & 0x1) == TIMER_INT_ACTIVE) {
      if(i == 0)   SysTick1msEnd = SysTick1msCount;
      i++;
      timer_ClearIRQ(LISOC_TIMER0);     // clear timer 0 IRQ;
    }
  }
  if(mode == TIMER_USERMODE && (i != INT_TIMEOUT/TIMER0_MS_COUNT))
    mode_test = FAILURE;
  else if(mode == TIMER_FREEMODE && (i != 1))
    mode_test = FAILURE;
  //disable the timer, configure timer mode as userdefine,
  timer_StopTimer(LISOC_TIMER0); 
  if((TIMER0_MS_COUNT*1.1 >= (SysTick1msEnd - SysTick1msStart)) && (TIMER0_MS_COUNT*0.97 <= (SysTick1msEnd - SysTick1msStart)) && (mode_test == SUCCESS))
    debug("timer0 test\t\t\t\t\tOK.\n",SysTick1msEnd - SysTick1msStart);
  else
    debug("timer0 test\t\t\t\t\tNG.\n",SysTick1msEnd - SysTick1msStart,mode_test);

}

void timer1_test(uint32_t mode)
{
  uint32_t int_tmo;
  uint16_t i = 0;
  uint8_t mode_test = SUCCESS;  
  // disable the timer, configure timer mode as userdefine,
  timer_StopTimer(LISOC_TIMER1);
  timer_SetMode(LISOC_TIMER1, mode);
  // disable the timer clock
  rcc_PerDisable(TIMER1_RCC_PERn);
  // configure the initial value of counter
  timer_Setload(LISOC_TIMER1, LISOC_TIMER_CLK / 1000u * TIMER1_MS_COUNT);
  // enable timer
  timer_StartTimer(LISOC_TIMER1);
  // enable the timer clock
  rcc_PerEnable(TIMER1_RCC_PERn);

  SysTick1msStart = SysTick1msCount;
  // wating the interrup when counter down to zero
  int_tmo = SysTick1msCount + INT_TIMEOUT + 50;
  while (IS_TIME_NOT_REACHED(int_tmo)) {
    if ((timer_StatusIRQ(LISOC_TIMER1) & 0x1) == TIMER_INT_ACTIVE) {
      if(i == 0)   SysTick1msEnd = SysTick1msCount;
      i++;
      timer_ClearIRQ(LISOC_TIMER1);     // clear timer 0 IRQ;
    }
  }
  if(mode == TIMER_USERMODE && (i != INT_TIMEOUT/TIMER1_MS_COUNT))
    mode_test = FAILURE;
  else if(mode == TIMER_FREEMODE && (i != 1))
    mode_test = FAILURE;
  //disable the timer, configure timer mode as userdefine,
  timer_StopTimer(LISOC_TIMER1); 
  if((TIMER1_MS_COUNT*1.1 >= (SysTick1msEnd - SysTick1msStart)) && (TIMER1_MS_COUNT*.098 <= (SysTick1msEnd - SysTick1msStart)) && (mode_test == SUCCESS))
    debug("timer1 test\t\t\t\t\tOK.\n",SysTick1msEnd - SysTick1msStart);
  else
    debug("timer1 test\t\t\t\t\tNG.\n",SysTick1msEnd - SysTick1msStart,mode_test,i);
}


void timer2_test(uint32_t mode)
{
  uint32_t int_tmo;
  uint16_t i = 0;
  uint8_t mode_test = SUCCESS;  
  // disable the timer, configure timer mode as userdefine,
  timer_StopTimer(LISOC_TIMER2);
  timer_SetMode(LISOC_TIMER2, mode);
  // disable the timer clock
  rcc_PerDisable(TIMER2_RCC_PERn);
  // configure the initial value of counter
  timer_Setload(LISOC_TIMER2, LISOC_TIMER_CLK / 1000u * TIMER2_MS_COUNT);
  // enable timer
  timer_StartTimer(LISOC_TIMER2);
  // enable the timer clock
  rcc_PerEnable(TIMER2_RCC_PERn);

  SysTick1msStart = SysTick1msCount;
  // wating the interrup when counter down to zero
  int_tmo = SysTick1msCount + INT_TIMEOUT + 50;
  while (IS_TIME_NOT_REACHED(int_tmo)) {
    if ((timer_StatusIRQ(LISOC_TIMER2) & 0x1) == TIMER_INT_ACTIVE) {
      if(i == 0)   SysTick1msEnd = SysTick1msCount;
      i++;
      timer_ClearIRQ(LISOC_TIMER2);     // clear timer 0 IRQ;
    }
  }
  if(mode == TIMER_USERMODE && (i != INT_TIMEOUT/TIMER2_MS_COUNT))
    mode_test = FAILURE;
  else if(mode == TIMER_FREEMODE && (i != 1))
    mode_test = FAILURE;
  //disable the timer, configure timer mode as userdefine,
  timer_StopTimer(LISOC_TIMER2); 
  if((TIMER2_MS_COUNT*1.03 >= (SysTick1msEnd - SysTick1msStart)) && (TIMER2_MS_COUNT*0.97 <= (SysTick1msEnd - SysTick1msStart)) && (mode_test == SUCCESS))
    debug("timer2 test\t\t\t\t\tOK.\n",SysTick1msEnd - SysTick1msStart);
  else
    debug("timer2 test\t\t\t\t\tNG.\n",SysTick1msEnd - SysTick1msStart,mode_test,i);
}

void timer_test(void)
{
  timer0_test(TIMER_USERMODE);
  timer1_test(TIMER_USERMODE);
  timer2_test(TIMER_FREEMODE);//one shot
}

