/******************************************************************************* * @brief Configures the GPIO for ADC1 * @param void * @retval void *******************************************************************************/ float ADC_SampleAndConv(ADC_TypeDef* ADCx) { /* Check the parameters */ APP_ASSERT(ADCx == ADC1); uint32_t TimeCnt=0; #ifdef DYNAMENT_DEBUG printf("batt require start \r\n"); #endif /* Re-enable DMA and ADC conf and start Temperature Data acquisition */ acquireVoltageValue(); TimeCnt = 160000; /* for DEBUG purpose uncomment the following line and comment the __WFI call to do not enter STOP mode */ while ((!flag_ADCDMA_TransferComplete) && (TimeCnt !=0)) { TimeCnt--; } if(!TimeCnt) { #ifdef DYNAMENT_DEBUG printf("ADC timeout.\r\n"); #endif } /* Clear global flag for DMA transfert complete */ ClearADCDMA_TransferComplete(); #ifdef DYNAMENT_DEBUG printf("batt require stop \r\n"); #endif powerDownADC(); #ifdef DYNAMENT_DEBUG // for(int32_t index = 0;index < ADC_CONV_BUFF_SIZE;index ++) // { // printf("ADC_ConvertedValueBuff[%d] = 0x%x.\r\n",index,ADC_ConvertedValueBuff[index]); // } #endif return (ComputeRealVoltage()); }
uint8_t noisyADCRead(const bool /*powerUpIO*/) { const bool neededEnable = powerUpADCIfDisabled(); #ifndef IGNORE_POWERUPIO const bool poweredUpIO = powerUpIO; if(powerUpIO) { power_intermittent_peripherals_enable(false); } #endif // Sample supply voltage. ADMUX = _BV(REFS0) | 14; // Bandgap vs Vcc. ADCSRB = 0; // Enable free-running mode. bitWrite(ADCSRA, ADATE, 0); // Multiple samples NOT required. ADC_complete = false; bitSet(ADCSRA, ADIE); // Turn on ADC interrupt. bitSet(ADCSRA, ADSC); // Start conversion. uint8_t count = 0; while(!ADC_complete) { ++count; } // Busy wait while 'timing' the ADC conversion. const uint8_t l1 = ADCL; // Capture the low byte and latch the high byte. const uint8_t h1 = ADCH; // Capture the high byte. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR V: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(h1, HEX); V0P2BASE_DEBUG_SERIAL_PRINT(' '); V0P2BASE_DEBUG_SERIAL_PRINTFMT(l1, HEX); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif // Sample internal temperature. ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); // Temp vs bandgap. ADC_complete = false; bitSet(ADCSRA, ADSC); // Start conversion. while(!ADC_complete) { ++count; } // Busy wait while 'timing' the ADC conversion. const uint8_t l2 = ADCL; // Capture the low byte and latch the high byte. const uint8_t h2 = ADCH; // Capture the high byte. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR T: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(h2, HEX); V0P2BASE_DEBUG_SERIAL_PRINT(' '); V0P2BASE_DEBUG_SERIAL_PRINTFMT(l2, HEX); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif uint8_t result = (h1 << 5) ^ (l2) ^ (h2 << 3) ^ count; #if defined(CATCH_OTHER_NOISE_DURING_NAR) result = _crc_ibutton_update(_adcNoise++, result); #endif // Sample all possible ADC inputs relative to Vcc, whatever the inputs may be connected to. // Assumed never to do any harm, eg physical damage, nor to disturb I/O setup. for(uint8_t i = 0; i < 8; ++i) { ADMUX = (i & 7) | (DEFAULT << 6); // Switching MUX after sample has started may add further noise. ADC_complete = false; bitSet(ADCSRA, ADSC); // Start conversion. while(!ADC_complete) { ++count; } const uint8_t l = ADCL; // Capture the low byte and latch the high byte. const uint8_t h = ADCH; // Capture the high byte. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR M: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(h, HEX); V0P2BASE_DEBUG_SERIAL_PRINT(' '); V0P2BASE_DEBUG_SERIAL_PRINTFMT(l, HEX); V0P2BASE_DEBUG_SERIAL_PRINT(' '); V0P2BASE_DEBUG_SERIAL_PRINT(count); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif result = _crc_ibutton_update(result ^ h, l ^ count); // A thorough hash. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR R: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(result, HEX); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif } bitClear(ADCSRA, ADIE); // Turn off ADC interrupt. bitClear(ADCSRA, ADATE); // Turn off ADC auto-trigger. #ifndef IGNORE_POWERUPIO if(poweredUpIO) { power_intermittent_peripherals_disable(); } #endif if(neededEnable) { powerDownADC(); } result ^= l1; // Ensure that the Vcc raw lsbs get directly folded in to the final result. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(result, HEX); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif return(result); // Use all the bits collected. }