gonzui


Format: Advanced Search

mtkernel_3/lib/libtk/sysdepend/cpu/stm32l4/ptimer_stm32l4.cbare sourcepermlink (0.01 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_STM32L4
   16: /*
   17:  *      ptimer_stm32l4.c
   18:  *
   19:  *      Physical timer (for STM32L4)
   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:         UINT   mode;             // Timer mode
   29:         UW     limit;              // Counter Limit
   30:         FP     ptmrhdr;    // Timer Hnadler
   31:         PRI    intpri;            // Interrupt priority
   32:         UW     psc;                // Prescaler value
   33:         BOOL   tim32;            // 32-bit timer?
   34:         void   *exinf;           // Extended information
   35: } T_PTMRCB;
   36: 
   37: T_PTMRCB ptmrcb[TK_MAX_PTIMER] = {
   38:         { TIM2_BASE, -1, 0, (FP)NULL, INTPRI_TIM2, TIM2PSC_PSC_INIT, TRUE,  0 },// No.1
   39:         { TIM3_BASE, -1, 0, (FP)NULL, INTPRI_TIM3, TIM3PSC_PSC_INIT, FALSE, 0 },// No.2
   40:         { TIM4_BASE, -1, 0, (FP)NULL, INTPRI_TIM4, TIM4PSC_PSC_INIT, FALSE, 0 },// No.3
   41:         { TIM5_BASE, -1, 0, (FP)NULL, INTPRI_TIM5, TIM5PSC_PSC_INIT, TRUE,  0 },// No.4
   42: };
   43: 
   44: #define TIM_CR1(n)      (ptmrcb[n].baddr + TIMxCR1)
   45: #define TIM_DIER(n)     (ptmrcb[n].baddr + TIMxDIER)
   46: #define TIM_SR(n)       (ptmrcb[n].baddr + TIMxSR)
   47: #define TIM_EGR(n)      (ptmrcb[n].baddr + TIMxEGR)
   48: #define TIM_CNT(n)      (ptmrcb[n].baddr + TIMxCNT)
   49: #define TIM_PSC(n)      (ptmrcb[n].baddr + TIMxPSC)
   50: #define TIM_ARR(n)      (ptmrcb[n].baddr + TIMxARR)
   51: 
   52: /*
   53:  * Physical timer interrupt handler
   54:  */
   55: LOCAL void ptmr_int_main( UINT intno, T_PTMRCB *p_cb)
   56: {
   57:         out_h(p_cb->baddr + TIMxSR, 0);                        // Clear interrupt flag
   58:         ClearInt( intno);
   59: 
   60:         if( p_cb->ptmrhdr != NULL) {
   61:                 (*p_cb->ptmrhdr)( p_cb->exinf);               // Execute user handler.
   62:         }
   63: 
   64:         if( p_cb->mode == TA_ALM_PTMR)  {
   65:                 DisableInt( intno);                   // Stop Pysical timer
   66:         }
   67: }
   68: 
   69: LOCAL void ptmr1_inthdr( UINT intno ) { ptmr_int_main( intno, &ptmrcb[0]); }
   70: LOCAL void ptmr2_inthdr( UINT intno ) { ptmr_int_main( intno, &ptmrcb[1]); }
   71: LOCAL void ptmr3_inthdr( UINT intno ) { ptmr_int_main( intno, &ptmrcb[2]); }
   72: LOCAL void ptmr4_inthdr( UINT intno ) { ptmr_int_main( intno, &ptmrcb[3]); }
   73: 
   74: LOCAL void (* const inthdr_tbl[])() = {
   75:         ptmr1_inthdr, ptmr2_inthdr, ptmr3_inthdr, ptmr4_inthdr
   76: };
   77: 
   78: LOCAL const UINT intno_tbl[] = {
   79:         INTNO_TIM2, INTNO_TIM3, INTNO_TIM4, INTNO_TIM5
   80: };
   81: 
   82: /*
   83:  * Start of physical timer operation
   84:  */
   85: EXPORT ER StartPhysicalTimer( UINT ptmrno, UW limit, UINT mode)
   86: {
   87:         T_DINT         dint;
   88:         UINT           intno;
   89:         UW             limit_max;
   90:         ER             err;
   91: 
   92:         /* parameter check */
   93:         if(( ptmrno == 0 || ptmrno > TK_MAX_PTIMER )
   94:                 || ( limit == 0 ) || ( mode > TA_CYC_PTMR ))  return E_PAR;
   95: 
   96:         ptmrno--;
   97:         if(ptmrcb[ptmrno].tim32) {
   98:                 limit_max = PTMR_MAX_CNT32;
   99:         } else {
  100:                 limit_max = PTMR_MAX_CNT16;
  101:         }
  102:         if( limit > limit_max) {
  103:                 return E_PAR;
  104:         }
  105: 
  106:         ptmrcb[ptmrno].limit   = limit;
  107:         ptmrcb[ptmrno].mode    = mode;
  108: 
  109:         /* Timer initialization */
  110:         out_h( TIM_CR1(ptmrno), 0);                    // Stop timer.
  111:         out_h( TIM_PSC(ptmrno), ptmrcb[ptmrno].psc);   // Set prescaler.
  112:         out_w( TIM_ARR(ptmrno), limit);                        // Set the counter upper limit.
  113: 
  114:         /* Register interrupt handler */
  115:         intno          = intno_tbl[ptmrno];
  116:         dint.intatr    = TA_HLNG;
  117:         dint.inthdr    = inthdr_tbl[ptmrno];
  118:         err = tk_def_int( intno, &dint);
  119:         if(err != E_OK) {
  120:                 return err;
  121:         }
  122:         out_h( TIM_SR(ptmrno), 0);                     // Clear Interrupt flag.
  123:         out_h( TIM_DIER(ptmrno), TIMxDIER_UIE);                // Enable Update Interrupt.
  124:         EnableInt( intno, ptmrcb[ptmrno].intpri);
  125: 
  126:         /* Start Physical Timer */
  127:         out_h( TIM_CR1(ptmrno) , TIMxCR1_CEN | ((mode==TA_ALM_PTMR)?TIMxCR1_OPM:0));   // Start Timer.
  128: 
  129:         return E_OK;
  130: }
  131: 
  132: EXPORT ER StopPhysicalTimer( UINT ptmrno )
  133: {
  134:         /* parameter check */
  135:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  136: 
  137:         ptmrno--;
  138: 
  139:         /* Stop Physical Timer */
  140:         DisableInt( intno_tbl[ptmrno]);
  141:         out_h( TIM_CR1(ptmrno), 0);            // Stop timer.
  142: 
  143:         return E_OK;
  144: }
  145: 
  146: 
  147: IMPORT ER GetPhysicalTimerCount( UINT ptmrno, UW *p_count )
  148: {
  149:         /* parameter check */
  150:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  151: 
  152:         ptmrno--;
  153: 
  154:         /* Get Physical timer counter */
  155:         if(ptmrcb[ptmrno].tim32) {     /* 32bit timer */
  156:                 *p_count = in_w( TIM_CNT(ptmrno)) ;                   // Read counter.
  157:         } else {                       /* 16bit timer */
  158:                 *p_count = in_w( TIM_CNT(ptmrno)) & PTMR_MAX_CNT16;   // Read counter.
  159:         }
  160: 
  161:         return E_OK;
  162: }
  163: 
  164: 
  165: EXPORT ER DefinePhysicalTimerHandler( UINT ptmrno, CONST T_DPTMR *pk_dptmr )
  166: {
  167:         /* parameter check */
  168:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  169: 
  170:         ptmrno--;
  171: 
  172:         /* Set user Handler */
  173:         if(pk_dptmr != NULL) {
  174:                 ptmrcb[ptmrno].ptmrhdr        = pk_dptmr->ptmrhdr;
  175:                 ptmrcb[ptmrno].exinf  = pk_dptmr->exinf;
  176:         } else {
  177:                 ptmrcb[ptmrno].ptmrhdr        = NULL;
  178:         }
  179: 
  180:         return E_OK;
  181: }
  182: 
  183: 
  184: EXPORT ER GetPhysicalTimerConfig(UINT ptmrno, T_RPTMR *pk_rptmr)
  185: {
  186:         UW             ptmrclk;
  187: 
  188:         /* parameter check */
  189:         if( ptmrno == 0 || ptmrno > TK_MAX_PTIMER ) return E_PAR;
  190: 
  191:         ptmrclk = (PCLK1 / (ptmrcb[--ptmrno].psc + 1));
  192: 
  193:         pk_rptmr->ptmrclk      = ptmrclk;
  194:         pk_rptmr->maxcount     = (ptmrcb[--ptmrno].tim32)?PTMR_MAX_CNT32:PTMR_MAX_CNT16;
  195:         pk_rptmr->defhdr       = TRUE;
  196: 
  197:         return E_OK;
  198: }
  199: 
  200: #endif  /* USE_PTMR */
  201: #endif  /* CPU_STM32L4 */