iLLD_TC27xC  1.0
How to use the VADC ADC Interface driver?
Collaboration diagram for How to use the VADC ADC Interface driver?:

VADC comprises of independent analog channels with Analog/Digital converters to convert analog input to discrete digital output.

In the following sections it will be described, how to integrate the driver into the application framework.

Preparation

Include Files

Include following header file into your C code:

Variables

// VADC handle

Module Initialisation

The module initialisation can be done in the same function:

// create configuration
IfxVadc_Adc_initModuleConfig(&adcConfig, &MODULE_VADC);
// initialize module
// IfxVadc_Adc vadc; // declared globally
IfxVadc_Adc_initModule(&vadc, &adcConfig);

Group Initialisation

The group initialisation can be done in the same function:

// create group config
IfxVadc_Adc_GroupConfig adcGroupConfig;
IfxVadc_Adc_initGroupConfig(&adcGroupConfig, &vadc);
// change group (default is GroupId_0, change to GroupId_3)
adcGroupConfig.groupId = IfxVadc_GroupId_3;
// IMPORTANT: usually we use the same group as master!
adcGroupConfig.master = adcGroupConfig.groupId;
// enable all arbiter request sources
adcGroupConfig.arbiter.requestSlotQueueEnabled = TRUE; // enable Queue mode
adcGroupConfig.arbiter.requestSlotScanEnabled = TRUE; // enable Scan mode
adcGroupConfig.arbiter.requestSlotBackgroundScanEnabled = TRUE; // enable Background scan
// enable all gates in "always" mode (no edge detection)
// initialize the group
IfxVadc_Adc_initGroup(&adcGroup, &adcGroupConfig);

Queued Transfers

Now, VADC is initialised. Here,Three channels are used for queued transfers

// IMPORTANT: for deterministic results we have to disable the queue gate
// while filling the queue, otherwise results could be output in the wrong order
unsigned savedGate = adcGroup.module.vadc->G[adcGroup.groupId].QMR0.B.ENGT;
adcGroup.module.vadc->G[adcGroup.groupId].QMR0.B.ENGT = 0;
// create channel config
IfxVadc_Adc_ChannelConfig adcChannelConfig[3];
IfxVadc_Adc_Channel adcChannel[3];
for(int chnIx=0; chnIx<3; ++chnIx) {
IfxVadc_Adc_initChannelConfig(&adcChannelConfig[chnIx], &adcGroup);
adcChannelConfig[chnIx].channelId = (IfxVadc_ChannelId)(chnIx);
adcChannelConfig[chnIx].resultRegister = IfxVadc_ChannelResult_1; // use result register #1 for all channels
// initialize the channel
IfxVadc_Adc_initChannel(&adcChannel[chnIx], &adcChannelConfig[chnIx]);
// Add channel to queue with refill enabled
// restore previous gate config
adcGroup.module.vadc->G[adcGroup.groupId].QMR0.B.ENGT = savedGate;
// start the Queue
IfxVadc_Adc_startQueue(&adcGroup); // just for the case that somebody copy&pastes the code - the queue has already been started in previous test
// get 10 results for all 3 channels and store in temporary buffer
// (the usage of a buffer is required, since the print statements used by the checks take more time than the conversions)
Ifx_VADC_RES resultTrace[3*10];
for(int i=0; i<3*10; ++i)
{
unsigned chnIx = i % 3;
// wait for valid result
Ifx_VADC_RES conversionResult;
do {
conversionResult = IfxVadc_Adc_getResult(&adcChannel[chnIx]);
} while( !conversionResult.B.VF );
// store result
resultTrace[i] = conversionResult;
}
// stop the queue
// check results in buffer
// ...
}

Auto Scan

Autoscan of 5 channels

// now with group 0
adcGroupConfig.groupId = IfxVadc_GroupId_0;
adcGroupConfig.master = adcGroupConfig.groupId;
// initialize the group
//IfxVadc_Adc_Group adcGroup; // no need to create a new one
IfxVadc_Adc_initGroup(&adcGroup, &adcGroupConfig);
{
// create channel config
IfxVadc_Adc_ChannelConfig adcChannelConfig[5];
IfxVadc_Adc_Channel adcChannel[5];
for(int chnIx=0; chnIx<5; ++chnIx) {
IfxVadc_Adc_initChannelConfig(&adcChannelConfig[chnIx], &adcGroup);
adcChannelConfig[chnIx].channelId = (IfxVadc_ChannelId)(chnIx);
adcChannelConfig[chnIx].resultRegister = (IfxVadc_ChannelResult)(chnIx); // use dedicated result register
// initialize the channel
IfxVadc_Adc_initChannel(&adcChannel[chnIx], &adcChannelConfig[chnIx]);
// add to autoscan
unsigned channels = (1 << adcChannelConfig[chnIx].channelId);
unsigned mask = channels;
boolean continuous = TRUE;
IfxVadc_Adc_setScan(&adcGroup, channels, mask, continuous);
}
// start autoscan
// check results
for(int chnIx=0; chnIx<5; ++chnIx) {
unsigned group = adcChannel[chnIx].group->groupId;
unsigned channel = adcChannel[chnIx].channel;
// wait for valid result
Ifx_VADC_RES conversionResult;
do {
conversionResult = IfxVadc_Adc_getResult(&adcChannel[chnIx]);
} while( !conversionResult.B.VF );
// print result, check with expected value
{
unsigned expected = ((adcMaxPlus1Value * (VADC_COMMANDS_CHN_PER_VOLTAGE_GROUP*group + channel) * vStep) / (vRef-vGnd));
result |= clib_trace(conversionResult.B.CHNR, channel);
result |= clib_trace_tolerant(conversionResult.B.RESULT, expected, 5);
}
}
}

Background Scan

Background Scan of 2 channels

// create channel config
IfxVadc_Adc_ChannelConfig adcChannelConfig[2];
IfxVadc_Adc_Channel adcChannel[2];
for(int chnIx=0; chnIx<2; ++chnIx)
{
IfxVadc_Adc_initChannelConfig(&adcChannelConfig[chnIx], &adcGroup);
adcChannelConfig[chnIx].channelId = (IfxVadc_ChannelId)(chnIx + 5);
adcChannelConfig[chnIx].resultRegister = (IfxVadc_ChannelResult)(5 + chnIx); // use register #5 and 6 for results
adcChannelConfig[chnIx].backgroundChannel = TRUE;
// initialize the channel
IfxVadc_Adc_initChannel(&adcChannel[chnIx], &adcChannelConfig[chnIx]);
// add to background scan
unsigned channels = (1 << adcChannelConfig[chnIx].channelId);
unsigned mask = channels;
IfxVadc_Adc_setBackgroundScan(&vadc, &adcGroup, channels, mask);
}
// start autoscan
boolean continuous = TRUE;
IfxVadc_Adc_startBackgroundScan(&vadc, continuous);
// check results
for(int chnIx=0; chnIx<2; ++chnIx)
{
unsigned group = adcChannel[chnIx].group->groupId;
unsigned channel = adcChannel[chnIx].channel;
// wait for valid result
Ifx_VADC_RES conversionResult;
do
{
conversionResult = IfxVadc_Adc_getResult(&adcChannel[chnIx]);
} while( !conversionResult.B.VF );
// check with expected value
// ...
}