XMC1100-configure analog-digital converter

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

cross mob
Not applicable
Hi,

i want wo use the VADC on the XMC11000. Unfortunately the ADC001 App is not working with the XMC1100, so i decided to go the old-fashioned way without the app.
So i read the reference manual and i thought i had everything to use the adc. But as i tried to run the programm on the board it didn't work.
I noticed that the ANOFF bit of the SHS0_SHSCFG register was not set and so the converter was not activated.
As you can see in the code example i enable the write acces (over the SCWC bit) of the register before i set the ANOFF bit. But neither the SCWC bit nor the ANOFF bit is set. The register just keeps the value 0x1000 (module in power down mode).


SHS0->SHSCFG |= (SHS_SHSCFG_SCWC_Msk); // Enable write access to ANOFF and AREF
SHS0->SHSCFG &= ~(SHS_SHSCFG_ANOFF_Msk); // Set ANOFF to 0 to toggle on converter.

while (~(SHS0->SHSCFG & (SHS_SHSCFG_ANRDY_Msk))); // Wait until converter is ready.


So if you have any idea what i could have forgotten or what else please answer 🙂

Jan
0 Likes
18 Replies
Not applicable
Hi Jan,

Did you disable the clock gating to the VADC?
You have to set at SCU_CGATCLR0 register to disable the gating which by default is gated.

This is how you can disabled your gating:
	SCU_GENERAL->PASSWD = 0x000000C0;
SCU_CLK->CGATCLR0 |= 0x00000001; // disable VADC gating
while((SCU_CLK->CLKCR)&0x40000000); // wait for VDDC to stabilize
SCU_GENERAL->PASSWD = 0x000000C3;
0 Likes
Not applicable
Hi Jackson,

thanks for the support. I already had the VADC gating disabled.
I tried something new and changed the Line
SHS0->SHSCFG |= (SHS_SHSCFG_SCWC_Msk); 
to
SHS0->SHSCFG = (SHS_SHSCFG_SCWC_Msk);

Now the SHSCFG register is 0x00 but still the ANRDY flag does not change to 1. But as the ANOFF Bit is 0 i think the ADC should start working... so i read again in the reference manual and found this for the ANOFF Bit: 0 Converter controlled by bitfields ANONS
(digital control block).
But I dont understand what that means. I did not find anything about ANONS, it is not a part of any register, so i dont know how i should control the Converter by ANONS. Do you have any idea how this works?

Just for more information about my programm this is the register initialization part:
DAVE_Init();			// Initialization of DAVE Apps


SCU_GENERAL->PASSWD = 0x000000C0;
SCU_CLK->CGATCLR0 |= 0x00000001; // disable VADC gating
while((SCU_CLK->CLKCR)&0x40000000); // wait for VDDC to stabilize
SCU_GENERAL->PASSWD = 0x000000C3;

// Initialize adc on P2.6
PORT2->IOCR4 &= ~PORT2_IOCR4_PC6_Msk; // Set P2.6 as Input.
VADC->CLC &= ~VADC_CLC_DISR_Msk; // Enable Clock for the analog section.
SHS0->SHSCFG = (SHS_SHSCFG_SCWC_Msk); // Enable write access to ANOFF and AREF
SHS0->SHSCFG &= ~(SHS_SHSCFG_ANOFF_Msk); // Toggle on converter.

while (~(SHS0->SHSCFG & (SHS_SHSCFG_ANRDY_Msk))); // Wait until converter is ready.
VADC->GLOBCFG &= ~VADC_GLOBCFG_DPCAL0_Msk; // Enable post-calibration.
VADC->GLOBCFG &= ~VADC_GLOBCFG_SUCAL_Msk; // Raising edge on SUCAL to initiate the calibration.
VADC->GLOBCFG |= VADC_GLOBCFG_SUCAL_Msk;
while (SHS0->SHSCFG & SHS_SHSCFG_STATE_Msk); // Wait until calibration is finished.
VADC->BRSMR |= 0x01UL; // Gate always enabled.
VADC->BRSSEL[0] |= VADC_BRSSEL_CHSELG0_Msk; // Select P2.6 as input channel.
VADC->GLOBICLASS[0] |= (0x02UL << VADC_GLOBICLASS_CMS_Pos); // Select 8-Bit conversion for channel 0.


I'm currently using the PWMSP001, CCU4GLOBAL and the CLK002 Apps with default settings (except the "start during initialization" flag of PWM).

I also noticed that Warning, when i start the Debugger to load the code on the board:
Warning: CPU is running at low speed (6197 kHz).
Could this have anything todo with my problem?

Jan
0 Likes
Arno
Employee
Employee
25 replies posted 10 replies posted 5 replies posted
Hi Jan,

please have a look at the errata sheet of XMC1100. There are two workarounds described which are relevant.

Arno
0 Likes
Not applicable
Hi Arno,

thank you very much, the ADC works just fine now.
But i still have a problem. When i load the code on the board, there is a warning, that the CPU is running at slow speed (about 6 Mhz). The CLK002 app is configured to 1MHz. Is this just an unimportant warning or could there be something wrong with the clock app?

There is one more thing, that i find pretty strange... I'm powering the board with 9V and there is a infrared distance sensor which is powerd by the 5V pin of the board. The strange thing is, the board makes a high frequenzy noise that somehow sounds like a chirr... When i unplug the sensor the noise goes away, but it comes from the board, not from the sensor.
Have you ever heard of something like that or any idea how i can fix this?

Jan
0 Likes
Not applicable
Hi Jan,

I experience the same issues on ADC init, could you share the complete code?

Anto
0 Likes
Not applicable
HI,

I wrote this code to initialize ADC adding workaround ... but somethings does not work properly. Any idea?

#define ADC_ADDR_FIX1 0x40010500
#define ADC_ADDR_FIX2 0x480340E0
#define ADC_ADDR_FIX3 0x480340E4
#define WRITE_MEMREG(addr,val) ((*(volatile uint32_t *)addr) = (val))

void MyADC_Init(void)
{
SCU_GENERAL->PASSWD = 0x000000C0;
SCU_CLK->CGATCLR0 |= 0x00000001; // disable VADC gating
while((SCU_CLK->CLKCR)&0x40000000); // wait for VDDC to stabilize
SCU_GENERAL->PASSWD = 0x000000C3;

// Initialize adc on P2.6
PORT2->IOCR4 &= ~PORT2_IOCR4_PC6_Msk; // Set P2.6 as Input.

VADC->CLC &= ~VADC_CLC_DISR_Msk; // Enable Clock for the analog section.
SHS0->SHSCFG = (SHS_SHSCFG_SCWC_Msk); // Enable write access to ANOFF and AREF
SHS0->SHSCFG &= ~(SHS_SHSCFG_ANOFF_Msk); // Toggle on converter.
WRITE_MEMREG(ADC_ADDR_FIX1,0x1); // FIX ADC_AI.003
block here--> while (~(SHS0->SHSCFG & (SHS_SHSCFG_ANRDY_Msk))); // Wait until converter is ready.

// SET initial calibration
VADC->GLOBCFG &= ~VADC_GLOBCFG_SUCAL_Msk; // Clear SUCAL bit
VADC->GLOBCFG |= VADC_GLOBCFG_DPCAL0_Msk; // Disable post-calibration.
VADC->GLOBCFG |= VADC_GLOBCFG_DPCAL1_Msk; // Disable post-calibration.
VADC->GLOBCFG |= VADC_GLOBCFG_SUCAL_Msk; // Raising edge on SUCAL to initiate the calibration.
while (SHS0->SHSCFG & SHS_SHSCFG_STATE_Msk); // Wait until calibration is finished.
WRITE_MEMREG(ADC_ADDR_FIX2,0x80008000); // FIX ADC_AI.004
WRITE_MEMREG(ADC_ADDR_FIX3,0x80008000); // FIX ADC_AI.004

VADC->BRSMR |= 0x01UL; // Gate always enabled.
VADC->BRSSEL[0] |= VADC_BRSSEL_CHSELG0_Msk; // Select P2.6 as input channel.
VADC->GLOBICLASS[0] |= (0x02UL << VADC_GLOBICLASS_CMS_Pos); // Select 8-Bit conversion for channel 0
}
0 Likes
Not applicable
Hi Anto,

this is what i have right now:


SCU_GENERAL->PASSWD = 0x000000C0;
SCU_CLK->CGATCLR0 |= 0x00000001; // disable VADC gating
while((SCU_CLK->CLKCR)&0x40000000); // wait for VDDC to stabilize
SCU_GENERAL->PASSWD = 0x000000C3;

// Initialize adc on P2.6
PORT2->IOCR4 &= ~PORT2_IOCR4_PC6_Msk; // Set P2.6 as Input.
VADC->CLC &= ~VADC_CLC_DISR_Msk; // Enable Clock for the analog section.
SHS0->SHSCFG = (SHS_SHSCFG_SCWC_Msk); // Enable write access to ANOFF and AREF
SHS0->SHSCFG &= ~(SHS_SHSCFG_ANOFF_Msk); // Toggle on converter.
*((int*)0x40010500) = 0x01; // workaround to enable converter.
// SHS0->SHSCFG TODO: set AREF
while ((SHS0->SHSCFG & SHS_SHSCFG_ANRDY_Msk) == 0); // Wait until converter is ready.

// VADC->GLOBCFG &= ~VADC_GLOBCFG_DPCAL0_Msk; // Enable post-calibration.
// workaround for calibration
VADC->GLOBCFG |= VADC_GLOBCFG_DPCAL0_Msk;
VADC->GLOBCFG |= VADC_GLOBCFG_DPCAL1_Msk;
VADC->GLOBCFG &= ~VADC_GLOBCFG_SUCAL_Msk; // Raising edge on SUCAL to initiate the calibration.
VADC->GLOBCFG |= VADC_GLOBCFG_SUCAL_Msk;
// workaround for calibration
VADC->GLOBCFG |= VADC_GLOBCFG_DPCAL0_Msk;
VADC->GLOBCFG |= VADC_GLOBCFG_DPCAL1_Msk;
while ((SHS0->SHSCFG & SHS_SHSCFG_STATE_Msk) != 0); // Wait until calibration is finished.
*((int*)0x480340E0) = 0x80008000;
*((int*)0x480340E4) = 0x80008000;

VADC->BRSMR |= 0x01UL; // Gate always enabled.
VADC->BRSSEL[0] |= VADC_BRSSEL_CHSELG0_Msk; // Select P2.6 as input channel.
VADC->GLOBICLASS[0] |= (0x01UL << VADC_GLOBICLASS_CMS_Pos); // Select 10-Bit conversion for channel 0.


I think the only diffrence is in the calibration workaround.
This is the workaround for the recalibration:


// reconfigure workaround
*((int*)0x480340E0) = 0x0;
*((int*)0x480340E4) = 0x0;
VADC->GLOBCFG |= VADC_GLOBCFG_SUCAL_Msk;
// workaround for calibration
VADC->GLOBCFG |= VADC_GLOBCFG_DPCAL0_Msk;
VADC->GLOBCFG |= VADC_GLOBCFG_DPCAL1_Msk;
while ((SHS0->SHSCFG & SHS_SHSCFG_STATE_Msk) != 0); // Wait until calibration is finished.
*((int*)0x480340E0) = 0x80008000;
*((int*)0x480340E4) = 0x80008000;


Jan
0 Likes
Not applicable
Hi Jan,

I just substitute this line

while (~(SHS0->SHSCFG & (SHS_SHSCFG_ANRDY_Msk)));

with this one

while ((SHS0->SHSCFG & SHS_SHSCFG_ANRDY_Msk) == 0);

and ADC start to work properly. Also could you share code for reading input on pin 2.6?

Thanks a lot.
Anto
0 Likes
Not applicable
Hi Anto,

your problem was: (SHS0->SHSCFG & (SHS_SHSCFG_ANRDY_Msk) evaluates to 0000000000000000x0000000000000 where x is the value of the ANRDY flag.
So with the binary negation operator "~" it evaluates to 11111111111111111(~x)11111111111111 which is allways true. Only 0000000000000000x0000000000000 is false.

For reading the sensor result:


VADC->BRSPND[0] |= VADC_BRSPND_CHPNDG0_Msk; // Set P2.6 to pending channel to start conversion.
while ((VADC->GLOBRES & VADC_GLOBRES_VF_Msk) == 0); // Wait until valid flag is set.
value = (VADC->GLOBRES & VADC_GLOBRES_RESULT_Msk) >> 2; // Save the result.


Which bits in the GLOBRES register actually hold the value depends on the mode you are using (8 bit, 10 bit, etc.) You should take a look in the reference manual.

Jan
0 Likes
Not applicable
Hi Jan,

sorry for delay in my answer, thank you for your support. SW works fine now.

Ragards,
Anto
0 Likes
Not applicable
Hello to everybody!
In these last month an APP for XMC1100 A/D was released. It works and I use it from a lot of times. I experience some data instability triggering a DC value, I found a problem in post-calibration, so I disable it.
Recently (23/8) an official A/D issue was reported on the use of SW calibration instead of HW. I would like to implement this SW calibration but I don't understood somethings. This is the workaround:

After the startup calibration, disable postcalibration for all groups and replace this by the following software calibration routine:
•Clear the offset calibration value
•Convert channel CH31 (this is VAREF)
•If the result is below 0xFFF, decrease the gain calibration value:
LOCi = LOCi + 0x00008000 - 1,
otherwise increase it:
LOCi = LOCi + 0x00008000 + 1.
The memory address of LOCi (i = 0 - 1) are:
480340C0H for group 0 (i = 0),
480340C4H for group 1 (i = 1).

I'm not able to identify "Convert channel CH31 (this is VAREF)".
Any idea?

Regards,
Anto
0 Likes
Arno
Employee
Employee
25 replies posted 10 replies posted 5 replies posted
Hi Anto,

thank you for the positive feedback about the ADC APP.
The workaround about software calibration was added to XMC1100 by mistake. It is only feasible with XMC1200 and XMC1300 families.
Of course you could connect an ADC input pin to a reference voltage (e.g. supply voltage) and run the workaround as described. Then it is not channel 31, but the selected input channel, which is to be used.

Best Regards,
Arno
0 Likes
User7921
Level 3
Level 3
I do not understand the "otherwise" path...

If the result is below 0xFFF, decrease the gain calibration value:
LOCi = LOCi + 0x00008000 - 1,
otherwise increase it:
LOCi = LOCi + 0x00008000 + 1.


How could the result ever get bigger than 0xFFF?
No matter how big the gain is, the ADC has 12bit and therefor a max. value of 4095.

I tried it with a 4096mV external ref on channel 0.
It works untill it reaches 0xFFF.
I didn't ever get a value greater than 0xFFF on channel 0.

Thanks for help.

Michael
0 Likes
Arno
Employee
Employee
25 replies posted 10 replies posted 5 replies posted
I think, we should read 0xFFF as 0xFFE in order to allow the calibration loop to adjust.
As a result we should scale the voltage to 0xFFE full scale.

Best regards,
Arno
0 Likes
MaxECU
Employee
Employee
Welcome!
Many thanks for this post, I was also able to use the ADC!
0 Likes
User13476
Level 1
Level 1
Hi Arno,

I am working on, XMC4700 evaluation KIT. I am working on ADC Module.

How to drive the VAREF to 2.5 volts?

As of now, I am trying to connect external voltage measuring 2.5 volts to VAREF, so that I can use 2.5 volts as standard reference voltage.
Its not taking voltage I am supplying to VAREF, instead 3.3 v default voltage is considering.

Need guidence.

Regards,
ADCG
0 Likes
User14877
Level 1
Level 1
Can u tell me how this value is calculated ?
*((int*)0x480340E0) = 0x80008000;
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi,

That register address and value is given in XMC1100 AA-Step Errata Sheet page 9/35 (XMC1100-AA Errata Sheet).

3092.attach

Best regards,
Deni
0 Likes