gonzui


Format: Advanced Search

mtkernel_3/lib/libtk/sysdepend/cpu/rx231/ptimer_rx231.cbare sourcepermlink (0.04 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    micro T-Kernel 3.00.04
    4:  *
    5:  *    Copyright (C) 2006-2021 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.2.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by TRON Forum(http://www.tron.org) at 2021/05/17 .
   10:  *
   11:  *----------------------------------------------------------------------
   12:  */
   13: 
   14: #include <sys/machine.h>
   15: #ifdef CPU_RX231
   16: /*
   17:  *      ptimer_rx231.c
   18:  *
   19:  *      Physical timer (for RX231)
   20:  */
   21: #include <tk/tkernel.h>
   22: #include <tk/syslib.h>
   23: 
   24: #if USE_PTMR
   25: 
   26: typedef struct {
   27:         UW     baddr;              // Register Base Address
   28:         INT    mode;              // Timer mode
   29:         UW     limit;              // Counter Limit
   30:         FP     ptmrhdr;    // Timer Hnadler
   31:         PRI    intptr;            // Interrupt priority
   32:         UINT   intno;            // Interrupt No.
   33:         UW     clock;              // Source clock
   34:         void   *exinf;           // Extended information
   35: } T_PTMRCB;
   36: 
   37: T_PTMRCB ptmrcb[TK_MAX_PTIMER] = {
   38:         { TMR01_BASE, -1, 0, (FP)NULL, INTPRI_TMR01, 0, TMR01_CLOCK, 0 },
   39:         { TMR23_BASE, -1, 0, (FP)NULL, INTPRI_TMR23, 0, TMR23_CLOCK, 0 },
   40: };
   41: 
   42: #define TMR_TCR         (p_cb->baddr + TCR)
   43: #define TMR_TCSR        (p_cb->baddr + TCSR)
   44: #define TMR_TCOR        (p_cb->baddr + TCORA)
   45: #define TMR_TCNT        (p_cb->baddr + TCNT)
   46: #define TMR_TCCR        (p_cb->baddr + TCCR)
   47: #define TMR_TCSTR       (p_cb->baddr + TCSTR)
   48: 
   49: /*
   50:  * Physical timer interrupt handler
   51:  */
   52: LOCAL void ptmr_int_main( UINT intno, T_PTMRCB *p_cb)
   53: {
   54:         ClearInt( intno);
   55:         if( p_cb->ptmrhdr != NULL) {
   56:                 (*p_cb->ptmrhdr)( p_cb->exinf);               // Execute user handler.
   57:         }
   58: 
   59:         if( p_cb->mode == TA_ALM_PTMR)  {
   60:                 /* Stop Pysical timer */
   61:                 DisableInt( intno);
   62:                 out_h(TMR_TCCR, 0);                   // Timer Stop
   63:         }
   64: }
   65: 
   66: LOCAL void ptmr1_inthdr( UINT intno ) { ptmr_int_main( intno, &ptmrcb[0]); }
   67: LOCAL void ptmr2_inthdr( UINT intno ) { ptmr_int_main( intno, &ptmrcb[1]); }
   68: 
   69: LOCAL void (* const inthdr_tbl[])() = {
   70:         ptmr1_inthdr, ptmr2_inthdr
   71: };
   72: 
   73: #define INTNO_CMIA(no)  (no==1?INTNO_CMIA0:INTNO_CMIA2)
   74: #define INTNO_OVI(no)   (no==1?INTNO_OVI0:INTNO_OVI2)
   75: 
   76: /*
   77:  * Start of physical timer operation
   78:  */
   79: EXPORT ER StartPhysicalTimer( UINT ptmrno, UW limit, UINT mode)
   80: {
   81:         T_DINT         dint;
   82:         T_PTMRCB       *p_cb;
   83:         ER             err;
   84: 
   85:         /* parameter check */
   86:         if(( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) || ( limit == 0 || limit > PTMR_MAX_CNT )
   87:                 || ( mode > TA_CYC_PTMR ))    return E_PAR;
   88: 
   89:         p_cb = &ptmrcb[ptmrno - 1];
   90:         p_cb->limit    = limit;
   91:         p_cb->mode     = mode;
   92: 
   93:         /* Timer initialization */
   94:         out_h(TMR_TCCR, 0);                    // Timer Stop
   95:         out_h(TMR_TCNT, 0);                    // Counter Clear
   96: 
   97:         if( limit != PTMR_MAX_CNT ) {
   98:                 out_h(TMR_TCOR, limit);                               // Set Compare match register
   99:                 out_b(TMR_TCR, TCR_CMIEA | TCR_CCLR_CMA);     // Enable CMIAn
  100:                 p_cb->intno = INTNO_CMIA(ptmrno);
  101:         } else {
  102:                 out_b(TMR_TCR, TCR_OVIE);                     // Enable OVIn
  103:                 p_cb->intno = INTNO_OVI(ptmrno);
  104:         }
  105: 
  106:         /* Register interrupt handler */
  107:         dint.intatr    = TA_HLNG;
  108:         dint.inthdr    = inthdr_tbl[ptmrno - 1];
  109:         err = tk_def_int( p_cb->intno, &dint);
  110:         if(err != E_OK) {
  111:                 return err;
  112:         }
  113:         EnableInt( p_cb->intno, p_cb->intptr);
  114: 
  115:         /* Start Physical Timer */
  116:         out_h(TMR_TCCR, TCCR_CSS_16BIT | (p_cb->clock)<<8);    // 16bit mode & Clock set
  117: 
  118:         return E_OK;
  119: }
  120: 
  121: EXPORT ER StopPhysicalTimer( UINT ptmrno )
  122: {
  123:         T_PTMRCB       *p_cb;
  124: 
  125:         /* parameter check */
  126:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  127: 
  128:         p_cb = &ptmrcb[ptmrno - 1];
  129: 
  130:         /* Stop Physical Timer */
  131:         DisableInt( p_cb->intno);
  132:         out_h(TMR_TCCR, 0);                    // Timer Stop
  133: 
  134:         return E_OK;
  135: }
  136: 
  137: 
  138: IMPORT ER GetPhysicalTimerCount( UINT ptmrno, UW *p_count )
  139: {
  140:         T_PTMRCB       *p_cb;
  141: 
  142:         /* parameter check */
  143:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  144: 
  145:         p_cb = &ptmrcb[ptmrno - 1];
  146:         if(p_cb->mode < 0) return E_PAR;
  147: 
  148:         /* Get Physical timer counter */
  149:         *p_count = (UW)in_h(TMR_TCNT); // Read counter.
  150: 
  151:         return E_OK;
  152: }
  153: 
  154: 
  155: EXPORT ER DefinePhysicalTimerHandler( UINT ptmrno, CONST T_DPTMR *pk_dptmr )
  156: {
  157:         T_PTMRCB       *p_cb;
  158: 
  159:         /* parameter check */
  160:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  161: 
  162:         p_cb = &ptmrcb[ptmrno - 1];
  163: 
  164:         /* Set user Handler */
  165:         if(pk_dptmr != NULL) {
  166:                 p_cb->ptmrhdr = pk_dptmr->ptmrhdr;
  167:                 p_cb->exinf   = pk_dptmr->exinf;
  168:         } else {
  169:                 p_cb->ptmrhdr = NULL;
  170:         }
  171: 
  172:         return E_OK;
  173: }
  174: 
  175: 
  176: EXPORT ER GetPhysicalTimerConfig(UINT ptmrno, T_RPTMR *pk_rptmr)
  177: {
  178:         T_PTMRCB       *p_cb;
  179:         UW             ptmrclk;
  180: 
  181:         /* parameter check */
  182:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  183: 
  184:         p_cb = &ptmrcb[ptmrno - 1];
  185: 
  186:         switch(p_cb->clock) {
  187:                 case 0x08:
  188:                         ptmrclk = SYSCLK_PCLKB;
  189:                         break;
  190:                 case 0x09:
  191:                         ptmrclk = SYSCLK_PCLKB/2;
  192:                         break;
  193:                 case 0x0A:
  194:                         ptmrclk = SYSCLK_PCLKB/8;
  195:                         break;
  196:                 case 0x0B:
  197:                         ptmrclk = SYSCLK_PCLKB/32;
  198:                         break;
  199:                 case 0x0C:
  200:                         ptmrclk = SYSCLK_PCLKB/64;
  201:                         break;
  202:                 case 0x0D:
  203:                         ptmrclk = SYSCLK_PCLKB/1024;
  204:                         break;
  205:                 case 0x0E:
  206:                         ptmrclk = SYSCLK_PCLKB/8192;
  207:                         break;
  208:                 default:
  209:                         ptmrclk = 0;         // Unkown
  210:         }
  211:         pk_rptmr->ptmrclk      = ptmrclk;
  212:         pk_rptmr->maxcount     = PTMR_MAX_CNT;
  213:         pk_rptmr->defhdr       = TRUE;
  214: 
  215:         return E_OK;
  216: }
  217: 
  218: #endif  /* USE_PTMR */
  219: #endif  /* CPU_RX231 */