Operating more than 1 channel per ADC

cancel
Showing results for 
Search instead for 
Did you mean: 

Operating more than 1 channel per ADC

1,686 Views
myke_predko
Senior Contributor III

Hi Folks,

 

In my application (developed in CW 10.4 and using MQX 4.0.1) I want to access more than one ADC on a channel (I will be using 7 between ADC0 and ADC1) in the K20 (using the TWRK20D72M as the development too while waiting for the PCBs). 

 

I am trying to to implement multiple channel reads for a single ADC in a single task and using them to trigger an lwevent.  I can do it successfully with a single channel per ADC in a task but not with multiple channels per ADC in a task. 

 

What I'm trying to do is:

  1. Create the lwevent for the ADC
  2. Open the ADC device
  3. Open a channel in the ADC that references the lwevent I created.  Opening the channel does not return an error and the task works with the different triggers as step 5 with the results listed below:
    1. "ioctl(f, ADC_IOCTL_FIRE_TRIGGER, (pointer)ADC_PDB_TRIGGER);" Works
    2. "ioctl(f, ADC_IOCTL_FIRE_TRIGGER, (pointer)ADC_TRIGGER_1);" ERROR WHEN ATTEMPTED TO EXECUTE/TASK BLOCKED AT THIS POINT
    3. "ioctl(f, ADC_IOCTL_RUN_CHANNEL, (pointer)ADC_PDB_TRIGGER);" Works
    4. "ioctl(f, ADC_IOCTL_RUN_CHANNEL, (pointer)ADC_TRIGGER_1);" Works
    5. "ioctl(f, ADC_IOCTL_RUN_CHANNELS, (pointer)ADC_PDB_TRIGGER);" Works
    6. "ioctl(f, ADC_IOCTL_RUN_CHANNELS,(pointer)ADC_TRIGGER_1);" ERROR WHEN ATTEMPTED TO EXECUTE/TASK BLOCKED AT THIS POINT
  4. Optionally open a second channel in the ADC that references the lwevent I created (with a different trigger).  Opening the channel does not return an error but the lwevent is not returned for any of the following triggers:
    1. "ioctl(f, ADC_IOCTL_FIRE_TRIGGER, (pointer)ADC_PDB_TRIGGER);" No Error for this ioctl but "_lwenvent_wait_ticks" never returns
    2. "ioctl(f, ADC_IOCTL_FIRE_TRIGGER, (pointer)(ADC_TRIGGER_1 | ADC_TRIGGER2));" ERROR WHEN ATTEMPTED TO EXECUTE/TASK BLOCKED AT THIS POINT
    3. "ioctl(f, ADC_IOCTL_RUN_CHANNEL, (pointer)ADC_PDB_TRIGGER);" No Error for this ioctl but "_lwenvent_wait_ticks" never returns
    4. "ioctl(f, ADC_IOCTL_RUN_CHANNEL, (pointer)(ADC_TRIGGER_1 | ADC_TRIGGER2));" No Error for this ioctl but "_lwenvent_wait_ticks" never returns
    5. "ioctl(f, ADC_IOCTL_RUN_CHANNELS, (pointer)ADC_PDB_TRIGGER);" No Error for this ioctl but "_lwenvent_wait_ticks" never returns
    6. "ioctl(f, ADC_IOCTL_RUN_CHANNELS, (pointer)(ADC_TRIGGER_1 | ADC_TRIGGER2));" No Error for this ioctl but "_lwenvent_wait_ticks" never returns
  5. Trigger the ADC using the ioctl commands listed above in steps 3 & 4.
  6. Execute an infinite loop while waiting on the lwevent - which never returns for the case where I open both channels.  The statements used (for both channels) is:
    1. "_lwevent_wait_ticks(&evn1, ADC_TRIGGER_1 | ADC_TRIGGER_2, FALSE, 0);"

 

I have looked through the MQX forum here and while I have found people with similar problems and some sample solutions, but I haven't found one that is right for my application.  I guess the worst-case solution is to close a channel after reading it and then opening another on the ADC, but I would think that I should be able to get multiple ADC channels operating in a task - correct? 

 

I have attached the code that I am using - maybe somebody has an idea why I am having this problem. 

 

Finally, what is the limit to the number of channels that can be opened for an ADC simultaneously?  When I looked through the forums it look like it is limited by ADC_MAX_CHANNELS, but when I tried to change this define in the bsp, the rebuild fails.  Any comments? 

 

Thanx,

 

myke

Original Attachment has been moved to: adc_task.h.zip

Original Attachment has been moved to: adc_task.c.zip

6 Replies

478 Views
c0170
Senior Contributor III

Hello Myke Predko,

ADC_MAX_CHANNELS is set on KINETIS to 2 because there are usually 2 ADC status registers (each status has own data register), which means only 2 channels can be run simultaneously.

PDB trigger's limitation is one per module, as I remember.

I have not tested lwadc, this is just a suggestion, that there's option to use lwadc but porting is required for K20. It's only for K21 board at the moment. The last time I checked, I had an impression it should be trivial to port it to another kinetis. Check this thread :

A/D Driver Unable to Open Channel

I have opened your code, but there's too many preprocessor compiled statements plus commented code. Could you somehow consolidate it so it's easier to find out what your code does and why it fails.

Regards,

c0170

0 Kudos

479 Views
myke_predko
Senior Contributor III

Hi Martin,

I got lwadc working under MQX 4.0.1 for the K20 - I would not consider the effort required to do this as "trivial".  It took me an honest three days with the need to reload MQX twice. 

The files that need to be copied from the K21 bsp to another Kinetis bsp are:

init_lwadc.c (this will also have to be modified after being copied over)

lwadc_kadc_prv.h

lwadc_kadc.c

lwadc_kadc.h (this will also have to be modified after being copied over)

lwadc_k20.c (this will also have to be modified after being copied over)

lwadc.h

And the following bsp files will have to be modified:

user_config.h

twrk20d72m.h (for the Tower System that I am working with)

bsp_prv.h

bsp.h

init_bsp.h

adc_mk20,h

.cproject

.project

Normally, I would publish the steps I used to get to this point, but there is a good chance that somebody following them will trash the bsp and have to reload it.  I'm not sure how to document the steps so that somebody would have a good chance at success, especially for different devices/boards (I have only done it for the TWRK20D72M). 

Despite the work, the lwadc does work very well and handles multiple channels as well as ADCs quite well.  The only comment that I would make that if you are reading channels across multiple ADCs you should put in a few ms delay between reads (this actually isn't a problem for my application) - if you are reading different channels in the same ADC, then you won't have any problems. 

Any comments, or is there a utility for adding a driver like this easily that I'm not aware of?  Are there any plans to include lwadc for Kinetis in future versions of MQX? 

Thanx,

myke

0 Kudos

479 Views
c0170
Senior Contributor III

Hello Myke,

I am glad to read you have ported it to K20 :smileywink: You know my statement that it seems to be trivial was made after reading few lines of code of lwadc and I had also ported a driver to MQX.  Can you share why did you have to reload MQX twice? Was it less time consuming than changing posix old adc driver?

LWADC should be ported to all kinetis boards in future version of MQX.

Regards,

c0170

0 Kudos

479 Views
myke_predko
Senior Contributor III

Hi Martin,

I had to reload MQX because of the necessity to update .project and .cproject correctly to pull in the new lwadc source files during the build.  If they got messed up I found it was easier to reload MQX than to try and restore them. 

The problem was bringing in the lwadc files from the TWRK21D50M bsp build in a way that they would be recognized during the build.  The way I finally got it to work was:

a) Copy the lwadc files into source files in C:\Freescale\Freescale_MQX_4_0\mqx\source\io

b) Drag and drop the lwadc files from C:\Freescale\Freescale_MQX_4_0\mqx\source\io into the twrk20d72m BSP project in CW.  I would have thought that by doing this, .cproject and .project for the bsp would be automatically, but they weren't so:

c) I had to update .cproject and .project

If there is an easy way to do this, please explain the process. 

That's good that lwadc will be in future versions of MQX - it really is a lot better than the current ADC driver.

Regards,

myke

0 Kudos

479 Views
myke_predko
Senior Contributor III

Hi Martin,

Sorry, I left in the old ADC driver in place - I suspect that even if I overwrote it, I would still have had the same problems as I did loading lwadc as its own separate resource.

myke

0 Kudos

479 Views
myke_predko
Senior Contributor III

Hi Martin,

Thank you for the reply - I'll look at the lwadc.

Attached is my code with the ability to specify how the ADC is configured taken out.

myke

0 Kudos