Hi,
everything does not need to correspond to the hw registers . You are using operating system.
You can use adc without mqx, just set BSPCFG_ENABLE_ADCx to 0. You avoid using posix adc driver but you have to write your own code to use ADC.
The source code of the ADC depends on the board, therefore you should check also kadc folder in io/adc/. There are defined structures.
Regards,
MartinK
Just wanted to point out that in MQX v4.0, the LWADC driver was updated to support Kinetis, and this driver allows more than 2 channels per ADC. Please see the post below for more details.
Hi georgiad,
the problem is not in MQX but hardware related. Because K60 got only two status registers (ADCx_SC1A or SC1B).
Therefore more than 2 channels on one adc module are not possible.
Best regards,
MartinK
Thanks MartinK for your reply, but in this case how can I scan more than 2 adc inputs?
If for example I need to scan AD11,AD12 and AD13, how do I do this? I've already done it,
without MQX but I cannot figure out how to do it using BSP. In each adc_channel_param you
can set only one source and you can use only two such structures.
You could open channel, measure,close channel, always with different structure. 3 structures in your case and close/open channel on adc module.
You should be able to measure more than 2 channels, but not at the same time.
Regards,
MartinK
Hi,
I solved the problem by using Processor Expert ADC-component.
It creates the channel count into adc1.h:
#define AD1_CHANNEL_COUNT 6u
How to use:
result table:
uint_16 AD1_ResultTable[AD1_CHANNEL_COUNT];
Init:
AD1_DevicePtr = AD1_Init(A1_UserDataPtr);
Start measurement:
AD1_measIndex = 0;
ad1error = AD1_SelectSampleGroup(AD1_DevicePtr, AD1_measIndex);
AD1_StartSingleMeasurement(AD1_DevicePtr);
Channel increment and starting the measurement:
void AD1_OnMeasurementComplete(LDD_TUserData *UserDataPtr)
{
/* Write your code here ... */
if (AD1_measIndex < AD1_CHANNEL_COUNT)
{
AD1_GetMeasuredValues(AD1_DevicePtr, &AD1_ResultTable[AD1_measIndex]);
if (++AD1_measIndex < AD1_CHANNEL_COUNT)
{
AD1_SelectSampleGroup(AD1_DevicePtr, AD1_measIndex);
AD1_StartSingleMeasurement(AD1_DevicePtr);
}
}
}
~Mark
Thanks both for the replies. Thanks Mark for the code snippet, but after some time spent to make PE work with MQX and a
lot of problems I decided to stop using PE. It is a nice fancy tool but not for complicated projects. I am trying now BSP, although
I have many problems and I suppose the main cause of them is that all these upper layers are black boxes for the user.
I tried to open and close the analog channel using every time a different structure but nothing.
Here is a simple 1 channel project that again cannot initialize f_ch1 which always return 0.
#include <mqx.h>
#include <bsp.h>
#define MY_ADC "adc1:" /* must be #1 as the inputs are wired to ADC 1 */
#define MY_TRIGGER ADC_PDB_TRIGGER
/* Task IDs */
#define ADC_TASK 6
/* Function prototypes */
extern void main_task(uint_32);
void adc_task(uint_32);
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task Index, Function, Stack, Priority, Name, Attributes, Param, Time Slice */
{ADC_TASK, adc_task, 1000, 7, "Adc", MQX_AUTO_START_TASK, 0, 0 },
{0}
};
/* ADC device init struct */
const ADC_INIT_STRUCT adc_init = {
ADC_RESOLUTION_DEFAULT, /* resolution */
};
/* Logical channel #1 init struct */
const ADC_INIT_CHANNEL_STRUCT adc_channel_param1 =
{
ADC1_SOURCE_AD12, /* physical ADC channel */
ADC_CHANNEL_MEASURE_LOOP | ADC_CHANNEL_START_NOW, /* runs continuously after IOCTL trigger */
10, /* number of samples in one run sequence */
0, /* time offset from trigger point in us */
10000, /* period in us (= 0.3 sec) */
0x10000, /* scale range of result (not used now) */
10, /* circular buffer size (sample count) */
MY_TRIGGER, /* logical trigger ID that starts this ADC channel */
};
void adc_task
(
uint_32 initial_data
)
{
ADC_RESULT_STRUCT data;
MQX_FILE_PTR f, f_ch1;
printf("\n\n-------------- Begin ADC example --------------\n\n");
printf("Opening ADC device ...");
f = fopen(MY_ADC, (const char*)&adc_init);
if(f != NULL)
{
printf("done\n");
}
else
{
printf("failed\n");
_task_block();
}
while(1){
f_ch1 = fopen(MY_ADC "gyrox", (const char*)&adc_channel_param1);
read(f_ch1, &data, sizeof(data));
printf("GYROX: %4d\n\r ", data.result);
fclose(f_ch1);
}
}
/* EOF */
THANKS
Hi,
you got problem with timing, it does not have enough time to open channel after you close it. Check structure times, period and number of samples and also try to add _time_delay after you open that channel.
You could see it ,it does not have enough time because first time you run the program and open the channel you get proper result,after that it does return always null.
Regards,
MartinK
Thanks MartinK for your reply. I found the source code of the adc BSP driver in \...\mqx\source\io\adc.
But I have the same problem. For example in the adc_channel_param there is the " time offset from trigger point in us",
which actually doesn't correspond to any HW register. How and where is defined circular buffer. In the HW there is
only ADCx_Rn registers to hold data e.t.c.
My question is if it is possible and how, to use MQX without BSP.
Thanks
I couldn'd find the way to send you a PM.
Hi,
everything does not need to correspond to the hw registers . You are using operating system.
You can use adc without mqx, just set BSPCFG_ENABLE_ADCx to 0. You avoid using posix adc driver but you have to write your own code to use ADC.
The source code of the ADC depends on the board, therefore you should check also kadc folder in io/adc/. There are defined structures.
Regards,
MartinK