| PDL for FM0+ Version1.0 Peripheral Driverl Library for FM0+

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

C:/pdl_v10/library/driver/adc/adc.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 "adc.h"
    00056
    00057 #if (defined(PDL_PERIPHERAL_ADC_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 stc_adc_instance_data_t m_astcAdcInstanceDataLut[ADC_INSTANCE_COUNT] =
    00075 {
    00076   #if (PDL_PERIPHERAL_ENABLE_ADC0 == PDL_ON)
    00077   {
    00078      &ADC0,  // pstcInstance
    00079      {0, 0 ,0, 0, 0 ,0}           // stcInternData (not initialized yet)
    00080   },
    00081   #endif
    00082   #if (PDL_PERIPHERAL_ENABLE_ADC1 == PDL_ON)
    00083   {
    00084      &ADC1,  // pstcInstance
    00085      {0, 0 ,0, 0, 0 ,0}            // stcInternData (not initialized yet)
    00086   },
    00087   #endif
    00088   #if (PDL_PERIPHERAL_ENABLE_ADC2 == PDL_ON)
    00089   {
    00090      &ADC2,  // pstcInstance
    00091      {0, 0 ,0, 0, 0 ,0}            // stcInternData (not initialized yet)
    00092   }
    00093   #endif
    00094 };
    00095
    00096 /******************************************************************************/
    00097 /* Local function prototypes ('static')                                       */
    00098 /******************************************************************************/
    00099 #if (PDL_INTERRUPT_ENABLE_ADC0 == PDL_ON) || \
    00100     (PDL_INTERRUPT_ENABLE_ADC1 == PDL_ON) || \
    00101     (PDL_INTERRUPT_ENABLE_ADC2 == PDL_ON)
    00102 static void Adc_InitNvic(volatile stc_adcn_t* pstcAdc);
    00103 static void Adc_DeInitNvic(volatile stc_adcn_t* pstcAdc);
    00104 static stc_adc_intern_data_t* AdcGetInternDataPtr(volatile stc_adcn_t* pstcAdc);
    00105 #endif
    00106
    00107 /******************************************************************************/
    00108 /* Local variable definitions ('static')                                      */
    00109 /******************************************************************************/
    00110
    00111 /******************************************************************************/
    00112 /* Function implementation - global ('extern') and local ('static')           */
    00113 /******************************************************************************/
    00114
    00115 /******************************************************************************/
    00116 /* Local Functions                                                            */
    00117 /******************************************************************************/
    00118
    00119 #if (PDL_INTERRUPT_ENABLE_ADC0 == PDL_ON) || \
    00120     (PDL_INTERRUPT_ENABLE_ADC1 == PDL_ON) || \
    00121     (PDL_INTERRUPT_ENABLE_ADC2 == PDL_ON)
    00122
    00132 static stc_adc_intern_data_t* AdcGetInternDataPtr(volatile stc_adcn_t* pstcAdc)
    00133 {
    00134     uint8_t u8Instance;
    00135
    00136     for (u8Instance = 0u; u8Instance < ADC_INSTANCE_COUNT; u8Instance++)
    00137     {
    00138         if (pstcAdc == m_astcAdcInstanceDataLut[u8Instance].pstcInstance)
    00139         {
    00140             return &m_astcAdcInstanceDataLut[u8Instance].stcInternData;
    00141         }
    00142     }
    00143
    00144     return NULL;
    00145 }
    00146
    00157 void AdcIrqHandler( volatile stc_adcn_t*   pstcAdc,
    00158                     stc_adc_intern_data_t* pstcAdcInternData)
    00159 {
    00160     if (pstcAdc->SCCR_f.SOVR)   // Error case (FIFO overflow)
    00161     {
    00162         pstcAdc->SCCR_f.SOVR = 0u;
    00163
    00164         if (pstcAdcInternData->pfnScanErrorCallback != NULL)
    00165         {
    00166             pstcAdcInternData->pfnScanErrorCallback();
    00167         }
    00168     }
    00169
    00170     if (pstcAdc->PCCR_f.POVR)  // Error case (Priority FIFO overflow)
    00171     {
    00172         pstcAdc->PCCR_f.POVR = 0u;
    00173
    00174         if (pstcAdcInternData->pfnPrioErrorCallback != NULL)
    00175         {
    00176             pstcAdcInternData->pfnPrioErrorCallback();
    00177         }
    00178     }
    00179
    00180     if (pstcAdc->ADCR_f.PCIF)  // Priority Conversion
    00181     {
    00182         pstcAdc->ADCR_f.PCIF = 0u;
    00183
    00184         if (pstcAdcInternData->pfnPrioCallback != NULL)
    00185         {
    00186             // Callback argument points to priority FIFO. User has to empty it in
    00187             // the callback function, because the FIFO depth is known.
    00188             pstcAdcInternData->pfnPrioCallback((volatile uint32_t*)&pstcAdc->PCFD);
    00189         }
    00190     }
    00191
    00192     if (pstcAdc->ADCR_f.SCIF)   // Scan conversion interrupt request?
    00193     {
    00194         pstcAdc->ADCR_f.SCIF = 0u;
    00195
    00196         if (pstcAdcInternData->pfnScanCallback != NULL)
    00197         {
    00198             // Callback argument points to scan FIFO. User has to empty it in
    00199             // the callback function, because the FIFO depth is known.
    00200             pstcAdcInternData->pfnScanCallback((volatile uint32_t*)&pstcAdc->SCFD);
    00201         }
    00202     }
    00203
    00204     if (pstcAdc->ADCR_f.CMPIF)  // Compare result interrupt request?
    00205     {
    00206         pstcAdc->ADCR_f.CMPIF = 0u;
    00207
    00208         if (pstcAdcInternData->pfnComparisonCallback != NULL)
    00209         {
    00210             pstcAdcInternData->pfnComparisonCallback();
    00211         }
    00212     }
    00213
    00214     if (pstcAdc->WCMRCIF_f.RCINT)  // Range result interrupt request?
    00215     {
    00216         pstcAdc->WCMRCIF_f.RCINT = 0u;
    00217
    00218         if (pstcAdcInternData->pfnRangeComparisonCallback != NULL)
    00219         {
    00220             pstcAdcInternData->pfnRangeComparisonCallback();
    00221         }
    00222     }
    00223
    00224     return;
    00225 } // AdcIrqHandler
    00226
    00234 static void Adc_InitNvic(volatile stc_adcn_t* pstcAdc)
    00235 {
    00236 #if (PDL_INTERRUPT_ENABLE_ADC0 == PDL_ON)
    00237     if (pstcAdc == (volatile stc_adcn_t*)(&ADC0))
    00238     {
    00239         NVIC_ClearPendingIRQ(ADC0_IRQn);
    00240         NVIC_EnableIRQ(ADC0_IRQn);
    00241         NVIC_SetPriority(ADC0_IRQn, PDL_IRQ_LEVEL_ADC0);
    00242     }
    00243 #endif
    00244 #if (PDL_INTERRUPT_ENABLE_ADC1 == PDL_ON)
    00245     if (pstcAdc == (volatile stc_adcn_t*)(&ADC1))
    00246     {
    00247         NVIC_ClearPendingIRQ(ADC1_IRQn);
    00248         NVIC_EnableIRQ(ADC1_IRQn);
    00249         NVIC_SetPriority(ADC1_IRQn, PDL_IRQ_LEVEL_ADC1);
    00250     }
    00251 #endif
    00252 #if (PDL_INTERRUPT_ENABLE_ADC2 == PDL_ON)
    00253     if (pstcAdc == (volatile stc_adcn_t*)(&ADC2))
    00254     {
    00255         NVIC_ClearPendingIRQ(ADC2_LCD_IRQn);
    00256         NVIC_EnableIRQ(ADC2_LCD_IRQn);
    00257         NVIC_SetPriority(ADC2_LCD_IRQn, PDL_IRQ_LEVEL_ADC2_LCD);
    00258     }
    00259 #endif
    00260 } // Adc_InitInterrupt
    00261
    00269 static void Adc_DeInitNvic(volatile stc_adcn_t* pstcAdc)
    00270 {
    00271     /* if SCIE, PCIE, CMPIE or OVRIE is not 0, return */
    00272     if((pstcAdc->ADCR & 0x0Fu) != 0x00u)
    00273     {
    00274         return;
    00275     }
    00276
    00277     /* if RCOIE is not 0, return */
    00278     if(pstcAdc->WCMPCR_f.RCOIE != 0)
    00279     {
    00280         return;
    00281     }
    00282
    00283     /* Only when all of ADC interrupt sources are disable, disable ADC IRQ */
    00284 #if (PDL_INTERRUPT_ENABLE_ADC0 == PDL_ON)
    00285     if (pstcAdc == (volatile stc_adcn_t*)(&ADC0))
    00286     {
    00287         NVIC_ClearPendingIRQ(ADC0_IRQn);
    00288         NVIC_DisableIRQ(ADC0_IRQn);
    00289         NVIC_SetPriority(ADC0_IRQn, PDL_DEFAULT_INTERRUPT_LEVEL);
    00290     }
    00291 #endif
    00292 #if (PDL_INTERRUPT_ENABLE_ADC1 == PDL_ON)
    00293     if (pstcAdc == (volatile stc_adcn_t*)(&ADC1))
    00294     {
    00295         NVIC_ClearPendingIRQ(ADC1_IRQn);
    00296         NVIC_DisableIRQ(ADC1_IRQn);
    00297         NVIC_SetPriority(ADC1_IRQn, PDL_DEFAULT_INTERRUPT_LEVEL);
    00298     }
    00299 #endif
    00300 #if (PDL_INTERRUPT_ENABLE_ADC2 == PDL_ON)
    00301     if (pstcAdc == (volatile stc_adcn_t*)(&ADC2))
    00302     {
    00303         NVIC_ClearPendingIRQ(ADC2_LCD_IRQn);
    00304         NVIC_DisableIRQ(ADC2_LCD_IRQn);
    00305         NVIC_SetPriority(ADC2_LCD_IRQn, PDL_DEFAULT_INTERRUPT_LEVEL);
    00306     }
    00307 #endif
    00308 } // Adc_DeInitInterrupt
    00309 #endif // #if (PDL_INTERRUPT_ENABLE_ADC0 == PDL_ON) || (PDL_INTERRUPT_ENABLE_ADC1 == PDL_ON) || (PDL_INTERRUPT_ENABLE_ADC2_LCD == PDL_ON)
    00310
    00311 /******************************************************************************/
    00312 /* Global Functions                                                           */
    00313 /******************************************************************************/
    00314
    00330 en_result_t Adc_Init( volatile stc_adcn_t* pstcAdc,
    00331                       stc_adc_config_t*    pstcConfig )
    00332 {
    00333     stc_adc0_sccr_field_t  stcSCCR;
    00334     stc_adc0_pccr_field_t  stcPCCR;
    00335     stc_adc0_adst0_field_t stcADST0;
    00336     stc_adc0_adst1_field_t stcADST1;
    00337     stc_adc0_wcmpcr_field_t stcWCMPCR;
    00338
    00339     //stc_adc0_pcis_field_t  stcPCIS;
    00340     uint8_t u8PCIS = 0;
    00341     uint8_t u8CMPCR = 0;
    00342
    00343     PDL_ZERO_STRUCT(stcSCCR);
    00344     PDL_ZERO_STRUCT(stcPCCR);
    00345     PDL_ZERO_STRUCT(stcADST0);
    00346     PDL_ZERO_STRUCT(stcADST1);
    00347     PDL_ZERO_STRUCT(stcWCMPCR);
    00348
    00349     // Check for NULL pointer
    00350     if ((pstcAdc    == NULL) ||
    00351         (pstcConfig == NULL))
    00352     {
    00353         return ErrorInvalidParameter ;
    00354     }
    00355
    00356     // Disable ADC in any case first
    00357     pstcAdc->ADCEN_f.ENBL = 0u;
    00358
    00359     // Clear all relevant registers
    00360     pstcAdc->ADCR = 0u;
    00361     pstcAdc->ADSR = 0u;
    00362     pstcAdc->SCCR = 0u;
    00363
    00364     // Set Sampling Time Selection Register
    00365     pstcAdc->ADSS0 = (uint8_t)(0x000000FFul & pstcConfig->u32SamplingTimeSelect.u32AD_CHn);
    00366     pstcAdc->ADSS1 = (uint8_t)(0x0000FF00ul & (pstcConfig->u32SamplingTimeSelect.u32AD_CHn >> 8u));
    00367     pstcAdc->ADSS2 = (uint8_t)(0x00FF0000ul & (pstcConfig->u32SamplingTimeSelect.u32AD_CHn >> 16u));
    00368     pstcAdc->ADSS3 = (uint8_t)(0xFF000000ul & (pstcConfig->u32SamplingTimeSelect.u32AD_CHn >> 24u));
    00369
    00370     // Set Sampling Times Config. 0
    00371     switch (pstcConfig->enSamplingTimeN0)
    00372     {
    00373         case Value1:
    00374             stcADST0.STX0 = 0u;
    00375             break;
    00376         case Value4:
    00377             stcADST0.STX0 = 1u;
    00378             break;
    00379         case Value8:
    00380             stcADST0.STX0 = 2u;
    00381             break;
    00382         case Value16:
    00383             stcADST0.STX0 = 3u;
    00384             break;
    00385         case Value32:
    00386             stcADST0.STX0 = 4u;
    00387             break;
    00388         case Value64:
    00389             stcADST0.STX0 = 5u;
    00390             break;
    00391         case Value128:
    00392             stcADST0.STX0 = 6u;
    00393             break;
    00394         case Value256:
    00395             stcADST0.STX0 = 7u;
    00396             break;
    00397         default:
    00398             return ErrorInvalidParameter;
    00399     }
    00400
    00401     if (pstcConfig->u8SamplingTime0 > 31u)
    00402     {
    00403         return ErrorInvalidParameter;
    00404     }
    00405
    00406     stcADST0.ST0 = pstcConfig->u8SamplingTime0;
    00407
    00408     pstcAdc->ADST0_f = stcADST0;
    00409
    00410     // Set Sampling Times Config. 1
    00411     switch (pstcConfig->enSamplingTimeN1)
    00412     {
    00413         case Value1:
    00414             stcADST1.STX1 = 0u;
    00415             break;
    00416         case Value4:
    00417             stcADST1.STX1 = 1u;
    00418             break;
    00419         case Value8:
    00420             stcADST1.STX1 = 2u;
    00421             break;
    00422         case Value16:
    00423             stcADST1.STX1 = 3u;
    00424             break;
    00425         case Value32:
    00426             stcADST1.STX1 = 4u;
    00427             break;
    00428         case Value64:
    00429             stcADST1.STX1 = 5u;
    00430             break;
    00431         case Value128:
    00432             stcADST1.STX1 = 6u;
    00433             break;
    00434         case Value256:
    00435             stcADST1.STX1 = 7u;
    00436             break;
    00437         default:
    00438             return ErrorInvalidParameter;
    00439     }
    00440
    00441     if (pstcConfig->u8SamplingTime1 > 31u)
    00442     {
    00443         return ErrorInvalidParameter;
    00444     }
    00445
    00446     stcADST1.ST1 = pstcConfig->u8SamplingTime1;
    00447
    00448     pstcAdc->ADST1_f = stcADST1;
    00449
    00450     // Frequency Division for ADC Instance
    00451     pstcAdc->ADCT = pstcConfig->u8SamplingMultiplier;
    00452
    00453     // MSB, LSB alignment
    00454     pstcAdc->ADSR_f.FDAS = (TRUE == pstcConfig->bLsbAlignment) ? 1u : 0u;
    00455
    00456     // Set enable time
    00457     pstcAdc->ADCEN &= 0x00FFu;
    00458     pstcAdc->ADCEN |= (uint16_t)((uint16_t)pstcConfig->u8EnableTime << 8u);
    00459
    00460     if(TRUE == pstcConfig->bScanInit)
    00461     {
    00462         // Set Scan Conversion Input Selection Register
    00463         pstcAdc->SCIS0 = (uint8_t)(0x000000FFul & pstcConfig->stcScanInit.u32ScanCannelSelect.u32AD_CHn);
    00464         pstcAdc->SCIS1 = (uint8_t)(0x0000FF00ul & (pstcConfig->stcScanInit.u32ScanCannelSelect.u32AD_CHn >> 8u));
    00465         pstcAdc->SCIS2 = (uint8_t)(0x00FF0000ul & (pstcConfig->stcScanInit.u32ScanCannelSelect.u32AD_CHn >> 16u));
    00466         pstcAdc->SCIS3 = (uint8_t)(0xFF000000ul & (pstcConfig->stcScanInit.u32ScanCannelSelect.u32AD_CHn >> 24u));
    00467
    00468         // Conversion mode single, repeated
    00469         switch (pstcConfig->stcScanInit.enScanMode)
    00470         {
    00471             case ScanSingleConversion:
    00472                 stcSCCR.RPT = 0u;
    00473                 break;
    00474             case ScanRepeatConversion:
    00475                 stcSCCR.RPT = 1u;
    00476                 break;
    00477             default:
    00478                 return ErrorInvalidParameter;
    00479         }
    00480
    00481         // Scan Conversion Timer Start Enable and Timer Source
    00482         if (TRUE == pstcConfig->stcScanInit.bScanTimerStartEnable)
    00483         {
    00484             stcSCCR.SHEN = 1u;
    00485             pstcAdc->SCTSL = (uint8_t) pstcConfig->stcScanInit.enScanTimerTrigger;
    00486         }
    00487
    00488         // Update hardware
    00489         pstcAdc->SCCR_f = stcSCCR;
    00490
    00491         // Scan Conversion FIFO Depth
    00492         if (pstcConfig->stcScanInit.u8ScanFifoDepth > 15u)
    00493         {
    00494             return ErrorInvalidParameter;
    00495         }
    00496
    00497         pstcAdc->SFNS = pstcConfig->stcScanInit.u8ScanFifoDepth;
    00498
    00499     }
    00500
    00501     if(TRUE == pstcConfig->bPrioInit)
    00502     {
    00503         // Priority external Trigger Analog Input
    00504         stcPCCR.ESCE = 0u;
    00505
    00506         // Priority external Trigger Start Enable
    00507         stcPCCR.PEEN = (TRUE == pstcConfig->stcPrioInit.bPrioExtTrigStartEnable) ? 1u : 0u;
    00508
    00509         // Priority Conversion Timer Start Enable and Timer Source
    00510         if (TRUE == pstcConfig->stcPrioInit.bPrioTimerStartEnable)
    00511         {
    00512             stcPCCR.PHEN = 1u;
    00513             pstcAdc->PRTSL = (uint8_t) pstcConfig->stcPrioInit.enPrioTimerTrigger;
    00514         }
    00515
    00516         // Update Hardware
    00517         pstcAdc->PCCR_f = stcPCCR;
    00518
    00519         // Priority Conversion FIFO Stage Count Setup
    00520         pstcAdc->PFNS = pstcConfig->stcPrioInit.u8PrioFifoDepth;
    00521
    00522         // Priority Conversion Input Selection
    00523         if (pstcConfig->stcPrioInit.u8PrioLevel1AnalogChSel > 7u)
    00524         {
    00525             return ErrorInvalidParameter;
    00526         }
    00527         u8PCIS = pstcConfig->stcPrioInit.u8PrioLevel1AnalogChSel & 0x07u;
    00528
    00529         if (pstcConfig->stcPrioInit.u8PrioLevel2AnalogChSel > 31u)
    00530         {
    00531             return ErrorInvalidParameter;
    00532         }
    00533         u8PCIS |= (uint8_t)((uint8_t)(0x1Fu & pstcConfig->stcPrioInit.u8PrioLevel2AnalogChSel) << 3u);
    00534
    00535         pstcAdc->PCIS = u8PCIS;
    00536     }
    00537
    00538     if (TRUE == pstcConfig->bComparisonEnable)
    00539     {
    00540         // Comparison Value
    00541         pstcAdc->CMPD = (((pstcConfig->stcComparisonInit.u16CompareValue >> 2u)) << 6u);
    00542
    00543         if (pstcConfig->stcComparisonInit.u8CompareChannel > 31u)
    00544         {
    00545             return ErrorInvalidParameter;
    00546         }
    00547
    00548         // Comparison Control
    00549         if(pstcConfig->stcComparisonInit.bCompIrqEqualGreater == TRUE)
    00550         {
    00551             u8CMPCR |= 0x40u;
    00552         }
    00553
    00554         if(TRUE == pstcConfig->stcComparisonInit.bCompareAllChannels)
    00555         {
    00556             u8CMPCR |= 0x20u;
    00557         }
    00558
    00559         u8CMPCR |= 0x80u; // Enable comparison function
    00560         u8CMPCR |= (0x1Fu & pstcConfig->stcComparisonInit.u8CompareChannel);
    00561
    00562         pstcAdc->CMPCR = u8CMPCR;
    00563     }
    00564
    00565     if (TRUE == pstcConfig->bRangeComparisonEnable)
    00566     {
    00567         // Set lower and upper value of the range
    00568         pstcAdc->WCMPDH = ((pstcConfig->stcRangeComparisonInit.u16UpperLimitRangeValue >> 2u) << 6u);
    00569         pstcAdc->WCMPDL = ((pstcConfig->stcRangeComparisonInit.u16LowerLimitRangeValue >> 2u) << 6u);
    00570
    00571         if (pstcConfig->stcRangeComparisonInit.u8RangeCountValue > 7u)
    00572         {
    00573             return ErrorInvalidParameter;
    00574         }
    00575
    00576         // Set compare times
    00577         stcWCMPCR.RCODC = pstcConfig->stcRangeComparisonInit.u8RangeCountValue;
    00578         // In-range compare or out-range compare
    00579         stcWCMPCR.RCOIRS = pstcConfig->stcRangeComparisonInit.bWithinRange;
    00580         // Enable range compare function
    00581         stcWCMPCR.RCOE = 1;
    00582         // Compare 1 channel or all
    00583         pstcAdc->WCMPSR_f.WCMD = pstcConfig->stcRangeComparisonInit.bRangeCompareAllChannels;
    00584
    00585         if (pstcConfig->stcRangeComparisonInit.u8RangeComapreChannel > 31u)
    00586         {
    00587             return ErrorInvalidParameter;
    00588         }
    00589
    00590         // Set the channel compared (according to single channel compare mode)
    00591         pstcAdc->WCMPSR_f.WCCH |= pstcConfig->stcRangeComparisonInit.u8RangeComapreChannel;
    00592
    00593         // update hardware
    00594         pstcAdc->WCMPCR_f = stcWCMPCR;
    00595     }
    00596
    00597   return Ok;
    00598 } // Adc_Init
    00599
    00611 en_result_t Adc_DeInit( volatile stc_adcn_t* pstcAdc )
    00612 {
    00613     // Check for NULL pointer
    00614     if (pstcAdc  == NULL)
    00615     {
    00616         return ErrorInvalidParameter ;
    00617     }
    00618
    00619     pstcAdc->ADCEN   = 0u;   // Disable ADC (including ENBL bit)
    00620     pstcAdc->ADCR    = 0u;
    00621     pstcAdc->ADSR    = 0u;
    00622     pstcAdc->SCCR    = 0u;
    00623     pstcAdc->SFNS    = 0u;
    00624     pstcAdc->SCIS0   = 0u;
    00625     pstcAdc->SCIS1   = 0u;
    00626     pstcAdc->SCIS2   = 0u;
    00627     pstcAdc->SCIS3   = 0u;
    00628     pstcAdc->PCCR    = 0u;
    00629     pstcAdc->PFNS    = 0u;
    00630     pstcAdc->PCFD    = 0u;
    00631     pstcAdc->PCIS    = 0u;
    00632     pstcAdc->CMPD    = 0u;
    00633     pstcAdc->CMPCR   = 0u;
    00634     pstcAdc->ADSS0   = 0u;
    00635     pstcAdc->ADSS1   = 0u;
    00636     pstcAdc->ADSS2   = 0u;
    00637     pstcAdc->ADSS3   = 0u;
    00638     pstcAdc->ADST0   = 0u;
    00639     pstcAdc->ADST1   = 0u;
    00640     pstcAdc->ADCEN   = 0u;
    00641     pstcAdc->WCMPDH  = 0u;
    00642     pstcAdc->WCMPCR  = 0u;
    00643     pstcAdc->WCMPDL  = 0u;
    00644     pstcAdc->WCMPSR  = 0u;
    00645     pstcAdc->WCMRCOT = 0u;
    00646     pstcAdc->WCMRCIF = 0u;
    00647     pstcAdc->SCTSL   = 0u;
    00648     pstcAdc->PRTSL   = 0u;
    00649
    00650     return Ok;
    00651 } // Adc_DeInit
    00652
    00653 #if (PDL_INTERRUPT_ENABLE_ADC0 == PDL_ON) || \
    00654     (PDL_INTERRUPT_ENABLE_ADC1 == PDL_ON) || \
    00655     (PDL_INTERRUPT_ENABLE_ADC2 == PDL_ON)
    00656
    00672 en_result_t      Adc_EnableInt(volatile stc_adcn_t* pstcAdc,
    00673                                stc_adc_int_sel_t* pstcIntSel,
    00674                                stc_adc_int_callback_t* pstcIntCallback)
    00675 {
    00676     // Pointer to internal data
    00677     stc_adc_intern_data_t* pstcAdcInternData ;
    00678
    00679     // Check for NULL pointer
    00680     if ((pstcAdc  == NULL) || (pstcIntSel == NULL) || (pstcIntCallback == NULL))
    00681     {
    00682         return ErrorInvalidParameter ;
    00683     }
    00684
    00685     // Get pointer to internal data structure ...
    00686     pstcAdcInternData = AdcGetInternDataPtr( pstcAdc ) ;
    00687
    00688     // Check for instance available or not
    00689     if(pstcAdcInternData == NULL)
    00690     {
    00691         return ErrorInvalidParameter ;
    00692     }
    00693
    00694     if(pstcIntSel->bScanIrq == TRUE)
    00695     {
    00696         pstcAdcInternData->pfnScanCallback = pstcIntCallback->pfnScanCallback;
    00697         pstcAdc->ADCR_f.SCIE = 1;
    00698     }
    00699
    00700     if(pstcIntSel->bPrioIrq == TRUE)
    00701     {
    00702         pstcAdcInternData->pfnPrioCallback = pstcIntCallback->pfnPrioCallback;
    00703         pstcAdc->ADCR_f.PCIE = 1;
    00704     }
    00705
    00706     if(pstcIntSel->bComparisonIrq == TRUE)
    00707     {
    00708         pstcAdcInternData->pfnComparisonCallback = pstcIntCallback->pfnComparisonCallback;
    00709         pstcAdc->ADCR_f.CMPIE = 1;
    00710     }
    00711
    00712     if(pstcIntSel->bRangeComparisonIrq == TRUE)
    00713     {
    00714         pstcAdcInternData->pfnRangeComparisonCallback = pstcIntCallback->pfnRangeComparisonCallback;
    00715         pstcAdc->WCMPCR_f.RCOIE = 1;
    00716     }
    00717
    00718     if(pstcIntSel->bFifoOverrunIrq == TRUE)
    00719     {
    00720         pstcAdcInternData->pfnScanErrorCallback = pstcIntCallback->pfnScanErrorCallback;
    00721         pstcAdcInternData->pfnPrioErrorCallback = pstcIntCallback->pfnPrioErrorCallback;
    00722         pstcAdc->ADCR_f.OVRIE = 1;
    00723     }
    00724
    00725     Adc_InitNvic(pstcAdc);
    00726
    00727     return Ok;
    00728 }
    00729
    00745 en_result_t   Adc_DisableInt(volatile stc_adcn_t* pstcAdc,
    00746                              stc_adc_int_sel_t* pstcIntSel)
    00747 {
    00748     // Pointer to internal data
    00749     stc_adc_intern_data_t* pstcAdcInternData ;
    00750
    00751     // Check for NULL pointer
    00752     if ((pstcAdc  == NULL) || (pstcIntSel == NULL))
    00753     {
    00754         return ErrorInvalidParameter ;
    00755     }
    00756
    00757     // Get pointer to internal data structure ...
    00758     pstcAdcInternData = AdcGetInternDataPtr( pstcAdc ) ;
    00759
    00760     // Check for instance available or not
    00761     if(pstcAdcInternData == NULL)
    00762     {
    00763         return ErrorInvalidParameter ;
    00764     }
    00765
    00766     if(pstcIntSel->bScanIrq == TRUE)
    00767     {
    00768         pstcAdcInternData->pfnScanCallback = NULL;
    00769         pstcAdc->ADCR_f.SCIE = 0;
    00770     }
    00771
    00772     if(pstcIntSel->bPrioIrq == TRUE)
    00773     {
    00774         pstcAdcInternData->pfnPrioCallback = NULL;
    00775         pstcAdc->ADCR_f.PCIE = 0;
    00776     }
    00777
    00778     if(pstcIntSel->bComparisonIrq == TRUE)
    00779     {
    00780         pstcAdcInternData->pfnComparisonCallback = NULL;
    00781         pstcAdc->ADCR_f.CMPIE = 0;
    00782     }
    00783
    00784     if(pstcIntSel->bRangeComparisonIrq == TRUE)
    00785     {
    00786         pstcAdcInternData->pfnRangeComparisonCallback = NULL;
    00787         pstcAdc->WCMPCR_f.RCOIE = 0;
    00788     }
    00789
    00790     if(pstcIntSel->bFifoOverrunIrq == TRUE)
    00791     {
    00792         pstcAdcInternData->pfnScanErrorCallback = NULL;
    00793         pstcAdcInternData->pfnPrioErrorCallback = NULL;
    00794         pstcAdc->ADCR_f.OVRIE = 0;
    00795     }
    00796
    00797     Adc_DeInitNvic(pstcAdc);
    00798
    00799     return Ok;
    00800 }
    00801 #endif
    00802
    00832 boolean_t   Adc_GetIntFlag(volatile stc_adcn_t* pstcAdc, en_adc_int_t enInt)
    00833 {
    00834     boolean_t bRet = FALSE;
    00835     switch(enInt)
    00836     {
    00837         case AdcScanInt:
    00838             bRet = (pstcAdc->ADCR_f.SCIF == 1) ? 1 : 0;
    00839             break;
    00840         case AdcPrioInt:
    00841             bRet = (pstcAdc->ADCR_f.PCIF == 1) ? 1 : 0;
    00842             break;
    00843         case AdcScanFifoOverrunInt:
    00844             bRet = (pstcAdc->SCCR_f.SOVR == 1) ? 1 : 0;
    00845             break;
    00846         case AdcPrioFifoOverrunInt:
    00847             bRet = (pstcAdc->PCCR_f.POVR == 1) ? 1 : 0;
    00848             break;
    00849         case AdcComparisonInt:
    00850             bRet = (pstcAdc->ADCR_f.CMPIF == 1) ? 1 : 0;
    00851             break;
    00852         case AdcRangeComparisonInt:
    00853             bRet = (pstcAdc->WCMRCIF_f.RCINT == 1) ? 1 : 0;
    00854             break;
    00855         default:
    00856             break;
    00857     }
    00858
    00859     return bRet;
    00860 }
    00861
    00881 en_result_t Adc_ClrIntFlag(volatile stc_adcn_t* pstcAdc, en_adc_int_t enInt)
    00882 {
    00883     // Check for NULL pointer
    00884     if (pstcAdc  == NULL)
    00885     {
    00886         return ErrorInvalidParameter ;
    00887     }
    00888
    00889     switch(enInt)
    00890     {
    00891         case AdcScanInt:
    00892             pstcAdc->ADCR_f.SCIF = 0;
    00893             break;
    00894         case AdcPrioInt:
    00895             pstcAdc->ADCR_f.PCIF = 0;
    00896             break;
    00897         case AdcScanFifoOverrunInt:
    00898             pstcAdc->SCCR_f.SOVR = 0;
    00899             break;
    00900         case AdcPrioFifoOverrunInt:
    00901             pstcAdc->PCCR_f.POVR = 0;
    00902             break;
    00903         case AdcComparisonInt:
    00904             pstcAdc->ADCR_f.CMPIF = 0;
    00905             break;
    00906         case AdcRangeComparisonInt:
    00907             pstcAdc->WCMRCIF_f.RCINT = 0;
    00908             break;
    00909         default:
    00910             return ErrorInvalidParameter ;
    00911     }
    00912
    00913     return Ok;
    00914 }
    00915
    00928 en_result_t Adc_Enable( volatile stc_adcn_t* pstcAdc )
    00929 {
    00930     uint32_t u32TimeOutCounter = PDL_ADC_READY_WAIT_COUNT;
    00931
    00932     // Check for NULL pointer
    00933     if (pstcAdc  == NULL)
    00934     {
    00935         return ErrorInvalidParameter ;
    00936     }
    00937
    00938     // Enable ADC
    00939     pstcAdc->ADCEN_f.ENBL = 1u;
    00940
    00941     // Polling for readiness
    00942     while (u32TimeOutCounter)
    00943     {
    00944         if (TRUE == pstcAdc->ADCEN_f.READY)
    00945         {
    00946             return Ok;
    00947         }
    00948
    00949         u32TimeOutCounter--;
    00950     }
    00951
    00952     return ErrorTimeout;
    00953 } // Adc_Enable
    00954
    00967 en_result_t     Adc_Disable( volatile stc_adcn_t* pstcAdc )
    00968 {
    00969     // Check for NULL pointer
    00970     if (pstcAdc  == NULL)
    00971     {
    00972         return ErrorInvalidParameter ;
    00973     }
    00974
    00975     // Disable ADC
    00976     pstcAdc->ADCEN_f.ENBL = 0u;
    00977
    00978     return Ok;
    00979 }
    00980
    00992 en_result_t Adc_SwTriggerScan( volatile stc_adcn_t* pstcAdc )
    00993 {
    00994   // Check for NULL pointer
    00995   if (pstcAdc  == NULL)
    00996   {
    00997     return ErrorInvalidParameter ;
    00998   }
    00999
    01000   pstcAdc->SCCR_f.SSTR = 1u;     // Trigger AD Conversion
    01001
    01002   return Ok;
    01003 } // Adc_SwStart
    01004
    01016 en_result_t  Adc_StopScanRepeat( volatile stc_adcn_t* pstcAdc )
    01017 {
    01018     // Check for NULL pointer
    01019     if (pstcAdc  == NULL)
    01020     {
    01021         return ErrorInvalidParameter ;
    01022     }
    01023
    01024     pstcAdc->SCCR_f.RPT = 0;
    01025
    01026     return Ok;
    01027 }
    01028
    01040 en_result_t Adc_SwTriggerPrio( volatile stc_adcn_t* pstcAdc )
    01041 {
    01042   // Check for NULL pointer
    01043   if (pstcAdc  == NULL)
    01044   {
    01045     return ErrorInvalidParameter ;
    01046   }
    01047
    01048   pstcAdc->PCCR_f.PSTR = 1u;     // Trigger AD Conversion
    01049
    01050   return Ok;
    01051 }
    01052
    01064 en_result_t Adc_ForceStop( volatile stc_adcn_t* pstcAdc )
    01065 {
    01066   // Check for NULL pointer
    01067   if (pstcAdc  == NULL)
    01068   {
    01069     return ErrorInvalidParameter ;
    01070   }
    01071
    01072   pstcAdc->ADSR_f.ADSTP = 1u;
    01073
    01074   return Ok;
    01075 } // Adc_SwStop
    01076
    01112 boolean_t   Adc_GetStatus(volatile stc_adcn_t* pstcAdc, en_adc_status_t enStatus)
    01113 {
    01114     boolean_t bRet = FALSE;
    01115     switch (enStatus)
    01116     {
    01117         case ScanFifoEmptyStatus:
    01118             bRet = (pstcAdc->SCCR_f.SEMP == 1) ? TRUE : FALSE;
    01119             break;
    01120         case ScanFifoFullStatus:
    01121             bRet = (pstcAdc->SCCR_f.SFUL == 1) ? TRUE : FALSE;
    01122             break;
    01123         case PrioFifoEmptyStatus:
    01124             bRet = (pstcAdc->PCCR_f.PEMP == 1) ? TRUE : FALSE;
    01125             break;
    01126         case PrioFifoFullStatus:
    01127             bRet = (pstcAdc->PCCR_f.PFUL == 1) ? TRUE : FALSE;
    01128             break;
    01129         case Prio2PendingStatus:
    01130             bRet = (pstcAdc->ADSR_f.PCNS == 1) ? TRUE : FALSE;
    01131             break;
    01132         case PrioStatus:
    01133             bRet = (pstcAdc->ADSR_f.PCS == 1) ? TRUE : FALSE;
    01134             break;
    01135         case ScanStatus:
    01136             bRet = (pstcAdc->ADSR_f.SCS == 1) ? TRUE : FALSE;
    01137             break;
    01138         case RangeThresholdExcessFlag:
    01139             bRet = (pstcAdc->WCMRCOT_f.RCOOF == 1) ? TRUE : FALSE;
    01140             break;
    01141         default:
    01142             break;
    01143     }
    01144
    01145     return bRet;
    01146 }
    01147
    01162 uint32_t Adc_GetScanFifo( volatile stc_adcn_t* pstcAdc )
    01163 {
    01164   // Check for NULL pointer
    01165   if (pstcAdc  == NULL)
    01166   {
    01167     return 0xFFFFFFFFu;
    01168   }
    01169
    01170   return pstcAdc->SCFD;
    01171 } // Adc_ReadScanFifo
    01172
    01184 en_result_t    Adc_ClrScanFifo(volatile stc_adcn_t* pstcAdc)
    01185 {
    01186     // Check for NULL pointer
    01187     if (pstcAdc  == NULL)
    01188     {
    01189         return ErrorInvalidParameter ;
    01190     }
    01191
    01192     pstcAdc->SCCR_f.SFCLR = 1;
    01193
    01194     return Ok;
    01195 }
    01196
    01212 en_result_t  Adc_ExtractScanFifo(volatile stc_adcn_t* pstcAdc,
    01213                                  uint32_t u32FifoData,
    01214                                  stc_scan_fifo_info_t* pstcFifo)
    01215 {
    01216     // Check for NULL pointer
    01217     if ((pstcAdc  == NULL) || (pstcFifo == NULL))
    01218     {
    01219         return ErrorInvalidParameter ;
    01220     }
    01221
    01222     if(pstcAdc->ADSR_f.FDAS == 0)
    01223     {
    01224         pstcFifo->u16Data = (uint16_t)(u32FifoData >> 20u);
    01225     }
    01226     else
    01227     {
    01228         pstcFifo->u16Data = (uint16_t)(u32FifoData >> 16u);
    01229     }
    01230
    01231     if((u32FifoData & 0x00001000u) == 0x00001000u)
    01232     {
    01233         pstcFifo->bInValid = 1;
    01234     }
    01235     else
    01236     {
    01237         pstcFifo->bInValid = 0;
    01238     }
    01239
    01240     if((u32FifoData & 0x00000300u) == 0x00000000u)
    01241     {
    01242         pstcFifo->enStartCause = ScanStartBySw;
    01243     }
    01244     else if((u32FifoData & 0x00000300u) == 0x00000100u)
    01245     {
    01246         pstcFifo->enStartCause = ScanStartByTimer;
    01247     }
    01248
    01249     pstcFifo->u8Ch = (uint8_t)(u32FifoData & 0x0000001Fu);
    01250
    01251     return Ok;
    01252 }
    01253
    01268 uint32_t Adc_GetPrioFifo( volatile stc_adcn_t* pstcAdc )
    01269 {
    01270     // Check for NULL pointer
    01271     if (pstcAdc  == NULL)
    01272     {
    01273         return 0xFFFFFFFFu;
    01274     }
    01275
    01276     return pstcAdc->PCFD;
    01277 } // Adc_ReadPrioFifo
    01278
    01290 en_result_t  Adc_ClrPrioFifo(volatile stc_adcn_t* pstcAdc)
    01291 {
    01292     // Check for NULL pointer
    01293     if (pstcAdc  == NULL)
    01294     {
    01295         return ErrorInvalidParameter ;
    01296     }
    01297
    01298     pstcAdc->PCCR_f.PFCLR = 1;
    01299
    01300     return Ok;
    01301 }
    01302
    01318 en_result_t    Adc_ExtractPrioFifo(volatile stc_adcn_t* pstcAdc,
    01319                                    uint32_t u32FifoData,
    01320                                    stc_prio_fifo_info_t* pstcFifo)
    01321 {
    01322     // Check for NULL pointer
    01323     if (pstcAdc  == NULL)
    01324     {
    01325         return ErrorInvalidParameter ;
    01326     }
    01327
    01328     if(pstcAdc->ADSR_f.FDAS == 0)
    01329     {
    01330         pstcFifo->u16Data = (uint16_t)(u32FifoData >> 20u);
    01331     }
    01332     else
    01333     {
    01334         pstcFifo->u16Data = (uint16_t)(u32FifoData >> 16u);
    01335     }
    01336
    01337
    01338     if((u32FifoData & 0x00001000u) == 0x00001000u)
    01339     {
    01340         pstcFifo->bInValid = 1;
    01341     }
    01342     else
    01343     {
    01344         pstcFifo->bInValid = 0;
    01345     }
    01346
    01347     if((u32FifoData & 0x00000700u) == 0x00000100u)
    01348     {
    01349         pstcFifo->enStartCause = PrioStartBySw;
    01350     }
    01351     else if((u32FifoData & 0x00000700u) == 0x000000200u)
    01352     {
    01353         pstcFifo->enStartCause = PrioStartByTimer;
    01354     }
    01355     else if((u32FifoData & 0x00000700u) == 0x000000400u)
    01356     {
    01357         pstcFifo->enStartCause = PrioStartByExtTrig;
    01358     }
    01359     pstcFifo->u8Ch = (uint8_t)(u32FifoData & 0x0000001Fu);
    01360
    01361     return Ok;
    01362 }
    01363
    01364
    01366
    01367 #endif // #if (defined(PDL_PERIPHERAL_ADC_ACTIVE))
    01368
    01369 /******************************************************************************/
    01370 /* EOF (not truncated)                                                        */
    01371 /******************************************************************************/