Configuring 60 ADC in aurix tc399 series

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User20162
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted
Hi,
i am trying to configure 50 to 60 ADC in aurix TC399 series. for that i have few doubts regarding configuration. in datasheet and user manual mentioned 3 queues for primary and secondary channels which is
8 stages for primary and 16 stages for secondary. my questions are

1. does aurix has total 3 queues for all the ADC or 3 queues for primary and 3 queues for secondary seperately? if yes, we have 24 stages and 48 stages for primary and secondary. is that correct?
2. for queuing i have understood that 8th stage configuration is lowest priority and 1st stage is highest priority to start conversion? is my understand correct?
3. How do i enable the group conversion done interrupt or specific channel interrupt? i havent see any demo code for that. kindly help me sort this out?


Thanks
Mohamed Rahmathulla
0 Likes
9 Replies
MoD
Employee
Employee
50 likes received 500 replies posted 100 solutions authored
The ADC of TC399 has 8 primary groups and 4 secondary groups. Each group can be used independent and has 3 queues. Each primary group has 8 stages queues, each secondary group 16 stages queues.
The priority of each queue can be defined individually by SW.
Unfortunately I don't have a demo code for using the ADC interrupts.
0 Likes
User20162
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted
Hi MoD,
Thank you for your quick response.

I going to try 3 primary group queue and 3 secondary group queue at the same time.

Moreover i didnt see any background scan and auto scan request in the ADC. Does this missing in TC399?

The only example i got from iLLD is evadc queue demo code. Is queue the only source to read ADC value?

Thanks & Regards
Mohamed Rahmathulla
0 Likes
User20162
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted
Hi MoD,
Thank you for your quick response.

I going to try 3 primary group queue and 3 secondary group queue at the same time.

Moreover i didnt see any background scan and auto scan request in the ADC. Does this missing in TC399?

The only example i got from iLLD is evadc queue demo code. Is queue the only source to read ADC value?

Thanks & Regards
Mohamed Rahmathulla
0 Likes
MoD
Employee
Employee
50 likes received 500 replies posted 100 solutions authored
Which groups you will use is dependent of the used analog inputs, e.g. group 0 can handle only AN0-AN7 (see UM appendix for TC39x). Note that all 12 groups can be used at the same time.
In older devices there are fixed sources used, e.g. auto scan with a fixed order of the conversions. This source is replaced by a queue with the same feature but more flexible (e.g. you can define the order of conversions, no longer fixed order for auto scan).
The available iLLD demo set 1 of the 3 queues in "auto scan" mode.
0 Likes
User20162
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted
Hi MoD,
I tried to configure group 0 and group 8 at the same time in same queue 0. But the CPU stopped in CPU_TRAP_DEBUG..
I gone through the user manual, they mentioned like you said auto scan automatically happen once we configured queue..
But i need to scan 60 channel.. but from my analysis we wont able to do in queue all the channel.. could you please help me how to configure
All 60 channel at once and start scan accordingly..

Note: for queuing i am reconfigure and shifting primary to secondary everytime to access the queue.. kindly let me know if any other peocess it has..
Thanks in advance.
0 Likes
MoD
Employee
Employee
50 likes received 500 replies posted 100 solutions authored
I don't know why you get a trap, maybe there is anything not correct initialized. Please note that queue 0 of group 0 is independent on queue 0 of group 8. They are not using the same queue.
When you will make an auto scan over 60 channels then you must define which 60 channels.
Example AutoScan AN0...AN31:
Configure group 0 up to group 3
Configure on each group all 8 channels in 1 queue with REFILL
Start the queues
Now you have an auto scan on each group.
Because you have 4 groups in parallel your auto scan is faster. During the time of 32 auto scan conversions on older device you make now 4*32 conversions.
0 Likes
User20162
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted
thank you MoD, now i can able to configure seperately. configuring primary and secodary at the same time and its worked. now i am trying with channel interrupt. does aurix has any interrupt for
group conversion?

here is my configuration

group 0 - channel 0 - 7 - queue 0
group 1 - channel 0 - 7 - queue 1
group 2 - channel 0 - 7 - queue 2
group 8 - channel 0 - 15 - queue 0

i can able to read the data from queue 0 for both primary and secondary.

as per my understanding i am configuring channel 15 in group 8 at last, so that is lowest priority which conversion will take once every other channel get completed. i am configuring interrupt
for channel 15 in group 8 then i came to know every conversation is finished. but how do i enable the interupt? and let me know if my understanding is wrong regarding the priority scanning.

Thanks in advance
mohamed rahmathulla
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
I'd reserve the word "priority" for conflicts between the three queues: see 32.6 Request Source Arbitration in the User Manual.

The queued sources are just that: first channel number entered in each queue is converted first, and the remaining entries in the queue are serviced first-in-first-out. Each group is independent, unless you have synchronized conversions enabled.

There are many ways to generate a EVADC service request. Here are a couple approaches:

- Feed EVADC through a single result register into DMA:
-- Configure GxCHCTRy.RESREG to map all conversions to the same result register (GxRESy)
-- Enable service request generation for GxRESy by setting GxREVNP0.REVyNP
--- For example, to generate a service request for SRC_VADCG3SR2 for G3RES4, set G3REVNP0.REV4NP=2)
--- In the interrupt router, configure SRC_VADCG3SR2 to enable the interrupt and configure the handler (DMA)
-- When debugging, make sure you're looking at GxRESDy instead of GxRESy directly. If service requests are enabled, each time the debugger updates GxRESy, it will "steal" an update away from the CPU or from DMA.
-- For an 8-entry queue, DMA would do a single transaction of 8 moves, and then cause a CPU interrupt when the transaction completed

- Alternately, you could map each channel into a separate result register, and just cause an interrupt on the channel number that is the last entry in the queue
-- For example: say the group 2 queue had channels 0, 1, 2, 5, 7
--- G2CHCTR0.RESREG =0, G2CHCTR1.RESREG=1, G2CHCTR2.RESREG=2, G2CHCTR5.RESREG=5, G2CHCTR7.RESREG=7
--- G2REVNP0.REV7NP=0
--- In the interrupt router, enable SRC_VADCG0SR0 and map it to a CPU interrupt
0 Likes
User20162
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted

#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include
#include

IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;

#define Adc_Isr_Priority 0x10


typedef struct
{
IfxEvadc_Adc evadc;
IfxEvadc_Adc_Group adcGroup;
}App_EvadcQueueTransfer;

App_EvadcQueueTransfer g_EvadcQueueTransfer;

volatile uint8 flag = 0;

IFX_INTERRUPT(AdcIntHandler, 0, Adc_Isr_Priority);





void AdcIntHandler(void)
{
uint8 ucIntState;
ucIntState=IfxCpu_disableInterrupts();
if(ucIntState == 0){}
flag = 1;
IfxEvadc_clearChannelRequest(g_EvadcQueueTransfer.adcGroup.group,(IfxEvadc_ChannelId)IfxEvadc_ChannelId_7);
IfxCpu_enableInterrupts();
}


void core0_main(void)
{
IfxCpu_enableInterrupts();


IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());


IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
EvadcQueueTransferDemo_init();
EvadcQueueTransferDemo_run();

while(1)
{
if(flag == 1)
{
flag =0;
EvadcQueueTransferDemo_run();
IfxCpu_enableInterrupts();
}


}
}


void EvadcQueueTransferDemo_init(void)
{
IfxEvadc_Adc_Config adcConfig;
IfxEvadc_Adc_initModuleConfig(&adcConfig, &MODULE_EVADC);

IfxEvadc_Adc_initModule(&g_EvadcQueueTransfer.evadc, &adcConfig);

IfxEvadc_Adc_GroupConfig adcGroupConfig;
IfxEvadc_Adc_initGroupConfig(&adcGroupConfig, &g_EvadcQueueTransfer.evadc);

adcGroupConfig.groupId = IfxEvadc_GroupId_0;
adcGroupConfig.master = adcGroupConfig.groupId;

adcGroupConfig.arbiter.requestSlotQueue0Enabled = TRUE; // enable Queue0 mode
adcGroupConfig.arbiter.requestSlotQueue1Enabled = TRUE; // enable Queue1 mode
adcGroupConfig.arbiter.requestSlotQueue2Enabled = TRUE; // enable Queue2 mode


adcGroupConfig.queueRequest[0].triggerConfig.gatingMode = IfxEvadc_GatingMode_always;
adcGroupConfig.queueRequest[1].triggerConfig.gatingMode = IfxEvadc_GatingMode_always;
adcGroupConfig.queueRequest[2].triggerConfig.gatingMode = IfxEvadc_GatingMode_always;


IfxEvadc_Adc_initGroup(&g_EvadcQueueTransfer.adcGroup, &adcGroupConfig);
}

void EvadcQueueTransferDemo_run(void)
{


{
uint32 chnIx;
static uint8 Configured = 0;

IfxEvadc_Adc_ChannelConfig adcChannelConfig[9];
IfxEvadc_Adc_Channel adcChannel[9];

if(Configured == 0)
{
IfxEvadc_RequestSource requestSource = IfxEvadc_RequestSource_queue0;
IfxEvadc_GatingMode savedGate = IfxEvadc_getQueueSlotGatingMode(g_EvadcQueueTransfer.adcGroup.group,requestSource);
IfxEvadc_GatingSource gatingSource = IfxEvadc_getQueueSlotGatingSource(g_EvadcQueueTransfer.adcGroup.group, requestSource );



for (chnIx = 0; chnIx < 8 ; ++chnIx)
{
IfxEvadc_Adc_initChannelConfig(&adcChannelConfig[chnIx], &g_EvadcQueueTransfer.adcGroup);
if(chnIx == 7)
{
adcChannelConfig[chnIx].channelPriority = Adc_Isr_Priority;
adcChannelConfig[chnIx].limitCheck = IfxEvadc_LimitCheck_always;
}

adcChannelConfig[chnIx].channelId = (IfxEvadc_ChannelId)(chnIx);
adcChannelConfig[chnIx].resultRegister = (IfxEvadc_ChannelId)(chnIx);


IfxEvadc_Adc_initChannel(&adcChannel[chnIx], &adcChannelConfig[chnIx]);


IfxEvadc_Adc_addToQueue(&adcChannel[chnIx], requestSource,IFXEVADC_QUEUE_REFILL);
}


IfxEvadc_setQueueSlotGatingConfig(g_EvadcQueueTransfer.adcGroup.group, gatingSource, savedGate, requestSource );


IfxEvadc_Adc_startQueue(&g_EvadcQueueTransfer.adcGroup,requestSource);
Configured = 1;
}

else
{


Ifx_EVADC_G_RES resultTrace[9];

uint32 i;

for (i = 0; i < 8 ; ++i)
{
unsigned chnIx = i % 8;


Ifx_EVADC_G_RES conversionResult;

do
{
conversionResult = IfxEvadc_Adc_getResult(&adcChannel[chnIx]);
} while (!conversionResult.B.VF);

/* store result */
resultTrace = conversionResult;
}

/* stop the queue */
// IfxEvadc_Adc_clearQueue(&g_EvadcQueueTransfer.adcGroup,requestSource);


Configured = 0;
}
}
#endif
}



The above code stuck into the ISR.. how to sort this out


thanks and regards
mohamed rahmathulla
0 Likes