ADC arbiter stop working sporadically

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

cross mob
Not applicable
We are using the XMC4500 as a motor controller (not Dave generated). A CCU8 pwm is used to trigger an ADC conversion. All can work fine for days/weeks but suddenly the ADC arbiter stops working.

The reason for the arbiter stops working is a very small change in any c file. The changed file does not need to have any relation to the ADC or CCU8. Most of the time it is just adding a single variable. A clean/rebuild does not solve the problem. Remove the variable and the problem disappears, adding it again and it returns. Adding more variables may/may not remove the problem.

When the problem occures the pwm starts an ADC conversion 1-8 times but then it just stops working. The pwm is still running but it does not cause an ADC conversion. The ARBCFG register indicates the arbiter is running normally BUT it never indicates busy. If you restart the arbiter by stopping the arbiter and starting it again (without changing anything else) the arbiter starts again and can function for another 1-8 ADC conversions and then it stops again. Change the code just slightly and the arbiter never stops.

This is a major problem. We have read the application notes for both ADC and CCU8 without finding any clues. My only idea is that there is some kind of timing/clock domain synchronization problem but this problem must be solved before any products can be delivered to any customer!!

We have done some more tests and found other interesting settings that effect the behaviour:

We are currently using 4 arbitration slots. This is recommended in the manual for the XMC4500. The system clock is 120MHz and the clock for the ADC kernel is configured to 30MHz (DIVA = 3).
The arbiter is running with full system clock (120MHz, DIVD = 0) when the above mentioned problem occur. If we decrease the frequency for the arbiter the problem disappears. With the value 2 or 3 written to the DIVD bit-field the interrupt is running and the problem seems to be solved. DIVD set to 0 or 1 does not work.

What is the maximum allowed frequency for the arbiter clock? In this case, with synchronous sampling of the ADC:s, what value of the DIVD bit-field is recommended to get a fixed (minimal) reaction time?
0 Likes
33 Replies
Not applicable
Hello,

i have a very similar problem with the ADC on a XE167-96F66L
The ADCs are synchronized and triggered via Period Match of CCU6 - T13
The synchronisation works partly - when i change something in the sourcecode which has no relation to the ADC, i only get the result of the Master-ADC. When i read out the Slave, the result is always 0.
Timing of both ADC Modules is the same - F_ADCI = f_ADC/4 (15MHz), f_ADCD = f_ADC (60MHz), INPCR0.STC = 0;

I would be pleased about any advices

Thanks,
Markus
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
jef wrote:
We are using the XMC4500 as a motor controller (not Dave generated). A CCU8 pwm is used to trigger an ADC conversion. All can work fine for days/weeks but suddenly the ADC arbiter stops working.

The reason for the arbiter stops working is a very small change in any c file. The changed file does not need to have any relation to the ADC or CCU8. Most of the time it is just adding a single variable. A clean/rebuild does not solve the problem. Remove the variable and the problem disappears, adding it again and it returns. Adding more variables may/may not remove the problem.

When the problem occures the pwm starts an ADC conversion 1-8 times but then it just stops working. The pwm is still running but it does not cause an ADC conversion. The ARBCFG register indicates the arbiter is running normally BUT it never indicates busy. If you restart the arbiter by stopping the arbiter and starting it again (without changing anything else) the arbiter starts again and can function for another 1-8 ADC conversions and then it stops again. Change the code just slightly and the arbiter never stops.

This is a major problem. We have read the application notes for both ADC and CCU8 without finding any clues. My only idea is that there is some kind of timing/clock domain synchronization problem but this problem must be solved before any products can be delivered to any customer!!

We have done some more tests and found other interesting settings that effect the behaviour:

We are currently using 4 arbitration slots. This is recommended in the manual for the XMC4500. The system clock is 120MHz and the clock for the ADC kernel is configured to 30MHz (DIVA = 3).
The arbiter is running with full system clock (120MHz, DIVD = 0) when the above mentioned problem occur. If we decrease the frequency for the arbiter the problem disappears. With the value 2 or 3 written to the DIVD bit-field the interrupt is running and the problem seems to be solved. DIVD set to 0 or 1 does not work.

What is the maximum allowed frequency for the arbiter clock? In this case, with synchronous sampling of the ADC:s, what value of the DIVD bit-field is recommended to get a fixed (minimal) reaction time?


Hi jef,

would you be able to share your project? Can this project be replicated on the Infineon relax kit or Hex board?

Best regards
Travis
0 Likes
Not applicable
Markus wrote:
The synchronisation works partly - when i change something in the sourcecode which has no relation to the ADC, i only get the result of the Master-ADC. When i read out the Slave, the result is always 0.

Same problem here with 1 Master and 3 Slaves: Changing something which has nothing to do with the functionality oder the ADC means 0 on 3rd slave.

I will try to make a small demo of that and upload it.
0 Likes
lock attach
Attachments are accessible only for community members.
Not applicable
Lonz wrote:
Same problem here with 1 Master and 3 Slaves: Changing something which has nothing to do with the functionality oder the ADC means 0 on 3rd slave.

I will try to make a small demo of that and upload it.

Finally here it is.

I do have a constant DC +2V on pins 14.8, 14.9, 14.2, 15.2 on my Relax Kit-V1 with Stepping AA.
Chan4 is all zero.
pin 0.12 is PWM out, to check if it is working.

Thank you in advance 🙂

Edit: On lite-Kit V1 with AA it is the same.
First you Press BUTTON1, then LED2 is on, indicating that channel4 is zero-only.
It is good to see when you pause in debug and add chan1...chan4 and chan1zero...chan4zero as Watch-Expression.
0 Likes
Not applicable
How to make it "work":
Add "status_t status;" in line 64 (before ADC_Result_Int-function)
Add "status =" in line 77 before ADCSYNC001_GetResult...

status then is 0.
But: This of cause is not really a solution. In my original project it also happens that a channel surprisingly becomes zero if I change something elsewhere having nothing to do with the ADCs (e.g. at Ethernet-Code), just as Markus mentioned.
0 Likes
Not applicable
By now I do have zeros on 14.8 (first slave) and cannot "fix" it (by adding senseless code).

As there are several people with the same problem I would really appreciate if someone (Travis?) could look on it.
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Lonz wrote:
By now I do have zeros on 14.8 (first slave) and cannot "fix" it (by adding senseless code).

As there are several people with the same problem I would really appreciate if someone (Travis?) could look on it.


Hi, We are reviewing your codes with our ADC expert team and will get back to you shortly.
0 Likes
Not applicable
Travis wrote:
Hi, We are reviewing your codes with our ADC expert team and will get back to you shortly.

Hi Travis, that is great!
Do you have any ideas already?
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi Lonz,

I believe that this is related to DAVE3 code generation as I am seeing something strange here. Anyway I will follow up on this thread once I had some updates.


Best Regards
Travis
0 Likes
Not applicable
Hi,
are there any news about this topic?
I have encountered the same problem.

Best Regards,
red
0 Likes
Not applicable
Hi Travis,

It would at least be great to have some kind of "manual fix" for the auto-generated code.

Thank you in advance.
Best regards, Lonz
0 Likes
Not applicable
As there are no news from Infineon:

Looking into the result-registers of the "zero-Channels" is showing that they are 0. So this is not a bug of reading it via the ADCSYNC001_GetResult-function. (you can do this in DAVE Debug mode, view Registers, dropdown VADC_G..., Name RES[...])
The files generated by DAVE do not change between the builds but only a part of unrelated sourcecode elsewhere in the project.

So it looks like there is some kind of bug/race condition in the make/build-process. I cannot really see what it might be in the DAVE code generation.
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi Lonz,

We had acknowledge this issue of the ADC and the IP owner is coming with an official fix to this issue soon.

Best Regards
Travis
0 Likes
Not applicable
Travis wrote:
We had acknowledge this issue of the ADC and the IP owner is coming with an official fix to this issue soon.

Hi Travis,

thank you, I am looking forward to that.

Best regards,
Lonz
0 Likes
P__Yélamos
Employee
Employee
10 sign-ins First like given 5 sign-ins
Hello,

we have recognized that under certain circunstances, the order of initialization generated by the Apps is not the right one. You can try the following to confirm this is Happening in your case:

- Comment out instruction
WR_REG(VADCGroupPtr->ARBCFG, VADC_G_ARBCFG_ANONC_Msk, VADC_G_ARBCFG_ANONC_Pos, (uint32_t)HandlePtr->kAnalogConverterCtrl);

you can find this at the end of void ADCGROUP001_lInit(const ADCGROUP001_HandleType *HandlePtr ) API that you can find in ADCGroup001.c file in the Folder "Dave/Generated/src/ADCGROUP001/"

-Add following instruction right after the DAVE_Init():

WR_REG(VADC_G0->ARBCFG, VADC_G_ARBCFG_ANONC_Msk, VADC_G_ARBCFG_ANONC_Pos, 0x3);

Basically, the configuration of the Ready and ANON signals (refer to figure Figure in reference Manual "Synchronization via ANON and Ready Signals") are done after ANONC is written in the master. What we try with this workaround is to write it after all configurations of the ADC.
Of course, if you re-generate code, this workaround (the comment out of the intruction), will be overwritten,

We will try to implement this into the Apps accordingly. Sorry for the inconvinience.

Best Regards,
P. Yelamos
0 Likes
Not applicable
P. Yélamos wrote:
- Comment out instruction
WR_REG(VADCGroupPtr->ARBCFG, VADC_G_ARBCFG_ANONC_Msk, VADC_G_ARBCFG_ANONC_Pos, (uint32_t)HandlePtr->kAnalogConverterCtrl);

you can find this at the end of void ADCGROUP001_lInit(const ADCGROUP001_HandleType *HandlePtr ) API that you can find in ADCGroup001.c file in the Folder "Dave/Generated/src/ADCGROUP001/"

-Add following instruction right after the DAVE_Init():

WR_REG(VADC_G0->ARBCFG, VADC_G_ARBCFG_ANONC_Msk, VADC_G_ARBCFG_ANONC_Pos, 0x3);


Hi Pablo,
thank you very much, so far this is working.

Best regards,
Lonz
0 Likes
Not applicable
Hello,

I have been searching for "wrong code" since Monday. Now I was looking here and finaly found something.

I'm using the XMC4500 Relax Kit with DAVE 4. In my Project I have to use all 4 ADCs synchronuous. So I configured ADC_G0 as master and the others as slave. But when reading the conversion results there is always a channel wich result is 0.

I've treid these setps from Yélamos:

P. Yélamos wrote:

- Comment out instruction
WR_REG(VADCGroupPtr->ARBCFG, VADC_G_ARBCFG_ANONC_Msk, VADC_G_ARBCFG_ANONC_Pos, (uint32_t)HandlePtr->kAnalogConverterCtrl);

you can find this at the end of void ADCGROUP001_lInit(const ADCGROUP001_HandleType *HandlePtr ) API that you can find in ADCGroup001.c file in the Folder "Dave/Generated/src/ADCGROUP001/"

-Add following instruction right after the DAVE_Init():

WR_REG(VADC_G0->ARBCFG, VADC_G_ARBCFG_ANONC_Msk, VADC_G_ARBCFG_ANONC_Pos, 0x3);


I could not find the line to comment out. I think it not even exists anymore. And to add the other line did not work.
I would be very happy, if someone can help. Although this thread is so old.

I can upload an example project, if you want.


Greetings
bqpd
0 Likes
lock attach
Attachments are accessible only for community members.
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi bqpd,

Can you try out this software and let me know if it is working good over your side?

The software has the below configuration which might be similar to what you are doing.

1574.attach


best regards
travis
0 Likes
lock attach
Attachments are accessible only for community members.
Not applicable
Hello Travis,

thank you so much for your fast reply.

I tried to debug your project but it fails instantly with the error "No source available for "main() at 0x800088a" ". After starting it the debugger says "No source available for "XMC_VADC_GLOBAL_StartupCalibration() at 0x8001004"". I don't know how to handle these messages.


Maybe it is usefull, if I give you some more details about my project.
As I've said I want to convert all 4 ADCs simultaneously. So I configured ADC_G0 as Master and the others as Slave. All ADCs use the channel 0. The pins I want to convert are P14_9, P14_0, P14_2 und P14_4. Since these pins are not available on all ADCs and the sync-mode only works in channel 0 or 1 I had to use the Alias feature for Pins 14_2 and 14_9. However I even recofigured the result registers for all ADCs.
After initialising I start the Master ADC via Software and let it run in continuous mode. I activated the Background Request Source only for the Master and the end of measurement interrupt. I also wait for the Raedy-Signal of the Slaves.
So with every Interrupt I try to read out the result registers.

As you can read I don't use any trigger or any other request sources. It works pritty fine this way and it is very fast. But sometimes one or two result registers are always 0.

I attached my project. So you can see what I mean.


Greetings

Michael





By the way:
I want to measure the conversion time. So I increment a variable (conversionCount) in the ISR. In my main function (before the while(1); ). At first I start the master ADC and a Timer. After that I wait until conversionCount reaches 1000000. If there were enough conversions I immediately stop the ADCs and the Timer.
But here is another Problem: the while()- Loop is never reached. The Conversion never stops. I tried to increment another counter in my waiting loop. It doesn't count! It seems that he only runs the ISR but never returns to the main function.
maybe this has something to do with my previous problem. Otherwise it doesn't belong in this thead.
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi,



After initialising I start the Master ADC via Software and let it run in continuous mode. I activated the Background Request Source only for the Master and the end of measurement interrupt.


I don't think you should run background source with synchronous mode. Can I recommend that you tried the example which I had provide you? Please use the example with DAVE4.

http://www.infineon.com/cms/en/product/microcontroller/32-bit-industrial-microcontroller-based-on-ar...
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi,

Just a quick review on your source code that you are using Background source which is not applicable for synchronous conversion. Therefore the problem which you had mentioned is due to incorrect initialization.
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi,

Just a quick review on your source code that you are using Background source which is not applicable for synchronous conversion. Therefore the problem which you had mentioned is due to incorrect initialization.
0 Likes
Not applicable
Hello Travis,

bqpd wrote:

I tried to debug your project but it fails instantly with the error "No source available for "main() at 0x800088a" ". After starting it the debugger says "No source available for "XMC_VADC_GLOBAL_StartupCalibration() at 0x8001004"".


I'm using DAVE 4 for my projects. So I imported your example into my workspace an tried to run it. But there are only some strange error messages.


Travis wrote:

you are using Background source which is not applicable for synchronous conversion. Therefore the problem which you had mentioned is due to incorrect initialization.


What's wrong in my initialzation?


But sometimes it workes pretty good with this code (with Background source). I could have sampled all 4 channels in less than 600ns. This means they ran synchronously. But then I cleaned it a bit and deleted useless comments (mostly out commented old code) and unnecessary code phrases. Then it did'nt work anymore. 😞


Best Regards
bqpd
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi bqpd,

In XMC VADC there are 3 source which are the Queue, Scan and background source. However synchronous conversion is applicable only on Queue and Scan source.

In fact I had tested the example and it is working good without any error message. You might want to try the latest version from below.

http://www.infineonforums.com/threads/3373-XMC4000_HOT-How-to-do-VADC-Queue-source-synchronous-conve...
0 Likes
Not applicable
Hi Travis,


I also tried the lates version of your example. but no chance to debug it. Same error massages as before.
At least I found the raseon why:
Your example project was configured for XMC4500-F144x1024. But my Relax Kit contains the XMC4500-F100x1024 Package. So I created a new project and imported the files. Everything is fine now. It even seems to work pretty good.

In my first project I tried to create a synchronous conversion with DAVE APPs. The Global_ADC APP has some inputs für SYNC Signals. Are there any possibilities to use them??

However, I think it will be the best do programm my procejt with the LLD like you did in the example. It also seems to be easy and faster than with DAVE APPs.

Thanks so far. You've helped me a lot.


Best Regards
bqpd
0 Likes
Not applicable
Is it possible to speed the conversion up?

I measured time for 100,000 conversions: 370,005.33 µs = 3,700 ns till Interrupt occures. That's much too slow. Is there any possibility to speed up the Queue source?

I tried to configure scan source instead, but that's not much better.
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi bqpd,

Current DAVE4 version, only had background source for the Apps. Hence it is more flexible to use the LLD instead.

The Queue conversion happens at every 20KHz and you can change the triggering at the CCU8.
0 Likes
Not applicable
But I need 1Msamp/sec or more.

Modifying the CCU8 trigger is a bit hard. This fails very fast, since there are to many interrupts caused by the trigger. So the programm doesn't return into main() and continues the regular code. That's why I don't want to use hardware trigger. Too much overhead und thus it is to slow.
In the reference Manual I read "Each request source can operate in single-shot or in continuous mode" (RM, V1.5, 2014-07, p.19-11). But how?

The refill- option is activated. But I have to trigger by Software in every Interupt. Is it possilie to restart the queue request automatically?
0 Likes
lock attach
Attachments are accessible only for community members.
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi,
You can give this example a try. Which is working on queue continuous mode.
0 Likes
Not applicable
Hi Travis,

thank you very much für this example project. This is excactly what I needed. In the end I only had to deactivate the external trigger in the queue request. Very easy. I could have find out this by myself. *shame on me*
The synchronous conversion with the channels I need works now pretty good. All channels are converted.


But there is another thing:
I would like to know, how fast the conversion realy is. I need to know this for comparision to other settings.So I want to measure the conversion time. To do this I increment a variable (conversionCount) in the ISR. After initialization and software triggering it beginns running. In my main function (before while(1)-loop) I wait until conversionCount reaches a specific value (lets say100,000). If there were enough conversions I immediately stop the ADCs and the timer.

But here is the Problem: the while(conversionCount < 100000)- Loop is never reached. The Conversion never stops. I tried to increment another useless variable in this waiting loop. It doesn't count! It seems that he only runs the ISR but never returns to the main function.

I searched in the reference manual to solve this. Maybe there exists an extra flag I don't wait for. But it doesn't seem so. I just can't stop the ADC from running.

Maybe this is a complete different problem that doesn't belong in this thread. If it is so feel free to delete it.


Best Regards
bqpd
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Can you do this in the ISR instead.


conversionCount ++;

if (conversionCount >= 100000)
{
XMC_VADC_GROUP_QueueDisableArbitrationSlot(VADC_G0);
}
0 Likes
Not applicable
I tried so. But this doesn't solve the problem.

Also some funny/strange things happen when using the if-statement in the ISR.
It ran 1000 times. Result 27306 (return value from timer)
It ran 100,000 times. Result 27306 (return value from timer)
It ran 1,000,000 time. Result 54613(!) (return value from timer)

I observed this when using background source as well. So I don't think it is because of the ADCs. It must be a Timer issue.

I configured the timer with Dave APP "TIMER". It has an Time interval [usec] of 17895424 (max possible value). No start after init and no event activated.

The important part of my Main function:


	DAVE_Init();           /* Initialization of DAVE APPs (only the TIMER App)  */

//Reset Timer
if(TIMER_Clear(&TIMER_0) == TIMER_STATUS_FAILURE)
while(1);

//initialize ADC
VADC_Init();

//Start ADC --- There are no Triggers in VADC_Init()
XMC_VADC_GROUP_QueueTriggerConversion(VADC_G0);

//Start Timer
TIMER_Start(&TIMER_0);

//Wait for Conversions to be completed
while(conversionCount < 100000){
//The same loop with '>=' excists in the ISR
}

//Stop ADC
XMC_VADC_GROUP_QueueDisableArbitrationSlot(VADC_G0);

//Stop Timer
TIMER_Stop(&TIMER_0);

//Read out Timer value
timeCount = TIMER_GetTime(&TIMER_0);


I just found out some other strange s*** *SORRY*

I comment out the line

XMC_VADC_GROUP_QueueTriggerConversion(VADC_G0);


I step over the initialization.
And the AD Conversion starts immediatly when I stepped over TIMER_Start(&TIMER_0); There is no hardware Trigger configured for ADC. And specially not this one.

I don't know why. This makes no sense at all. I will delete the TIMER App and configure the Timer with LLD. This seems to be more efficient and less susceptible.


What do you think?
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
This function is not required

//Start ADC --- There are no Triggers in VADC_Init()
XMC_VADC_GROUP_QueueTriggerConversion(VADC_G0);

The latest software which i had provided you does not required any triggered. The VADC starts immediately when the arbitration is started. Hence your start timer is not in sync with the VADC by a few clock cycle.

Further more your stop timer is placed after the VADC interrupt and other coding, this cause additional delays to your measurement. My advise to you is to place the measuring code in the VADC ISR.

Anyway the whole this seems to be your software organisation.
0 Likes