ADC Blocking

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ADC Blocking

Jump to solution
2,630 Views
CarlFST60L
Senior Contributor II

Hi,

 

I have several ADC inputs configured like this:

 

const ADC_INIT_CHANNEL_STRUCT adc_channel_param1 =
{
    Zone1_ADC_Input, // physical ADC channel
    ADC_CHANNEL_MEASURE_LOOP | ADC_CHANNEL_START_TRIGGERED, // runs continuously after IOCTL trigger
    4,              // number of samples in one run sequence
    0,              // time offset from trigger point in us
    200000,         // period in us = 150mS
    0x10000,        // scale range of result (not used now)
    4,             // circular buffer size (sample count)
    ADC_TRIGGER_1,  // logical trigger ID that starts this ADC channel
};

 

The above period is set to 150mS, but it doesnt block.

 

How should I use the ADC to run 4 samples over 150mS and block to the processor can do its other various tasks while it waits?

 

0 Kudos
1 Solution
822 Views
CarlFST60L
Senior Contributor II

Seems to be working as above for me now, though I did remove the other 12 tasks. I think maybe I had a higher priorty task taking up to much processing power or something.

 

I will look into it.

View solution in original post

0 Kudos
8 Replies
822 Views
CarlFST60L
Senior Contributor II
The answer I believe it to use LWEVENT_STRUCT_PTR complete_event in adc_init_channel_struct
0 Kudos
822 Views
CarlFST60L
Senior Contributor II

I have written some code to run a blocking ADC task, however, it never blocks.

 

The code only needs to run every 150mS, and the ADC should take 4 samples over the 150mS. The task must also be blocked for the entire 150mS.

 

The actual ADC works without the lwevent i.e. I can read the ADC and get the expect results, I just cannot get it to block when I add the lwevent code.

 

 

#ifndef MQX_USE_LWEVENTS
#error This application requires LWEVENTS in config.h to be set
#endif

//I have 4 of these, one for each ADC (X = 1 to 4)const ADC_INIT_CHANNEL_STRUCT adc_channel_paramX = {    ADC_SOURCE_AN1, // physical ADC channel     ADC_CHANNEL_MEASURE_LOOP | ADC_CHANNEL_START_TRIGGERED, // runs continuously after IOCTL trigger     4,              // number of samples in one run sequence     0,              // time offset from trigger point in us     37500,          // period in us = 150mS (4 / 150mS = 375000, so it actually samples 4 times at 37.5mS)    0x10000,        // scale range of result (not used now)     4,              // circular buffer size (sample count)     ADC_TRIGGER_1,  // logical trigger ID that starts this ADC channel     &LWE_ADC1};//I have four lwevents defined, not sure if I can use one as I cannot choose which flags each ADC gets setstatic LWEVENT_STRUCT LWE_ADC1;static LWEVENT_STRUCT LWE_ADC2;static LWEVENT_STRUCT LWE_ADC3;static LWEVENT_STRUCT LWE_ADC4;void ADC_Task(uint_32){    FILE_PTR  f, z1, z2, z3, z4;    ADC_RESULT_STRUCT data;         if ((_lwevent_create(&LWE_ADC1, LWEVENT_AUTO_CLEAR) != MQX_OK) ||     (_lwevent_create(&LWE_ADC2, LWEVENT_AUTO_CLEAR) != MQX_OK) ||     (_lwevent_create(&LWE_ADC3, LWEVENT_AUTO_CLEAR) != MQX_OK) ||     (_lwevent_create(&LWE_ADC4, LWEVENT_AUTO_CLEAR) != MQX_OK))    {     printf("lwevent_creat failed!\n");        _task_block();    }        z1 = fopen("adc:1", (const char*)&adc_channel_param1);    z2 = fopen("adc:2", (const char*)&adc_channel_param2);    z3 = fopen("adc:3", (const char*)&adc_channel_param3);    z4 = fopen("adc:4", (const char*)&adc_channel_param4);    //Doesnt start unless I do this for some reason    ioctl(f, IOCTL_ADC_FIRE_TRIGGER, (pointer) ADC_TRIGGER_1);    ioctl(f, IOCTL_ADC_FIRE_TRIGGER, (pointer) ADC_TRIGGER_2);    ioctl(f, IOCTL_ADC_FIRE_TRIGGER, (pointer) ADC_TRIGGER_3);    ioctl(f, IOCTL_ADC_FIRE_TRIGGER, (pointer) ADC_TRIGGER_4);        for(;;)    {        if (_lwevent_wait_ticks(&LWE_ADC1, 0x01, TRUE, 0) == MQX_OK) {            if(read(z1, &data, sizeof(data) ))            {                //run my code to check the data            }        }        if (_lwevent_wait_ticks(&LWE_ADC2, 0x01, TRUE, 0) == MQX_OK) {            if(read(z2, &data, sizeof(data) ))            {                //run my code to check the data            }        }        if (_lwevent_wait_ticks(&LWE_ADC3, 0x01, TRUE, 0) == MQX_OK) {            if(read(z3, &data, sizeof(data) ))            {                //run my code to check the data            }        }        if (_lwevent_wait_ticks(&LWE_ADC4, 0x01, TRUE, 0) == MQX_OK) {            if(read(z4, &data, sizeof(data) ))            {                //run my code to check the data            }        }    }}

 

 I am also not sure exactly how the ADC will handle having four lwevents all triggered one afte the other.

 

I have another task running at a lower priority, and it never runs as this task never blocks.

 

Thanks in advance.

 

PS: I have not really used lwevents before, so its probably something obvious?!

 

 

 

 

 

 

 

 

 

0 Kudos
822 Views
JuroV
NXP Employee
NXP Employee

Hi Carl,

 

your code is fine, there is no mistake.  It should work. I have no report about events not working in ADC. Which version of MQX do you use?

0 Kudos
822 Views
CarlFST60L
Senior Contributor II

Thanks for checking that JuroV, I am using 3.4.

 

I thought it should be a simple task, but several hours of trying various things I came up with no solution.

 

 

0 Kudos
822 Views
JuroV
NXP Employee
NXP Employee
You are using mcf52259, right? Can you pass the whole code? Thanks.
0 Kudos
823 Views
CarlFST60L
Senior Contributor II

Seems to be working as above for me now, though I did remove the other 12 tasks. I think maybe I had a higher priorty task taking up to much processing power or something.

 

I will look into it.

0 Kudos
822 Views
CarlFST60L
Senior Contributor II

Hi,

 

I have been using the above code for testing. I have a simple voltage divider on the input wiht a 100nF cap for filtering. There are also a dozen other busy tasks running.

 

At completely random intervals (usually within 24 hours), I will get a case where the first ADC read shows the correct value, and the other 3 show the wrong value (I think they must go down to 0, or close too. I will log this over then next 24 hour period).

 

As the first event always returns the correct value and the following three all show the wrong value at the time of the error, I wonder if there is a problem with _lwevent_wait_ticks? The loop basically blocks until the first ADC event happens, then goes and checks all the lwevents, could this cause a problem? I there a 'better' way to do the above code?

0 Kudos
822 Views
CarlFST60L
Senior Contributor II

I managed to capture the ADC returning the wrong values by putting a printf in each read, then loging the fread's for just over 10 hours, here is the section with he error:

 

0123456:  992  998 1001  998  846 1267

0123456:  993  996 1000 1000  830 1267

0123456:  993  998 1001  997  847 1267
0123456:  993    3 6696 8192    0    0
0123456:  993  997  999  999  837 1256
0123456:  993  995  999  999  835 1258
0123456:  992  997 1003  998  852 1260
0123456:  994  997 1003  999  842 1265
0123456:  993  996 1000  997  847 1266
I am 99% sure there is a problem with MQX when using the configuration above. For some reason the first fread has never been a problem. Any idea's? 
Also, I captured the event on a 500Mhz 4M DSO and the voltage on the inputs and VCC pins are rock solid with no hint of movement or noise of any kind.

 

0 Kudos