adc.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *   adc.c:  ADC module file for Philips LPC214x Family Microprocessors
00003  *
00004  *   Copyright(C) 2006, Philips Semiconductor
00005  *   All rights reserved.
00006  *
00007  *   History
00008  *   2005.10.01  ver 1.00    Prelimnary version, first Release
00009  *
00010 ******************************************************************************/
00011 #include "LPC214x.h"                        /* LPC21xx definitions */
00012 #include "type.h"
00013 #include "irq.h"
00014 #include "target.h"
00015 #include "adc.h"
00016 
00017 volatile unsigned int ADC0Value[ADC_NUM], ADC1Value[ADC_NUM];
00018 volatile unsigned int ADC0IntDone = 0, ADC1IntDone = 0;
00019 unsigned int adcChannelValues[8];
00020 
00021 #if ADC_INTERRUPT_FLAG
00022 /******************************************************************************
00023 ** Function name:               ADC0Handler
00024 **
00025 ** Descriptions:                ADC0 interrupt handler
00026 **
00027 ** parameters:                  None
00028 ** Returned value:              None
00029 **
00030 ******************************************************************************/
00031 void ADC0Handler (void) __irq
00032 {
00033     unsigned int regVal;
00034 
00035     IENABLE;                    /* handles nested interrupt */
00036 
00037     regVal = AD0STAT;           /* Read ADC will clear the interrupt */
00038     if ( regVal & 0x0000FF00 )  /* check OVERRUN error first */
00039     {
00040         regVal = (regVal & 0x0000FF00) >> 0x08;
00041                                 /* if overrun, just read ADDR to clear */
00042                                 /* regVal variable has been reused. */
00043         switch ( regVal )
00044         {
00045             case 0x01:
00046                 regVal = AD0DR0;
00047                 break;
00048             case 0x02:
00049                 regVal = AD0DR1;
00050                 break;
00051             case 0x04:
00052                 regVal = AD0DR2;
00053                 break;
00054             case 0x08:
00055                 regVal = AD0DR3;
00056                 break;
00057             case 0x10:
00058                 regVal = AD0DR4;
00059                 break;
00060             case 0x20:
00061                 regVal = AD0DR5;
00062                 break;
00063             case 0x40:
00064                 regVal = AD0DR6;
00065                 break;
00066             case 0x80:
00067                 regVal = AD0DR7;
00068                 break;
00069             default:
00070                 break;
00071         }
00072         AD0CR &= 0xF8FFFFFF;    /* stop ADC now */
00073         ADC0IntDone = 1;
00074         return;
00075     }
00076 
00077     if ( regVal & ADC_ADINT )
00078     {
00079         switch ( regVal & 0xFF )        /* check DONE bit */
00080         {
00081             case 0x01:
00082                 ADC0Value[0] = ( AD0DR0 >> 6 ) & 0x3FF;
00083                 break;
00084             case 0x02:
00085                 ADC0Value[1] = ( AD0DR1 >> 6 ) & 0x3FF;
00086                 break;
00087             case 0x04:
00088                 ADC0Value[2] = ( AD0DR2 >> 6 ) & 0x3FF;
00089                 break;
00090             case 0x08:
00091                 ADC0Value[3] = ( AD0DR3 >> 6 ) & 0x3FF;
00092                 break;
00093             case 0x10:
00094                 ADC0Value[4] = ( AD0DR4 >> 6 ) & 0x3FF;
00095                 break;
00096             case 0x20:
00097                 ADC0Value[5] = ( AD0DR5 >> 6 ) & 0x3FF;
00098                 break;
00099             case 0x40:
00100                 ADC0Value[6] = ( AD0DR6 >> 6 ) & 0x3FF;
00101                 break;
00102             case 0x80:
00103                 ADC0Value[7] = ( AD0DR7 >> 6 ) & 0x3FF;
00104                 break;
00105             default:
00106                 break;
00107         }
00108         AD0CR &= 0xF8FFFFFF;    /* stop ADC now */
00109         ADC0IntDone = 1;
00110     }
00111 
00112     IDISABLE;
00113     VICVectAddr = 0;            /* Acknowledge Interrupt */
00114 }
00115 
00116 /******************************************************************************
00117 ** Function name:               ADC1Handler
00118 **
00119 ** Descriptions:                ADC1 interrupt handler
00120 **
00121 ** parameters:                  None
00122 ** Returned value:              None
00123 **
00124 ******************************************************************************/
00125 void ADC1Handler (void) __irq
00126 {
00127     unsigned int regVal;
00128 
00129     IENABLE;                    /* handles nested interrupt */
00130 
00131     regVal = AD1STAT;           /* Read ADC will clear the interrupt */
00132     if ( regVal & 0x0000FF00 )  /* check OVERRUN error first */
00133     {
00134         regVal = (regVal & 0x0000FF00) >> 0x08;
00135                                 /* if overrun, just read AD1DRx to clear */
00136                                 /* regVal variable has been reused. */
00137         switch ( regVal )
00138         {
00139             case 0x01:
00140                 regVal = AD1DR0;
00141                 break;
00142             case 0x02:
00143                 regVal = AD1DR1;
00144                 break;
00145             case 0x04:
00146                 regVal = AD1DR2;
00147                 break;
00148             case 0x08:
00149                 regVal = AD1DR3;
00150                 break;
00151             case 0x10:
00152                 regVal = AD1DR4;
00153                 break;
00154             case 0x20:
00155                 regVal = AD1DR5;
00156                 break;
00157             case 0x40:
00158                 regVal = AD1DR6;
00159                 break;
00160             case 0x80:
00161                 regVal = AD1DR7;
00162                 break;
00163             default:
00164                 break;
00165         }
00166         AD1CR &= 0xF8FFFFFF;    /* stop ADC now */
00167         ADC1IntDone = 1;
00168         return;
00169     }
00170 
00171     if ( regVal & ADC_ADINT )
00172     {
00173         switch ( regVal & 0xFF )        /* check DONE bit */
00174         {
00175             case 0x01:
00176                 ADC1Value[0] = ( AD1DR0 >> 6 ) & 0x3FF;
00177                 break;
00178             case 0x02:
00179                 ADC1Value[1] = ( AD1DR1 >> 6 ) & 0x3FF;
00180                 break;
00181             case 0x04:
00182                 ADC1Value[2] = ( AD1DR2 >> 6 ) & 0x3FF;
00183                 break;
00184             case 0x08:
00185                 ADC1Value[3] = ( AD1DR3 >> 6 ) & 0x3FF;
00186                 break;
00187             case 0x10:
00188                 ADC1Value[4] = ( AD1DR4 >> 6 ) & 0x3FF;
00189                 break;
00190             case 0x20:
00191                 ADC1Value[5] = ( AD1DR5 >> 6 ) & 0x3FF;
00192                 break;
00193             case 0x40:
00194                 ADC1Value[6] = ( AD1DR6 >> 6 ) & 0x3FF;
00195                 break;
00196             case 0x80:
00197                 ADC1Value[7] = ( AD1DR7 >> 6 ) & 0x3FF;
00198                 break;
00199             default:
00200                 break;
00201         }
00202         AD1CR &= 0xF8FFFFFF;    /* stop ADC now */
00203         ADC1IntDone = 1;
00204     }
00205 
00206     IDISABLE;
00207     VICVectAddr = 0;            /* Acknowledge Interrupt */
00208 }
00209 #endif
00210 
00211 /*****************************************************************************
00212 ** Function name:               ADCInit
00213 **
00214 ** Descriptions:                initialize ADC channel
00215 **
00216 ** parameters:                  ADC clock rate
00217 ** Returned value:              true or false
00218 **
00219 *****************************************************************************/
00220 unsigned int ADCInit( unsigned int ADC_Clk )
00221 {
00222            AD0CR = ( 0x01 ) |   // SEL=1,select channel 0, 1 to 4 on ADC0
00223                 ( ( Fpclk / ADC_Clk - 1 ) << 8 ) |  // CLKDIV = Fpclk / 1000000 - 1
00224                 ( 1 << 16 ) |           // BURST = 0, no BURST, software controlled
00225                 ( 0 << 17 ) |           // CLKS = 0, 11 clocks/10 bits
00226                 ( 1 << 21 ) |           // PDN = 1, normal operation
00227                 ( 0 << 22 ) |           // TEST1:0 = 00
00228                 ( 0 << 24 ) |           // START = 0 A/D conversion stops
00229                 ( 0 << 27 );            /* EDGE = 0 (CAP/MAT singal falling,trigger A/D
00230                                         conversion) */
00231 
00232 
00233       /*
00234         AD0CR = ( 0x01 << 0 ) |         // SEL=1,select channel 0, 1 to 4 on ADC0
00235         ( ( Fpclk / ADC_Clk - 1 ) << 8 ) |  // CLKDIV = Fpclk / 1000000 - 1
00236         ( 0 << 16 ) |           // BURST = 0, no BURST, software controlled
00237         ( 0 << 17 ) |           // CLKS = 0, 11 clocks/10 bits
00238         ( 1 << 21 ) |           // PDN = 1, normal operation
00239         ( 0 << 22 ) |           // TEST1:0 = 00
00240         ( 0 << 24 ) |           // START = 0 A/D conversion stops
00241         ( 0 << 27 );            // EDGE = 0 (CAP/MAT singal falling,trigger A/D
00242                                 conversion) */
00243 
00244     AD1CR = ( 0x01 << 0 ) |     // SEL=1,select channel 0, 0 to 7 on ADC1
00245         ( ( Fpclk / ADC_Clk - 1 ) << 8 ) |  // CLKDIV = Fpclk / 1000000 - 1
00246         ( 0 << 16 ) |           // BURST = 0, no BURST, software controlled
00247         ( 0 << 17 ) |           // CLKS = 0, 11 clocks/10 bits
00248         ( 1 << 21 ) |           // PDN = 1, normal operation
00249         ( 0 << 22 ) |           // TEST1:0 = 00
00250         ( 0 << 24 ) |           // START = 0 A/D conversion stops
00251         ( 0 << 27 );            /* EDGE = 0 (CAP/MAT singal falling,trigger A/D
00252                                 conversion) */
00253 
00254     /* If POLLING, no need to do the following */
00255 #if ADC_INTERRUPT_FLAG
00256     AD0INTEN = 0x11E;           // Enable all interrupts
00257     AD1INTEN = 0x1FF;
00258 
00259     if ( install_irq( ADC0_INT, (void *)ADC0Handler ) == FALSE )
00260     {
00261         return (FALSE);
00262     }
00263     if ( install_irq( ADC1_INT, (void *)ADC1Handler ) == FALSE )
00264     {
00265         return (FALSE);
00266     }
00267 #endif
00268 
00269     return (TRUE);
00270 }
00271 
00272 /*****************************************************************************
00273 ** Function name:               ADC0Read
00274 **
00275 ** Descriptions:                Read ADC0 channel
00276 **
00277 ** parameters:                  Channel number
00278 ** Returned value:              Value read, if interrupt driven, return channel #
00279 **
00280 *****************************************************************************/
00281 unsigned int ADC0Read( unsigned char channelNum )
00282 {
00283 #if !ADC_INTERRUPT_FLAG
00284     unsigned int regVal, ADC_Data;
00285     volatile unsigned int timeout=0;
00286 #endif
00287 
00288     /* channel number is 0 through 7 */
00289     if ( channelNum >= ADC_NUM )
00290     {
00291         channelNum = 0;         /* reset channel number to 0 */
00292     }
00293     AD0CR &= 0xFFFFFF00;
00294     AD0CR |= (1 << 24) | (1 << channelNum);
00295                                 /* switch channel,start A/D convert */
00296 #if !ADC_INTERRUPT_FLAG
00297     while ( timeout++<5000 )                    /* wait until end of A/D convert */
00298     {
00299         regVal = *(volatile unsigned long *)(AD0_BASE_ADDR
00300                         + ADC_OFFSET + ADC_INDEX * channelNum);
00301                                 /* read result of A/D conversion */
00302         if ( regVal & ADC_DONE )
00303         {
00304             break;
00305         }
00306     }
00307 
00308     AD0CR &= 0xF8FFFFFF;        /* stop ADC now */
00309     if ( regVal & ADC_OVERRUN ) /* save data when it's not overrun
00310                                 otherwise, return zero */
00311     {
00312         return ( 0 );
00313     }
00314     ADC_Data = ( regVal >> 6 ) & 0x3FF;
00315     return ( ADC_Data );        /* return A/D conversion value */
00316 #else
00317     return ( channelNum );      /* if it's interrupt driven, the
00318                                 ADC reading is done inside the handler.
00319                                 so, return channel number */
00320 #endif
00321 }
00322 
00323 /*****************************************************************************
00324 ** Function name:               ADC1Read
00325 **
00326 ** Descriptions:                Read ADC1 channel
00327 **
00328 ** parameters:                  Channel number
00329 ** Returned value:              Value read, if interrupt driven, return channel #
00330 **
00331 *****************************************************************************/
00332 unsigned int ADC1Read( unsigned char channelNum )
00333 {
00334 #if !ADC_INTERRUPT_FLAG
00335     unsigned int regVal;
00336         unsigned int ADC_Data;
00337 #endif
00338 
00339     /* channel number is 0 through 7 */
00340     if ( channelNum >= ADC_NUM )
00341     {
00342         channelNum = 0;         /* reset channel number to 0 */
00343     }
00344     AD1CR &= 0xFFFFFF00;
00345     AD1CR |= (1 << 24) | (1 << channelNum);
00346                                 /* switch channel,start A/D convert */
00347 #if !ADC_INTERRUPT_FLAG
00348     while ( 1 )                 /* wait until end of A/D convert */
00349     {
00350         regVal = *(volatile unsigned long *)(AD1_BASE_ADDR
00351                         + ADC_OFFSET + ADC_INDEX * channelNum);
00352                                 /* read result of A/D conversion */
00353         if ( regVal & ADC_DONE )
00354         {
00355             break;
00356         }
00357     }
00358 
00359     AD1CR &= 0xF8FFFFFF;        /* stop ADC now */
00360     if ( regVal & ADC_OVERRUN ) /* save data when it's not overrun
00361                                 otherwise, return zero */
00362     {
00363         return ( 0 );
00364     }
00365 
00366     ADC_Data = ( regVal >> 6 ) & 0x3FF;
00367     return ( ADC_Data );        /* return A/D conversion value */
00368 #else
00369     return ( channelNum );
00370 #endif
00371 }
00372 
00373 void ADC0triggerSampling(unsigned char selectChannels)
00374 {
00375         AD0CR |= (selectChannels);
00376 
00377 }
00378 
00379 void ADC0getSamplingResults(unsigned char selectChannels, unsigned int * channelValues)
00380 {
00381         int i;
00382         //get last result from all selected channels
00383         for (i=0;i<8;i++)
00384                 if (selectChannels&(1<<i))
00385                 {
00386                     unsigned int regVal;
00387 
00388                         regVal=*(volatile unsigned long *)(AD0_BASE_ADDR
00389                                         + ADC_OFFSET + ADC_INDEX * i);
00390 
00391                         if ((regVal&(ADC_OVERRUN|ADC_DONE))==0)
00392                                         channelValues[i]=0;
00393                         else
00394                                         channelValues[i]=( regVal >> 6 ) & 0x3FF;
00395                 }
00396 }
00397 
00398 /*********************************************************************************
00399 **                            End Of File
00400 *********************************************************************************/


asctec_hl_firmware
Author(s): Markus Achtelik, Michael Achtelik, Stephan Weiss, Laurent Kneip
autogenerated on Tue Jan 7 2014 11:05:19