Beispiel #1
0
SX Variable::highest() const{
  if(isDifferential()){
    return der();
  } else {
    return var();
  }
}
Beispiel #2
0
/* Reads the analog value of the pin.
* It waits until the value is read and then returns the result.
* If a comparison has been set up and fails, it will return -1.
* Set the resolution, number of averages and voltage reference using the appropriate functions.
*/
int ADC::analogRead(uint8_t pin)
{
	uint16_t result;

	if (pin >= 14 && pin <= 39) {
		if (pin <= 23) {
			pin -= 14;  // 14-23 are A0-A9
		} else if (pin >= 34) {
			pin -= 24;  // 34-37 are A10-A13, 38 is temp sensor, 39 is vref
		}
    } else {
        return ADC_ERROR_VALUE;   // all others are invalid
    }

	if (calibrating) wait_for_cal();

	uint8_t res = getResolution();
	uint8_t diffRes = 0; // is the new resolution different from the old one?

    // vars to save the current state of the ADC in case it's in use
    uint32_t savedSC1A, savedSC2, savedSC3, savedCFG1, savedCFG2, savedRes;
    uint8_t wasADCInUse = isConverting(); // is the ADC running now?

    if(wasADCInUse) { // this means we're interrupting a conversion
        // save the current conversion config, we don't want any other interrupts messing up the configs
        __disable_irq();
        //GPIOC_PSOR = 1<<5;
        savedRes = res;
        savedSC1A = ADC0_SC1A;
        savedCFG1 = ADC0_CFG1;
        savedSC2 = ADC0_SC2;
        savedSC3 = ADC0_SC3;

        // change the comparison values if interrupting a 16 bits and diff mode
        if(res==16 && isDifferential()) {
            ADC0_CV1 /= 2;
            ADC0_CV2 /= 2;
        }

        // disable continuous mode in case analogRead is interrupting a continuous mode
        ADC0_SC3 &= !ADC_SC3_ADCO;

        __enable_irq(); ////keep irq disabled until we start our conversion

    }


    // if the resolution is incorrect (i.e. 9, 11 or 13) silently correct it
	if( (res==9) || (res==11) || (res==13) ) {
        setResolution(res-1);
        diffRes = 1; // resolution changed
	}

    __disable_irq();
    ADC0_SC1A = channel2sc1a[pin] + var_enableInterrupts*ADC_SC1_AIEN; // start conversion on pin and with interrupts enabled if requested
	__enable_irq();


	while (1) {
		__disable_irq();
		if ((ADC0_SC1A & ADC_SC1_COCO)) { // conversion completed
			result = ADC0_RA;

			// if we interrupted a conversion, set it again
            if (wasADCInUse) {
                //GPIOC_PCOR = 1<<5;

                // restore ADC config, and restart conversion
                if(diffRes) setResolution(savedRes); // don't change res if isn't necessary
                if(res==16 && ((savedSC1A & ADC_SC1_DIFF) >> 5) )  { // change back the comparison values if interrupting a 16 bits and diff mode
                    ADC0_CV1 *= 2;
                    ADC0_CV2 *= 2;
                }
                ADC0_CFG1 = savedCFG1;
                ADC0_SC2 = savedSC2 & 0x7F; // restore first 8 bits
                ADC0_SC3 = savedSC3 & 0xF; // restore first 4 bits
                ADC0_SC1A = savedSC1A & 0x7F; // restore first 8 bits
            }
			__enable_irq();
			return result;
		} else if( ((ADC0_SC2 & ADC_SC2_ADACT) == 0) && ((ADC0_SC1A & ADC_SC1_COCO) == 0) ) { // comparison was false