![]() |
PDL for FM0+
Version1.0
Peripheral Driverl Library for FM0+
|
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