1:     2:     3:     4:     5:     6:     7:     8:     9:    10:    11:    12: 
   13: 
   14: #include <sys/machine.h>
   15: #ifdef CPU_RX231
   16:    17:    18:    19:    20: 
   21: #include <tk/tkernel.h>
   22: #include <tk/syslib.h>
   23: 
   24: #if USE_PTMR
   25: 
   26: typedef struct {
   27:         UW     baddr;              
   28:         INT    mode;              
   29:         UW     limit;              
   30:         FP     ptmrhdr;    
   31:         PRI    intptr;            
   32:         UINT   intno;            
   33:         UW     clock;              
   34:         void   *exinf;           
   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:    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);               
   57:         }
   58: 
   59:         if( p_cb->mode == TA_ALM_PTMR)  {
   60:                 
   61:                 DisableInt( intno);
   62:                 out_h(TMR_TCCR, 0);                   
   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:    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:         
   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:         
   94:         out_h(TMR_TCCR, 0);                    
   95:         out_h(TMR_TCNT, 0);                    
   96: 
   97:         if( limit != PTMR_MAX_CNT ) {
   98:                 out_h(TMR_TCOR, limit);                               
   99:                 out_b(TMR_TCR, TCR_CMIEA | TCR_CCLR_CMA);     
  100:                 p_cb->intno = INTNO_CMIA(ptmrno);
  101:         } else {
  102:                 out_b(TMR_TCR, TCR_OVIE);                     
  103:                 p_cb->intno = INTNO_OVI(ptmrno);
  104:         }
  105: 
  106:         
  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:         
  116:         out_h(TMR_TCCR, TCCR_CSS_16BIT | (p_cb->clock)<<8);    
  117: 
  118:         return E_OK;
  119: }
  120: 
  121: EXPORT ER StopPhysicalTimer( UINT ptmrno )
  122: {
  123:         T_PTMRCB       *p_cb;
  124: 
  125:         
  126:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  127: 
  128:         p_cb = &ptmrcb[ptmrno - 1];
  129: 
  130:         
  131:         DisableInt( p_cb->intno);
  132:         out_h(TMR_TCCR, 0);                    
  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:         
  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:         
  149:         *p_count = (UW)in_h(TMR_TCNT); 
  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:         
  160:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  161: 
  162:         p_cb = &ptmrcb[ptmrno - 1];
  163: 
  164:         
  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:         
  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;         
  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  
  219: #endif