PDL for FM0+  Version1.0
Peripheral Driverl Library for FM0+
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 /******************************************************************************/