int_fast16_t ADCLPF3_convert(ADC_Handle handle, uint16_t *value) { ADCLPF3_HWAttrs const *hwAttrs; int_fast16_t conversionResult = ADC_STATUS_SUCCESS; uint32_t conversionValue; uint32_t interruptStatus; uint32_t semaphorePendTimeout = HwiP_inISR() ? SemaphoreP_NO_WAIT : SemaphoreP_WAIT_FOREVER; DebugP_assert(handle); /* Get handle */ hwAttrs = handle->hwAttrs; /* Acquire the lock for this particular ADC handle */ if (SemaphoreP_pend(&ADCLPF3_adcSemaphore, semaphorePendTimeout) != SemaphoreP_OK) { return ADC_STATUS_ERROR; } /* Set constraints to guarantee operation */ Power_setConstraint(PowerLPF3_DISALLOW_STANDBY); /* Make sure conversion is disabled to allow configuration changes */ ADCDisableConversion(); /* Specify range of ctrl registers for conversion. Use ctrl register 0 */ ADCSetMemctlRange(0, 0); /* Set clock-divider and sampling duration */ ADCSetSampleDuration(hwAttrs->adcClkkDivider, hwAttrs->samplingDuration); /* Set sampling mode to auto, meaning the sample duration is determined by * sample duration configured above. */ ADCSetSamplingMode(ADC_SAMPLE_MODE_AUTO); /* Set resolution */ ADCSetResolution(hwAttrs->resolutionBits); /* Set reference source */ ADCSetInput(hwAttrs->refSource, hwAttrs->internalChannel, 0); /* Pass correct offset-value to ADC peripheral, depending on reference source */ ADCSetAdjustmentOffset(hwAttrs->refSource); /* Configure ADC to only do one conversion */ ADCSetSequence(ADC_SEQUENCE_SINGLE); /* Use software trigger source */ ADCSetTriggerSource(ADC_TRIGGER_SOURCE_SOFTWARE); /* Enable conversion. ADC will wait for trigger. */ ADCEnableConversion(); /* Start conversion. No need to call ADCStopConversion() since that is only * needed in manual sampling mode. */ ADCStartConversion(); /* There is a delay of 9 cycles on CC23X0 and 18 cycles on CC27XX between * writing the SC_START bit, and the BUSY-bit going high. If we start * polling too early, we will miss it. Delay 6 loops, where each loop is * minimum 3 cycles. */ CPUDelay(6); /* Read out conversion (blocking while ADC is busy) */ conversionValue = ADCReadResult(0); /* Check if something went wrong. (Underflow or overflow) */ interruptStatus = ADCRawInterruptStatus(); if (interruptStatus & (ADC_INT_OVIFG | ADC_INT_UVIFG)) { conversionResult = ADC_STATUS_ERROR; } /* Clear all interrupts generated by ADC */ ADCClearInterrupt(0xFFFFFFFF); /* Allow entering standby again after ADC conversion complete */ Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY); /* Release the lock for this particular ADC handle */ SemaphoreP_post(&ADCLPF3_adcSemaphore); /* If we want to return the trimmed value, calculate it here. */ if (hwAttrs->returnAdjustedVal) { uint16_t gain = ADCGetAdjustmentGain(hwAttrs->refSource); conversionValue = ADCAdjustValueForGain(conversionValue, hwAttrs->resolutionBits, gain); } *value = conversionValue; /* Return the status-code of the conversion */ return conversionResult; }