/* 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() } }
/* 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; }
/* 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(); } }
/* ====================================================================== 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); }
/* 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(); }
/* 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
/* 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
/* 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