gonzui


Format: Advanced Search

tkernel_2/kernel/sysdepend/device/tef_em1d/tkdev_timer.hbare sourcepermlink (0.03 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: 
   15: /*
   16:  *      tkdev_timer.h (EM1-D512)
   17:  *      Hardware-Dependent Timer Processing
   18:  */
   19: 
   20: #ifndef _TKDEV_TIMER_
   21: #define _TKDEV_TIMER_
   22: 
   23: #include <tk/syslib.h>
   24: #include <sys/sysinfo.h>
   25: #include "tkdev_conf.h"
   26: 
   27: /*
   28:  * Range of settable period  (microseconds)
   29:  */
   30: #define MIN_TIMER_PERIOD        10
   31: #define MAX_TIMER_PERIOD        50000
   32: 
   33: /*
   34:  * Setting up timer
   35:  */
   36: Inline void init_hw_timer( void )
   37: {
   38:         UW     n, d, imask;
   39: 
   40:         DI(imask);
   41: 
   42:         /* stop timer */
   43:         out_w(TI_OP, 0);
   44: 
   45:         /* choose clock */
   46:         out_w(TI0TIN_SEL, (in_w(TI0TIN_SEL) & ~3) | TITIN_PLL3);
   47:         d = in_w(DIVTIMTIN);
   48: 
   49:         /* supply clock */
   50:         out_w(GCLKCTRL3ENA, in_w(GCLKCTRL3ENA) | TI0_TIN_GCK);
   51:         out_w(GCLKCTRL3,    in_w(GCLKCTRL3)    | TI0_TIN_GCK);
   52: 
   53:         /* enable timer */
   54:         out_w(TI_OP, TM_EN);
   55:         while ( (in_w(TI_SCLR) & TM_SCLR) != 0 );
   56:         WaitUsec(100);
   57: 
   58:         /* set counter */
   59:         n = (TIMER_PERIOD * TIN_CLK(d)) / 1000000 - 1;
   60:         out_w(TI_SET, n);
   61: 
   62:         /* start timer count */
   63:         out_w(TI_OP, TO_EN|TSTART|TM_EN);
   64: 
   65:         EI(imask);
   66: }
   67: 
   68: /*
   69:  * Timer start processing
   70:  *      Initialize timer, and start periodic timer interrupt.
   71:  */
   72: Inline void start_hw_timer( void )
   73: {
   74: IMPORT  void     timer_handler_startup( void );
   75: 
   76:         /* set up timer */
   77:         init_hw_timer();
   78: 
   79:         /* define interrupt handler */
   80:         define_inthdr(VECNO_TIMER, timer_handler_startup);
   81: 
   82:         /* enable timer interrupt */
   83:         SetIntMode(VECNO_TIMER, IM_ENA);
   84:         ClearInt(VECNO_TIMER);
   85:         EnableInt(VECNO_TIMER);
   86: }
   87: 
   88: /*
   89:  * Clear timer interrupt
   90:  *      clear timer interrupt. Depending on hardware, we have to clear
   91:  *      the request of the timer interrupt at the beginning of the
   92:  *      timer handler, or clear it at the end.
   93:  *      clear_hw_timer_interrupt() is called at the beginning of the
   94:  *      timer interrupt handler.
   95:  *      end_of_hw_timer_interrupt() is called at the end.
   96:  *      Either one of them, or both are used according hardware requirements.
   97:  */
   98: Inline void clear_hw_timer_interrupt( void )
   99: {
  100:         /* Mask the current interrupt to allow multiple interrupts */
  101:         out_w(IT0_IDS1, IRQM(IRQ_TIMER));
  102: 
  103:         /* Clear timer interrupt */
  104:         out_w(IT0_IIR, IRQM(IRQ_TIMER));
  105: }
  106: Inline void end_of_hw_timer_interrupt( void )
  107: {
  108:         /* Enable the current interrupt */
  109:         out_w(IT0_IEN1, IRQM(IRQ_TIMER));
  110: }
  111: 
  112: /*
  113:  * Timer stop processing
  114:  *      stop timer
  115:  *      called during system shutdown
  116:  */
  117: Inline void terminate_hw_timer( void )
  118: {
  119:         UW     imask;
  120: 
  121:         /* disable timer interrupt */
  122:         DisableInt(VECNO_TIMER);
  123: 
  124:         DI(imask);
  125: 
  126:         /* stop timer */
  127:         out_w(TI_OP, 0);
  128: 
  129:         /* stop clock */
  130:         out_w(GCLKCTRL3, in_w(GCLKCTRL3) & ~TI0_TIN_GCK);
  131: 
  132:         EI(imask);
  133: }
  134: 
  135: /*
  136:  * Obtain the elapsed time (nanoseconds) from the last timer interrupt
  137:  * To compensate for the possibility that the timer interrupt may have
  138:  * occurred during the interval when the interrupt was disabled,
  139:  * we calculate the time in the following range:
  140:  *              0 <= elapsed time < TIMER_PERIOD * 2
  141:  */
  142: Inline UINT get_hw_timer_nsec( void )
  143: {
  144:         UW     ofs, max, ovf, imask, d;
  145: 
  146:         DI(imask);
  147: 
  148:         d = in_w(DIVTIMTIN);
  149: 
  150:         max = in_w(TI_SET);
  151:         do {
  152:                 ovf = in_w(IT0_RAW1) & IRQM(IRQ_TIMER);
  153:                 ofs = in_w(TI_RCR);
  154:         } while ( ovf != (in_w(IT0_RAW1) & IRQM(IRQ_TIMER)) );
  155:         if ( ovf != 0 ) ofs += max + 1;
  156: 
  157:         EI(imask);
  158: 
  159:         return ofs * 1000000000LL / TIN_CLK(d);
  160: }
  161: 
  162: /*
  163:  * Similar to the function as above, but returns value in microseconds.
  164:  */
  165: Inline UINT get_hw_timer_usec( void )
  166: {
  167:         UW     ofs, max, ovf, imask, d;
  168: 
  169:         DI(imask);
  170: 
  171:         d = in_w(DIVTIMTIN);
  172: 
  173:         max = in_w(TI_SET);
  174:         do {
  175:                 ovf = in_w(IT0_RAW1) & IRQM(IRQ_TIMER);
  176:                 ofs = in_w(TI_RCR);
  177:         } while ( ovf != (in_w(IT0_RAW1) & IRQM(IRQ_TIMER)) );
  178:         if ( ovf != 0 ) ofs += max + 1;
  179: 
  180:         EI(imask);
  181: 
  182:         return (ofs + 1) * 1000000LL / TIN_CLK(d);
  183: }
  184: 
  185: #endif /* _TKDEV_TIMER_ */