ADC_Initialize
Default mainpageat91libperipheralsadcADC_Initialize
Description Source Call Graph
Start Line: 80
void ADC_Initialize(AT91S_ADC *pAdc, unsigned char idAdc, unsigned char trgEn, unsigned char trgSel, unsigned char sleepMode, unsigned char resolution, unsigned int mckClock, unsigned int adcClock, unsigned int startupTime, unsigned int sampleAndHoldTime)
{
    unsigned int prescal;
    unsigned int startup;
    unsigned int shtim;

    ASSERT(startupTime<=ADC_STARTUP_TIME_MAX, "ADC Bad startupTime\n\r");
    ASSERT(sampleAndHoldTime>=ADC_TRACK_HOLD_TIME_MIN, "ADC Bad sampleAndHoldTime\n\r");

    // Example:
    // 5 MHz operation, 20µs startup time, 600ns track and hold time
    // PRESCAL: Prescaler Rate Selection ADCClock = MCK / ( (PRESCAL+1) * 2 )
    // PRESCAL = [MCK / (ADCClock * 2)] -1 = [48/(5*2)]-1 = 3,8
    // PRESCAL =  4 -> 48/((4+1)*2) = 48/10 = 4.8MHz
    // 48/((3+1)*2) = 48/8 = 6MHz
    // Startup Time = (STARTUP+1) * 8 / ADCClock
    // STARTUP = [(Startup Time * ADCClock)/8]-1 = [(20 10e-6 * 5000000)/8]-1 = 11,5
    // STARTUP = 11 -> (11+1)*8/48000000 = 96/4800000 = 20µs
    //
    // Sample & Hold Time = (SHTIM+1) / ADCClock
    // SHTIM = (HoldTime * ADCClock)-1 = (600 10e-9 * 5000000)-1 = 2
    // SHTIM   =  2 -> (2+1)/4800000 = 1/1200000 = 833ns
    prescal = (mckClock / (2*adcClock)) - 1;
    startup = ((adcClock/1000000) * startupTime / 8) - 1;
    shtim = (((adcClock/1000000) * sampleAndHoldTime)/1000) - 1;

    ASSERT( (prescal<0x3F), "ADC Bad PRESCAL\n\r");
    ASSERT(startup<0x7F, "ADC Bad STARTUP\n\r");
    ASSERT(shtim<0xF, "ADC Bad SampleAndHoldTime\n\r");

    TRACE_DEBUG("adcClock:%d MasterClock:%d\n\r", (mckClock/((prescal+1)*2)), mckClock);
    TRACE_DEBUG("prescal:0x%X startup:0x%X shtim:0x%X\n\r", prescal, startup, shtim);
    
    if( adcClock != (mckClock/((prescal+1)*2)) ) {
        TRACE_WARNING("User and calculated adcClocks are different : user=%d calc=%d\n\r", 
            adcClock, (mckClock/((prescal+1)*2)));
    }

    // Enable peripheral clock    
    AT91C_BASE_PMC->PMC_PCER = 1 << idAdc;    
    
    // Reset the controller
    ADC_SoftReset(pAdc);

    // Write to the MR register
    ADC_CfgModeReg( pAdc,
                    ( trgEn & AT91C_ADC_TRGEN)
                  | ( trgSel & AT91C_ADC_TRGSEL)
                  | ( resolution & AT91C_ADC_LOWRES)            
                  | ( sleepMode & AT91C_ADC_SLEEP)
                  | ( (prescal<<8) & AT91C_ADC_PRESCAL) 
                  | ( (startup<<16) & AT91C_ADC_STARTUP) 
                  | ( (shtim<<24) & AT91C_ADC_SHTIM) );
}