Esempio n. 1
0
/* Reads the differential analog value of two pins (pinP - pinN)
* It waits until the value is read and then returns the result
* If a comparison has been set up and fails, it will return ADC_ERROR_DIFF_VALUE
* Set the resolution, number of averages and voltage reference using the appropriate functions
*/
int ADC_Module::analogReadDifferential(uint8_t pinP, uint8_t pinN)
{
	int32_t result;

	if( ((pinP != A10) && (pinP != A12)) || ((pinN != A11) && (pinN != A13)) ) {
        fail_flag |= ADC_ERROR_WRONG_PIN;
        return ADC_ERROR_DIFF_VALUE;   // all others are invalid
	}

	// increase the counter of measurements
	num_measurements++;

	// check for calibration before setting channels,
	// because conversion will start as soon as we write to *ADC_SC1A
	if (calibrating) wait_for_cal();

	uint8_t res = getResolution();

    // vars to saved the current state of the ADC in case it's in use
    ADC_Config old_config = {0};
    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();
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
        old_config.savedSC1A = *ADC_SC1A;
        old_config.savedCFG1 = *ADC_CFG1;
        old_config.savedCFG2 = *ADC_CFG2;
        old_config.savedSC2 = *ADC_SC2;
        old_config.savedSC3 = *ADC_SC3;
        __enable_irq();
    }

    // no continuous mode
    *ADC_SC3_adco = 0;

    // once *ADC_SC1A is set, conversion will start, enable interrupts if requested
	if ( (pinP == A10) && (pinN == A11) ) { // pins 34 and 35
        __disable_irq();
        #if defined(__MK20DX256__)
        if ( *ADC_PGA & ADC_PGA_PGAEN ) { // PGA is enabled
            if(ADC_num == 0) { // PGA0 connects to A10-A11
                *ADC_SC1A = ADC_SC1_DIFF + 0x2 + var_enableInterrupts*ADC_SC1_AIEN;
                __enable_irq();
            } else { // If this is ADC1 we can't connect to PGA0
                __enable_irq();
                fail_flag |= ADC_ERROR_WRONG_ADC;
                num_measurements--;
                return ADC_ERROR_DIFF_VALUE;
            }
        } else { // no pga
            if(ADC_num == 0) {
                *ADC_SC1A = ADC_SC1_DIFF + 0x0 + var_enableInterrupts*ADC_SC1_AIEN; // In ADC0, A10-A11 is DAD0
                __enable_irq();
            } else if(ADC_num == 1) {
                *ADC_SC1A = ADC_SC1_DIFF + 0x3 + var_enableInterrupts*ADC_SC1_AIEN; // In ADC1, A10-A11 is DAD3
                __enable_irq()
            }
        }
Esempio n. 2
0
/* Starts continuous and differential conversion between the pins (pinP-pinN)
 * It returns as soon as the ADC is set, use analogReadContinuous() to read the value
 * Set the resolution, number of averages and voltage reference using the appropriate functions BEFORE calling this function
*/
bool ADC_Module::startContinuousDifferential(uint8_t pinP, uint8_t pinN) {

    if(!checkDifferentialPins(pinP, pinN)) {
        fail_flag |= ADC_ERROR_WRONG_PIN;
        return false;   // all others are invalid
    }

    // increase the counter of measurements
    num_measurements++;

    // check for calibration before setting channels,
    // because conversion will start as soon as we write to *ADC_SC1A
    if (calibrating) wait_for_cal();

    // save the current state of the ADC in case it's in use
    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();
        saveConfig(&adc_config);
        __enable_irq();
    }

    // set continuous mode
    continuousMode();

    // start conversions
    startDifferentialFast(pinP, pinN);

    return true;
}
Esempio n. 3
0
/* Starts an analog measurement on the pin.
*  It returns inmediately, read value with readSingle().
*  If the pin is incorrect it returns ADC_ERROR_VALUE.
*/
bool ADC_Module::startSingleRead(uint8_t pin) {

    // check whether the pin is correct
    if(!checkPin(pin)) {
        fail_flag |= ADC_ERROR_WRONG_PIN;
        return false;
    }

    if (calibrating) wait_for_cal();

    // save the current state of the ADC in case it's in use
    adcWasInUse = isConverting(); // is the ADC running now?

    if(adcWasInUse) { // this means we're interrupting a conversion
        // save the current conversion config, the adc isr will restore the adc
        __disable_irq();
        saveConfig(&adc_config);
        __enable_irq();
    }

    // no continuous mode
    singleMode();

    // start measurement
    startReadFast(pin);

    return true;
}
void VideoConverter::cancelConversion()
{
	if (isConverting())
	{
		ffmpegProcess->kill();
		ffmpegProcess->waitForFinished();
	}
}
Esempio n. 5
0
/* ======================================================================
Function: waitEndConversion
Purpose : wait for a temperature or RH conversion is done  
Input   : 
Output  : delay in ms the process took. 
Comments: if return >= TH02_CONVERSION_TIME_OUT, time out occured
====================================================================== */
uint8_t TH02::waitEndConversion(void)
{
  // okay this is basic approach not so accurate
  // but avoid using long and millis()
  uint8_t time_out = 0;
  
  // loop until conversion done or duration >= time out
  while (isConverting() && time_out <= TH02_CONVERSION_TIME_OUT )
  {
    ++time_out;
    delay(1);
  }
  
  // return approx time of conversion
  return (time_out);
}
Esempio n. 6
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 ADC_ERROR_VALUE.
* Set the resolution, number of averages and voltage reference using the appropriate functions.
*/
int ADC_Module::analogRead(uint8_t pin)
{
	int32_t result;

	if ( (pin < 0) || (pin > 43) ) {
        fail_flag |= ADC_ERROR_WRONG_PIN;
        return ADC_ERROR_VALUE;   // all others are invalid
    }

    // increase the counter of measurements
	num_measurements++;

	if (calibrating) wait_for_cal();

    // check if we are interrupting a measurement, store setting if so.
    // vars to save the current state of the ADC in case it's in use
    ADC_Config old_config = {0};
    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();
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
        old_config.savedSC1A = *ADC_SC1A;
        old_config.savedCFG1 = *ADC_CFG1;
        old_config.savedCFG2 = *ADC_CFG2;
        old_config.savedSC2 = *ADC_SC2;
        old_config.savedSC3 = *ADC_SC3;
        __enable_irq();
    }

	#if defined(__MK20DX256__)
	// ADC1 has A15=5a and A20=4a so we have to change the mux to read the "a" channels
	if( (ADC_num==1) && ( (pin==26) || (pin==31) ) ) { // mux a
        //*ADC_CFG2 &= ~ADC_CFG2_MUXSEL;
        *ADC_CFG2_muxsel = 0;
	} else { // mux b
        //*ADC_CFG2 |= ADC_CFG2_MUXSEL;
        *ADC_CFG2_muxsel = 1;
	}
	#endif

    // no continuous mode
    *ADC_SC3_adco = 0;

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

	// wait for the ADC to finish
    while(isConverting()) {
        yield();
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
    }

    // it's done, check if the comparison (if any) was true
    __disable_irq(); // make sure nothing interrupts this part
    if (isComplete()) { // conversion succeded
        result = (uint16_t)*ADC_RA;
    } else { // comparison was false
        fail_flag |= ADC_ERROR_COMPARISON;
        result = ADC_ERROR_VALUE;
    }
    __enable_irq();

    // if we interrupted a conversion, set it again
    if (wasADCInUse) {
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
        *ADC_CFG1 = old_config.savedCFG1;
        *ADC_CFG2 = old_config.savedCFG2;
        *ADC_SC2 = old_config.savedSC2;
        *ADC_SC3 = old_config.savedSC3;
        *ADC_SC1A = old_config.savedSC1A;
    }

    num_measurements--;
    return result;

} // analogRead
bool VideoConverter::canStartConversion()
{
	return !isConverting();
}
Esempio n. 8
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 ADC_ERROR_VALUE.
* Set the resolution, number of averages and voltage reference using the appropriate functions.
*/
int ADC_Module::analogRead(uint8_t pin) {

    //digitalWriteFast(LED_BUILTIN, HIGH);

    // check whether the pin is correct
    if(!checkPin(pin)) {
        fail_flag |= ADC_ERROR_WRONG_PIN;
        return ADC_ERROR_VALUE;
    }

    // increase the counter of measurements
    num_measurements++;

    //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));

    if (calibrating) wait_for_cal();

    //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));

    // check if we are interrupting a measurement, store setting if so.
    // vars to save the current state of the ADC in case it's in use
    ADC_Config old_config = {0};
    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();
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
        saveConfig(&old_config);
        __enable_irq();
    }


    // no continuous mode
    singleMode();

    startReadFast(pin); // start single read

    // wait for the ADC to finish
    while(isConverting()) {
        yield();
    }

    // it's done, check if the comparison (if any) was true
    int32_t result;
    __disable_irq(); // make sure nothing interrupts this part
    if (isComplete()) { // conversion succeded
        result = (uint16_t)*ADC_RA;
    } else { // comparison was false
        fail_flag |= ADC_ERROR_COMPARISON;
        result = ADC_ERROR_VALUE;
    }
    __enable_irq();

    // if we interrupted a conversion, set it again
    if (wasADCInUse) {
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
        __disable_irq();
        loadConfig(&old_config);
        __enable_irq();
    }

    num_measurements--;
    return result;

} // analogRead
Esempio n. 9
0
/* Reads the differential analog value of two pins (pinP - pinN)
* It waits until the value is read and then returns the result
* If a comparison has been set up and fails, it will return ADC_ERROR_DIFF_VALUE
* Set the resolution, number of averages and voltage reference using the appropriate functions
*/
int ADC_Module::analogReadDifferential(uint8_t pinP, uint8_t pinN) {

    if(!checkDifferentialPins(pinP, pinN)) {
        fail_flag |= ADC_ERROR_WRONG_PIN;
        return ADC_ERROR_VALUE;   // all others are invalid
    }

    // increase the counter of measurements
    num_measurements++;

    // check for calibration before setting channels,
    // because conversion will start as soon as we write to *ADC_SC1A
    if (calibrating) wait_for_cal();

    uint8_t res = getResolution();

    // vars to saved the current state of the ADC in case it's in use
    ADC_Config old_config = {0};
    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();
        saveConfig(&old_config);
        __enable_irq();
    }

    // no continuous mode
    singleMode();

    startDifferentialFast(pinP, pinN); // start conversion

    // wait for the ADC to finish
    while( isConverting() ) {
        yield();
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
    }

    // it's done, check if the comparison (if any) was true
    int32_t result;
    __disable_irq(); // make sure nothing interrupts this part
    if (isComplete()) { // conversion succeded
        result = (int16_t)(int32_t)(*ADC_RA); // cast to 32 bits
        if(res==16) { // 16 bit differential is actually 15 bit + 1 bit sign
            result *= 2; // multiply by 2 as if it were really 16 bits, so that getMaxValue gives a correct value.
        }
    } else { // comparison was false
        result = ADC_ERROR_VALUE;
        fail_flag |= ADC_ERROR_COMPARISON;
    }
    __enable_irq();

    // if we interrupted a conversion, set it again
    if (wasADCInUse) {
        __disable_irq();
        loadConfig(&old_config);
        __enable_irq();
    }

    num_measurements--;
    return result;

} // analogReadDifferential
Esempio n. 10
0
File: ADC.cpp Progetto: jimparis/ADC
/* 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