8
« on: May 03, 2021, 04:52:19 AM »
Mark,
I have been studying the uTasker ADC documentation, the forum, and ADC_Timers.c for quite some time. I think I understand the process fairly well. However, I am still unable to confidently get resultant data back from the ADC module as I would like.
I am trying to read the voltage on a variable potentiometer. 0-3.3V. Connected to SE14. I know the voltages are changing at the port. I am able to generate the interrupt depending upon the voltage. However, I am unable to see the actual line voltage as read from the ADC module.
Can you explain why I am unable to obtain a valid read from SE14 using the ADC module?
Step 1 - Initialization of ADC configuration:
ADC_SETUP adc_setup; // ADC Setup Structure for Headphone Rotary Dial (POT)
ADC_RESULTS adc_results; // ADC Raw Voltage Level of Headphone Rotary Dial (POT)
#define AD_DA_BUFFER_LENGTH (8 * 1024) // DMA buffer for 1s at 8k bytes/s
static signed short sADC_buffer[AD_DA_BUFFER_LENGTH] = {0}; // 16 bit samples
// ADC Setup for Headphone Rotary Dial (POT) Calibration
adc_setup.int_type = ADC_INTERRUPT; // identifier when configuring
adc_setup.int_handler = 0; // adc INT handler routine
adc_setup.dma_int_priority = 3; // priority of DMA interrupt the user wants to set
adc_setup.dma_int_handler = 0; // no interrupt so that free-running circular buffer is used (when ADC_FULL_BUFFER_DMA_AUTO_REPEAT is not defined)
adc_setup.ucDmaChannel = 6;
adc_setup.ptrADC_Buffer = sADC_buffer; // ADC sample buffer to be used
adc_setup.ulADC_buffer_length = sizeof(sADC_buffer); // physical length of the buffer
adc_setup.usDmaTriggerSource = 0; // default trigger is the ADC conversion completion of the channel in question
adc_setup.pga_gain = PGA_GAIN_OFF; // {13} PGA gain can be specified for certain inputs
adc_setup.int_priority = PRIORITY_ADC; // ADC interrupt priority
adc_setup.int_adc_controller = 1; // ADC controller 1
adc_setup.int_adc_int_type = (ADC_SINGLE_SHOT_TRIGGER_INT); // interrupt type
adc_setup.int_adc_offset = 0; // no offset
adc_setup.int_adc_bit = ADC_SE14_SINGLE; // SE14 Pin
adc_setup.int_adc_mode = (ADC_CALIBRATE | ADC_SELECT_INPUTS_A | ADC_CLOCK_BUS_DIV_2 | ADC_CLOCK_DIVIDE_8 | ADC_SAMPLE_ACTIVATE_LONG | ADC_CONFIGURE_ADC | ADC_REFERENCE_VREF | ADC_CONFIGURE_CHANNEL | ADC_SINGLE_ENDED_INPUT | ADC_SINGLE_SHOT_MODE | ADC_12_BIT_MODE | ADC_SW_TRIGGERED);
adc_setup.int_adc_sample = (ADC_SAMPLE_LONG_PLUS_12 | ADC_SAMPLE_AVERAGING_32); // additional sampling clocks
adc_setup.int_adc_result = 0; // no result is requested at this stage
fnConfigureInterrupt((void *)&adc_setup); // Perform Configure and Calibration of ADC Channel
Step 2 - Setup the interrupt for the ADC: (just triggering on any voltage below 1.0V, which seems to trigger properly)
adc_setup.int_adc_controller = 1; // ADC controller 1
adc_setup.int_adc_bit = ADC_SE14_SINGLE;
adc_setup.int_adc_int_type = (ADC_LOW_LIMIT_INT); // interrupt type (trigger only when lower than the defined level)
adc_setup.int_low_level_trigger = (unsigned short)(ADC_VOLT * 1.0); // the low level trigger threshold represented as input voltage (note: setting low threshold higher than the high threshold causes a trigger inside the range rather than outside of it)
adc_setup.int_handler = GetRotaryPos; // handling function
adc_setup.int_adc_result = &adc_results; // I want to know the current value
adc_setup.int_adc_mode = (ADC_SELECT_INPUTS_A | ADC_CLOCK_BUS_DIV_2 | ADC_CLOCK_DIVIDE_8 | ADC_SAMPLE_ACTIVATE_LONG | ADC_CONFIGURE_ADC | ADC_REFERENCE_VREF | ADC_CONFIGURE_CHANNEL | ADC_SINGLE_ENDED_INPUT | ADC_SINGLE_SHOT_MODE | ADC_12_BIT_MODE | ADC_SW_TRIGGERED); // note that the first configuration should calibrate the ADC - single shot with interrupt on completion {12}
fnConfigureInterrupt((void *)&adc_setup); // start operation now
Step 3 - Evaluate the results of the analog line and setup the ADC for subsequent interrupts:
void GetRotaryPos(void) // Service Routine for ADC Rotary Dial Read
{
signed short rotary_raw; // value of SE14 pin voltage
// ucADC_status[0] and [1] are always not valid (0)
if (adc_results.ucADC_status[0] == ADC_RESULT_VALID) // if the conversion is ready
rotary_raw = adc_results.sADC_value[0];
else
rotary_raw = 0;
// Relaunch ADC Interrupt for Headphone Rotary Dial (POT) - Get Value of Rotary Dial Position (voltage level)
// ...
return;
}
Result: rotary_raw is always 0. Goal: rotary_raw should be between 0.0 and 3.3. In this interrupt example above, rotary_raw should be between 0.0 and 1.0.
Any suggestions?
Regards,
Phil