PDL for FM0+  Version1.0
Peripheral Driverl Library for FM0+
C:/pdl_v10/library/driver/dt/dt.c
Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2013 Spansion LLC. All Rights Reserved. 
00003 *
00004 * This software is owned and published by: 
00005 * Spansion LLC, 915 DeGuigne Dr. Sunnyvale, CA  94088-3453 ("Spansion").
00006 *
00007 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND 
00008 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
00009 *
00010 * This software contains source code for use with Spansion 
00011 * components. This software is licensed by Spansion to be adapted only 
00012 * for use in systems utilizing Spansion components. Spansion shall not be 
00013 * responsible for misuse or illegal use of this software for devices not 
00014 * supported herein.  Spansion is providing this software "AS IS" and will 
00015 * not be responsible for issues arising from incorrect user implementation 
00016 * of the software.  
00017 *
00018 * SPANSION MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
00019 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS), 
00020 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING, 
00021 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED 
00022 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED 
00023 * WARRANTY OF NONINFRINGEMENT.  
00024 * SPANSION SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT, 
00025 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT 
00026 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, 
00027 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR 
00028 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT, 
00029 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA, 
00030 * SAVINGS OR PROFITS, 
00031 * EVEN IF SPANSION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
00032 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
00033 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED 
00034 * FROM, THE SOFTWARE.  
00035 *
00036 * This software may be replicated in part or whole for the licensed use, 
00037 * with the restriction that this Disclaimer and Copyright notice must be 
00038 * included with each copy of this software, whether used in part or whole, 
00039 * at all times.  
00040 */
00041 /******************************************************************************/
00052 /******************************************************************************/
00053 /* Include files                                                              */
00054 /******************************************************************************/
00055 #include "dt.h"
00056 
00057 #if (defined(PDL_PERIPHERAL_DT_ACTIVE))
00058 
00064 
00065 /******************************************************************************/
00066 /* Local pre-processor symbols/macros ('#define')                             */
00067 /******************************************************************************/
00068 
00069 /******************************************************************************/
00070 /* Global variable definitions (declared in header file with 'extern')        */
00071 /******************************************************************************/
00072 
00074 static stc_dt_instance_data_t m_astcDtInstanceDataLut[DtInstanceIndexMax] =
00075 {
00076 #if (PDL_PERIPHERAL_ENABLE_DT == PDL_ON)
00077     {
00078         &DT0,   /* pstcInstance */
00079         {NULL}  /* stcInternData (not initialized yet) */
00080     }
00081 #endif
00082 };
00083 
00084 /******************************************************************************/
00085 /* Local type definitions ('typedef')                                         */
00086 /******************************************************************************/
00087 
00088 
00089 /******************************************************************************/
00090 /* Local function prototypes ('static')                                       */
00091 /******************************************************************************/
00092 static stc_dt_intern_data_t* DtGetInternDataPtr(volatile stc_dtn_t** ppstcDt,
00093                                                 uint8_t              u8Ch);
00094 #if (PDL_INTERRUPT_ENABLE_DT == PDL_ON)
00095 static void Dt_InitIrq(void);
00096 static void Dt_DeInitIrq(void);
00097 #endif
00098 
00099 /******************************************************************************/
00100 /* Local variable definitions ('static')                                      */
00101 /******************************************************************************/
00102 
00103 /*****************************************************************************/
00104 /* Function implementation - global ('extern') and local ('static')          */
00105 /*****************************************************************************/
00106 
00118 static stc_dt_intern_data_t* DtGetInternDataPtr(volatile stc_dtn_t** ppstcDt,
00119                                                 uint8_t              u8Ch)
00120 {
00121     stc_dt_intern_data_t* pstcDtInternData = NULL;
00122     uint32_t              u32Instance;
00123 
00124     /* check for channel */
00125     if ((NULL != ppstcDt)
00126     &&  (NULL != *ppstcDt)
00127     &&  (DtMaxChannels > u8Ch)
00128        )
00129     {
00130         /* Get ptr to internal data struct ... */
00131         for (u32Instance = 0; u32Instance < (uint32_t)DtInstanceIndexMax; u32Instance++)
00132         {
00133             if (*ppstcDt == m_astcDtInstanceDataLut[u32Instance].pstcInstance)
00134             {
00135                 /* Set actual address of register list of current channel */
00136                 *ppstcDt = &((*ppstcDt)[u8Ch]);
00137                 pstcDtInternData = &m_astcDtInstanceDataLut[u32Instance].stcInternData;
00138                 break;
00139             }
00140         }
00141     }
00142 
00143     return (pstcDtInternData);
00144 } /* DtGetInternDataPtr */
00145 
00146 #if (PDL_INTERRUPT_ENABLE_DT == PDL_ON)
00147 
00153 static void Dt_InitIrq(void)
00154 {    
00155 #if (PDL_INTERRUPT_ENABLE_DT == PDL_ON)
00156     NVIC_ClearPendingIRQ(DTIM_QDU_IRQn);
00157     NVIC_EnableIRQ(DTIM_QDU_IRQn);
00158     NVIC_SetPriority(DTIM_QDU_IRQn, PDL_IRQ_LEVEL_DT_QPRC);
00159 #endif
00160 } /* Dt_InitIrq */
00161 
00167 static void Dt_DeInitIrq(void)
00168 {
00169 #if (PDL_INTERRUPT_ENABLE_QPRC0 == PDL_OFF) && (PDL_INTERRUPT_ENABLE_QPRC1 == PDL_OFF) && \
00170     (PDL_INTERRUPT_ENABLE_QPRC2 == PDL_OFF) && (PDL_INTERRUPT_ENABLE_QPRC3 == PDL_OFF)
00171     NVIC_ClearPendingIRQ(DTIM_QDU_IRQn);
00172     NVIC_DisableIRQ(DTIM_QDU_IRQn);
00173     NVIC_SetPriority(DTIM_QDU_IRQn, PDL_DEFAULT_INTERRUPT_LEVEL);
00174 #endif    
00175 } /* Dt_DeInitIrq */
00176 
00192 void DtIrqHandler(uint8_t u8Ch)
00193 {
00194     volatile stc_dtn_t*   pstcDt;
00195     stc_dt_intern_data_t* pstcDtInternData;
00196 
00197     pstcDt = &DT0;
00198     /* Get actual address of register list of current channel */
00199     pstcDt = (volatile stc_dtn_t*)(&((pstcDt)[u8Ch]));
00200     pstcDtInternData = &m_astcDtInstanceDataLut[0].stcInternData;
00201 
00202     if (TRUE == pstcDt->TIMERXRIS_f.TIMERXRIS)  /* Timer 0 interrupt? */
00203     {
00204         pstcDt->TIMERXINTCLR = 0;               /* Clear interrupt */
00205 
00206         /* Check for callback function pointer */
00207         if (NULL != pstcDtInternData->pfnIntCallbackIntern[u8Ch])
00208         {
00209             pstcDtInternData->pfnIntCallbackIntern[u8Ch]() ;
00210         }
00211     }
00212 } /* DtIrqHandler */
00213 
00214 #endif
00215 
00234 en_result_t Dt_Init(stc_dt_channel_config_t* pstcConfig,
00235                     uint8_t                  u8Ch
00236                    )
00237 {
00238     en_result_t                    enResult;
00239     /* Pointer to Dual Timer instance register area */
00240     volatile stc_dtn_t*            pstcDt;
00241     /* Pointer to internal data */
00242     stc_dt_intern_data_t*          pstcDtInternData;
00243     stc_dtim_timerXcontrol_field_t stcTIMERXCTRL = { 0 }; /* Preset to zero */
00244 
00245     pstcDt = &DT0;
00246     /*-------- Initialize internal data -------*/
00247     /* Get pointer to internal data structure and check channel... */
00248     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00249     /* ... and check for NULL */
00250     if ((NULL == pstcDtInternData)
00251     ||  (NULL == pstcConfig)
00252        )
00253     {
00254         enResult = ErrorInvalidParameter;
00255     }
00256     else
00257     {
00258         enResult = Ok;
00259         /*-------- Configure the DT timer -------*/
00260         pstcDt->TIMERXCONTROL = 0;              /* Disable everything */
00261 
00262         /* Set Timer Mode */
00263         switch (pstcConfig->u8Mode)
00264         {
00265             /* Free run mode */
00266             case DtFreeRun:
00267                 stcTIMERXCTRL.TIMERMODE = FALSE;
00268                 stcTIMERXCTRL.ONESHOT   = FALSE;
00269                 break;
00270             /* Periodic mode */
00271             case DtPeriodic:
00272                 stcTIMERXCTRL.TIMERMODE = TRUE;
00273                 stcTIMERXCTRL.ONESHOT   = FALSE;
00274                 break;
00275             /* One shot mode */
00276             case DtOneShot:
00277                 stcTIMERXCTRL.TIMERMODE = FALSE;
00278                 stcTIMERXCTRL.ONESHOT   = TRUE;
00279                 break;
00280             default:
00281                 enResult = ErrorInvalidParameter;
00282                 break;
00283         }
00284 
00285         /* Set Prescaler */
00286         switch (pstcConfig->u8PrescalerDiv)
00287         {
00288             /* Clock/1 */
00289             case DtPrescalerDiv1:
00290                 stcTIMERXCTRL.TIMERPRE = DT_PRE_TIMER_DIV_1;
00291                 break;
00292             /* Clock/16 */
00293             case DtPrescalerDiv16:
00294                 stcTIMERXCTRL.TIMERPRE = DT_PRE_TIMER_DIV_16;
00295                 break;
00296             /* Clock/256 */
00297             case DtPrescalerDiv256:
00298                 stcTIMERXCTRL.TIMERPRE = DT_PRE_TIMER_DIV_256;
00299                 break;
00300             default:
00301                 enResult = ErrorInvalidParameter;
00302                 break;
00303         }
00304 
00305         /* Set Counter Size */
00306         switch (pstcConfig->u8CounterSize)
00307         {
00308             /* 16bit */
00309             case DtCounterSize16:
00310                 stcTIMERXCTRL.TIMERSIZE = FALSE;
00311                 break;
00312             /* 32bit */
00313             case DtCounterSize32:
00314                 stcTIMERXCTRL.TIMERSIZE = TRUE;
00315                 break;
00316             default:
00317                 enResult = ErrorInvalidParameter;
00318                 break;
00319         }
00320     }
00321 
00322     if (Ok == enResult)
00323     {
00324         /* Set control register */
00325         pstcDt->TIMERXCONTROL_f = stcTIMERXCTRL;
00326 
00327         /* Initialize (clear) callback */
00328         pstcDtInternData->pfnIntCallbackIntern[u8Ch] = NULL;
00329     }
00330 
00331     return (enResult);
00332 } /* Dt_Init */
00333 
00351 en_result_t Dt_DeInit(uint8_t u8Ch)
00352 {
00353     en_result_t           enResult;
00354     /* Pointer to Dual Timer instance register area */
00355     volatile stc_dtn_t*   pstcDt;
00356     /* Pointer to internal data */
00357     stc_dt_intern_data_t* pstcDtInternData;
00358 
00359     pstcDt = &DT0;
00360     /*-------- Initialize internal data -------*/
00361     /* Get pointer to internal data structure and check channel... */
00362     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00363     /* ... and check for NULL */
00364     if (NULL == pstcDtInternData)
00365     {
00366         enResult = ErrorInvalidParameter;
00367     }
00368     else
00369     {
00370         /* Clear all registers */
00371         pstcDt->TIMERXCONTROL = 0;
00372 
00373         pstcDt->TIMERXLOAD    = 0;
00374         pstcDt->TIMERXINTCLR  = 1;
00375         pstcDt->TIMERXBGLOAD  = 0;
00376 
00377         /* Clear callback */
00378         pstcDtInternData->pfnIntCallbackIntern[u8Ch] = NULL;
00379         enResult = Ok;
00380     }
00381 
00382     return (enResult);
00383 } /* Dt_DeInit */
00384 
00400 en_result_t Dt_EnableCount(uint8_t u8Ch)
00401 {
00402     en_result_t           enResult;
00403     /* Pointer to Dual Timer instance register area */
00404     volatile stc_dtn_t*   pstcDt;
00405     /* Pointer to internal data */
00406     stc_dt_intern_data_t* pstcDtInternData;
00407 
00408     enResult = ErrorInvalidParameter;
00409 
00410     pstcDt = &DT0;
00411     /* Get pointer to internal data structure and check channel... */
00412     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00413     /* ... and check for NULL */
00414     if (NULL != pstcDtInternData)
00415     {
00416         /* Enable timer counter */
00417         pstcDt->TIMERXCONTROL_f.TIMEREN = TRUE;
00418         enResult = Ok;
00419     }
00420 
00421     return (enResult);
00422 } /* Dt_EnableCount */
00423 
00439 en_result_t Dt_DisableCount(uint8_t u8Ch)
00440 {
00441     en_result_t           enResult;
00442     /* Pointer to Dual Timer instance register area */
00443     volatile stc_dtn_t*   pstcDt;
00444     /* Pointer to internal data */
00445     stc_dt_intern_data_t* pstcDtInternData;
00446 
00447     enResult = ErrorInvalidParameter;
00448 
00449     pstcDt = &DT0;
00450     /* Get pointer to internal data structure and check channel... */
00451     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00452     /* ... and check for NULL */
00453     if (NULL != pstcDtInternData)
00454     {
00455         /* Disable timer counter */
00456         pstcDt->TIMERXCONTROL_f.TIMEREN = FALSE;
00457         enResult = Ok;
00458     }
00459 
00460     return (enResult);
00461 } /* Dt_DisableCount */
00462 
00463 #if (PDL_INTERRUPT_ENABLE_DT == PDL_ON)
00464 
00481 en_result_t Dt_EnableInt(dt_cb_func_ptr_t pfnIntCallback,
00482                          uint8_t          u8Ch
00483                         )
00484 {
00485     en_result_t           enResult;
00486     /* Pointer to Dual Timer instance register area */
00487     volatile stc_dtn_t*   pstcDt;
00488     /* Pointer to internal data */
00489     stc_dt_intern_data_t* pstcDtInternData;
00490 
00491     enResult = ErrorInvalidParameter;
00492 
00493     pstcDt = &DT0;
00494     /* Get pointer to internal data structure and check channel... */
00495     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00496     /* ... and check for NULL */
00497     if (NULL != pstcDtInternData)
00498     {
00499         /* Set callback function */
00500         pstcDtInternData->pfnIntCallbackIntern[u8Ch] = pfnIntCallback;
00501         /* Enable interrupt */
00502         pstcDt->TIMERXCONTROL_f.INTENABLE = TRUE;
00503         /* Enable IRQ */
00504         Dt_InitIrq();
00505         enResult = Ok;
00506     }
00507 
00508     return (enResult);
00509 } /* Dt_EnableInt */
00510 
00526 en_result_t Dt_DisableInt(uint8_t u8Ch)
00527 {
00528     en_result_t           enResult;
00529     /* Pointer to Dual Timer instance register area */
00530     volatile stc_dtn_t*   pstcDt;
00531     /* Pointer to internal data */
00532     stc_dt_intern_data_t* pstcDtInternData;
00533 
00534     enResult = ErrorInvalidParameter;
00535 
00536     pstcDt = &DT0;
00537     /* Get pointer to internal data structure and check channel... */
00538     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00539     /* ... and check for NULL */
00540     if (NULL != pstcDtInternData)
00541     {
00542         /* Disable IRQ */
00543         Dt_DeInitIrq();
00544         /* Disable interrupt */
00545         pstcDt->TIMERXCONTROL_f.INTENABLE = FALSE;
00546         /* Clear callback function */
00547         pstcDtInternData->pfnIntCallbackIntern[u8Ch] = NULL;
00548         enResult = Ok;
00549     }
00550 
00551     return (enResult);
00552 } /* Dt_DisableInt */
00553 #endif
00554 
00565 boolean_t Dt_GetIntFlag(uint8_t u8Ch)
00566 {
00567     /* Pointer to Dual Timer instance register area */
00568     volatile stc_dtn_t*   pstcDt;
00569     boolean_t             bRetVal = FALSE;
00570     /* Pointer to internal data */
00571     stc_dt_intern_data_t* pstcDtInternData;
00572 
00573     pstcDt = &DT0;
00574     /* Get pointer to internal data structure and check channel... */
00575     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00576     /* ... and check for NULL */
00577     if (NULL != pstcDtInternData)
00578     {
00579         /* Check the interrupt status */
00580         if (TRUE == pstcDt->TIMERXRIS_f.TIMERXRIS)
00581         {
00582             bRetVal = TRUE;
00583         }
00584     }
00585 
00586     return (bRetVal);
00587 } /* Dt_GetIntFlag */
00588 
00599 boolean_t Dt_GetMaskIntFlag(uint8_t u8Ch)
00600 {
00601     /* Pointer to Dual Timer instance register area */
00602     volatile stc_dtn_t*   pstcDt;
00603     boolean_t             bRetVal = FALSE;
00604     /* Pointer to internal data */
00605     stc_dt_intern_data_t* pstcDtInternData;
00606 
00607     pstcDt = &DT0;
00608     /* Get pointer to internal data structure and check channel... */
00609     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00610     /* ... and check for NULL */
00611     if (NULL != pstcDtInternData)
00612     {
00613         /* Check the mask interrupt status */
00614         if (TRUE == pstcDt->TIMERXMIS_f.TIMERXMIS)
00615         {
00616             bRetVal = TRUE;
00617         }
00618     }
00619 
00620     return (bRetVal);
00621 } /* Dt_GetMaskIntFlag */
00622 
00637 en_result_t Dt_ClrIntFlag(uint8_t u8Ch)
00638 {
00639     en_result_t           enResult;
00640     /* Pointer to Dual Timer instance register area */
00641     volatile stc_dtn_t*   pstcDt;
00642     /* Pointer to internal data */
00643     stc_dt_intern_data_t* pstcDtInternData;
00644 
00645     enResult = ErrorInvalidParameter;
00646 
00647     pstcDt = &DT0;
00648     /* Get pointer to internal data structure and check channel... */
00649     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00650     /* ... and check for NULL */
00651     if (NULL != pstcDtInternData)
00652     {
00653         /* Clear the interrupt status */
00654         pstcDt->TIMERXINTCLR = 1;
00655         enResult = Ok;
00656     }
00657 
00658     return (enResult);
00659 } /* Dt_ClrIntFlag */
00660 
00676 en_result_t Dt_WriteLoadVal(uint32_t u32LoadVal,
00677                             uint8_t  u8Ch
00678                            )
00679 {
00680     en_result_t           enResult;
00681     /* Pointer to Dual Timer instance register area */
00682     volatile stc_dtn_t*   pstcDt;
00683     /* Pointer to internal data */
00684     stc_dt_intern_data_t* pstcDtInternData;
00685 
00686     enResult = ErrorInvalidParameter;
00687 
00688     pstcDt = &DT0;
00689     /* Get pointer to internal data structure and check channel... */
00690     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00691     /* ... and check for NULL */
00692     if (NULL != pstcDtInternData)
00693     {
00694         /* 16bit mode */
00695         if (FALSE == pstcDt->TIMERXCONTROL_f.TIMERSIZE)
00696         {
00697             u32LoadVal &= 0x0000FFFF;
00698         }
00699         /* Write load value to register */
00700         pstcDt->TIMERXLOAD = u32LoadVal;
00701         enResult = Ok;
00702     }
00703 
00704     return (enResult);
00705 } /* Dt_WriteLoadVal */
00706 
00722 en_result_t Dt_WriteBgLoadVal(uint32_t u32BgLoadVal,
00723                               uint8_t  u8Ch
00724                              )
00725 {
00726     en_result_t           enResult;
00727     /* Pointer to Dual Timer instance register area */
00728     volatile stc_dtn_t*   pstcDt;
00729     /* Pointer to internal data */
00730     stc_dt_intern_data_t* pstcDtInternData;
00731 
00732     enResult = ErrorInvalidParameter;
00733 
00734     pstcDt = &DT0;
00735     /* Get pointer to internal data structure and check channel... */
00736     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00737     /* ... and check for NULL */
00738     if (NULL != pstcDtInternData)
00739     {
00740         /* 16bit mode */
00741         if (FALSE == pstcDt->TIMERXCONTROL_f.TIMERSIZE)
00742         {
00743             u32BgLoadVal &= 0x0000FFFF;
00744         }
00745         /* Write back-ground load value to register */
00746         pstcDt->TIMERXBGLOAD = u32BgLoadVal;
00747         enResult = Ok;
00748     }
00749 
00750     return (enResult);
00751 } /* Dt_WriteBgLoadVal */
00752 
00763 uint32_t Dt_ReadCurCntVal(uint8_t u8Ch)
00764 {
00765     /* Pointer to Dual Timer instance register area */
00766     volatile stc_dtn_t*   pstcDt;
00767     uint32_t              u32DtValue = 0;
00768     /* Pointer to internal data */
00769     stc_dt_intern_data_t* pstcDtInternData;
00770 
00771     pstcDt = &DT0;
00772     /* Get pointer to internal data structure and check channel... */
00773     pstcDtInternData = DtGetInternDataPtr(&pstcDt, u8Ch);
00774     /* ... and check for NULL */
00775     if (NULL != pstcDtInternData)
00776     {
00777         /* Read current count value */
00778         u32DtValue = pstcDt->TIMERXVALUE;
00779         /* 16bit mode */
00780         if (FALSE == pstcDt->TIMERXCONTROL_f.TIMERSIZE)
00781         {
00782             u32DtValue &= 0x0000FFFF;
00783         }
00784     }
00785 
00786     return (u32DtValue);
00787 } /* Dt_ReadCurCntVal */
00788 
00790 
00791 #endif /* #if (defined(PDL_PERIPHERAL_DT_ACTIVE)) */
00792 
00793 /******************************************************************************/
00794 /* EOF (not truncated)                                                        */
00795 /******************************************************************************/
00796