I'm using MQX 4.0 and am using _io_read to read values from one the internal ADC modules on a MK10 mirco. My read logic is similar to:
if ( _io_read(...) ) {
do something
} else {
write error message to console
}
Every so often, the _io_read function returns an error value and I get an error message on the console output. I'm having trouble trying to understand what's causing the error & am hoping for some help. How can I translate the return value of the function to a pass/fail value and learn more about why the read failed?
Here's more info:
Thanks for the help!
Hello Scott,
Can you show on the configuration about the ADC and the task , also the error ?
And you can refer to the adc sample under C:\Freescale\Freescale_MQX_4_1_1\mqx\examples (change 4.1 to 4.0, I use MQX4.1, ).
Hope it helps
Alice
Thanks for the reply, Alice.
I'm not sure exactly what the "error" is, as I'm having difficulty reading and interpreting the return value of the _io_read function. When the "error" occurs, my code enters the "else" branch and I see the message I have within.
This looks to be the relevant code from the adc_demo.c file:
/* channel 1 sample ready? */
if (read(f_ch1, &data, sizeof(data) ))
printf("ADC ch 1: %4d ", data.result);
else
printf(" ");
Looking at the comment line, if a sample cannot be read, it's because it is not "ready". Does this imply that there is not necessarily an error, just that it hasn't been acquired/processed yet? If so, then my interpretation of a "failed" read as an "error" is incorrect. Like I stated previously, this does not happen regularly or consistently on any one channel.
Is there a way to determine the reason why the sample isn't ready? What can I do to ensure that when requested, the sample will be ready?
Here are the configuration/initialization commands for my ADC:
#define ADC1 "adc1:" /* adc1 must be #1 as the inputs are wired to ADC 1 */
// ADC configuration parameters
#define ADC_HARDWARE_AVERAGING 16
#define NO_SAMPLE_IN_ONE_RUN 16 // number of samples in one run sequence (orig 32)
#define START_OFFSET 4400 // time offset from trigger point in us (orig 100); manually tweaked for improved accuracy
#define PERIOD 30000 // period in us (orig 30000)
#define SCALE_RANGE 0x10000 // scale range of result (not used now)
#define CIRCULAR_BUFFER_SIZE 16 // circular buffer size (sample count) (orig 32)
#define ADC_LONG_SAMPLE 2 // long sample time = 2 usec
#define ADC_REF_VREF 3300 // Vref = 3.3 volts
#define MY_TRIGGER ADC_PDB_TRIGGER // logical trigger ID that starts this ADC channel
// global variables
MQX_FILE_PTR f0, f1;
// ADC device initialization structure
const ADC_INIT_STRUCT adc_init = { ADC_RESOLUTION_DEFAULT, /* resolution */
};
//
// AI_MUX_DA and AI_MUX_DA read together
//
const ADC_INIT_CHANNEL_STRUCT ai_mux_da_param = { AI_MUX_DA, // physical ADC channel
ADC_CHANNEL_MEASURE_ONCE | ADC_CHANNEL_START_TRIGGERED,
NO_SAMPLE_IN_ONE_RUN,
START_OFFSET,
PERIOD,
SCALE_RANGE,
CIRCULAR_BUFFER_SIZE,
MY_TRIGGER
};
const ADC_INIT_CHANNEL_STRUCT ai_mux_db_param = { AI_MUX_DB, // physical ADC channel
ADC_CHANNEL_MEASURE_ONCE | ADC_CHANNEL_START_TRIGGERED,
NO_SAMPLE_IN_ONE_RUN,
START_OFFSET+100, // problems occur if both reads occur simultaneously
PERIOD,
SCALE_RANGE,
CIRCULAR_BUFFER_SIZE,
MY_TRIGGER
};
Within the main task loop, I'm opening the ADCs
_mqx_int error_code = MQX_OK;
f1 = _io_fopen(ADC1, (const char*) &adc_init);
if (f1 != NULL) {
// long sample time
error_code = _io_ioctl(f1, ADC_IOCTL_SET_LONG_SAMPLE, (pointer)ADC_LONG_SAMPLE);
// hardware averaging
error_code = _io_ioctl(f1, ADC_IOCTL_SET_HW_AVERAGING, (pointer)ADC_HARDWARE_AVERAGING);
// reference voltage; not sure how this is used
error_code = _io_ioctl(f1, ADC_IOCTL_SET_REFERENCE,(pointer)ADC_REF_VREF);
// acquisition speed (was previously HIGH speed
error_code = _io_ioctl(f1, ADC_IOCTL_SET_LOW_SPEED, NULL);
} else {
_task_block();
}
_time_delay(OPEN_DELAY);
Then opening the individual channels
ch_ai_mux_da = _io_fopen(ADC1 "MUX_DA", (const char*) &ai_mux_da_param);
if (ch_ai_mux_da != NULL) {
} else {
_io_printf("Failed to open MUX_DA\n");
_task_block();
}
ch_ai_mux_db = _io_fopen(ADC1 "MUX_DB", (const char*) &ai_mux_db_param);
if (ch_ai_mux_db != NULL) {
} else {
_io_printf("Failed to open MUX_DB\n");
_task_block();
}
Then triggering
_io_ioctl(f1, ADC_IOCTL_FIRE_TRIGGER, (pointer) MY_TRIGGER);
_time_delay(TRIGGER_TIME_DELAY);
Then reading (analogLimitCheck is my limit check routine, the BYPASS... statement is the one which started this discussion)
if (_io_read(ch_ai_mux_da, &data, sizeof(data))) {
analogLimitCheck(...);
} else {
_io_printf("BYPASS reading ch_ai_mux_da\n");
}
if (_io_read(ch_ai_mux_db, &data, sizeof(data))) {
analogLimitCheck(...);
} else {
_io_printf("BYPASS reading ch_ai_mux_da\n");
}
Then closing the channels
_io_fclose(ch_ai_mux_da);
_io_fclose(ch_ai_mux_db);
And closing the ADC
_io_fclose(f1);
_time_delay(CLOSE_DELAY);
========
Please let me know if I'm missing anything. I think I got it all.
Thanks!