XMC4000 Background Request Source Behavior

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

cross mob
funkyluke
Level 2
Level 2
5 sign-ins First like received 10 replies posted
Hello,

I posted a similar question a while ago but got no replies 😞 So I will ask it a bit differently 🙂

I have a Application where I need Results from multiple ADC Channels but have no stringent timing requirements.
Therefore I thought that the Global Background source on continuous mode would be the right choice and I would just grab a result when I need one.
This kind of works but I have some problems that may be due to lack of understanding what actually goes on behind the scenes.

I use FIFOs on some of the channels to aid with DRM/DMM, so I need Wait-for-Read Mode (It seems that if WFR is turned off on the input stage, then all the intermediate results of the DRM will be propagated through the FIFO - is this correct?)
The problem here is that if a channel with WFR set is not serviced (=read) then the background source stalls.
This is not desirable for my application since the lowest read frequency will determine the update frequency for all channels.
Is there any way around this, maybe through the use of a different queuing scheme?

Regards,
Funky Luke
0 Likes
5 Replies
User16529
Level 4
Level 4
First solution authored
Hi! For the ADC i use this code


const XMC_VADC_GLOBAL_CONFIG_t g_global_handle = {
.clock_config = {
.analog_clock_divider = 1, /*fADC = 10MHz (10us)*/
},
};



/* VADC group data configuration. No configuration needed, standard values
* are used. */

const XMC_VADC_GROUP_CONFIG_t g_group_handle = { };


/* Data configuration for background source. Standard values are used*/

const XMC_VADC_BACKGROUND_CONFIG_t g_bgn_handle = { };


/* Channel data configuration. Channel does NOT use alias feature and uses
* desired result register. */

const XMC_VADC_CHANNEL_CONFIG_t g_g0_ch0_handle = {
//.broken_wire_detect_channel = XMC_VADC_CHANNEL_BWDCH_VAREF,
//.broken_wire_detect = 1,
.alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
.result_reg_number = 0, };

const XMC_VADC_CHANNEL_CONFIG_t g_g0_ch1_handle = {
//.broken_wire_detect_channel = XMC_VADC_CHANNEL_BWDCH_VAREF,
//.broken_wire_detect = 1,
.alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
.result_reg_number = 1, };

const XMC_VADC_CHANNEL_CONFIG_t g_g0_ch2_handle = {
//.broken_wire_detect_channel = XMC_VADC_CHANNEL_BWDCH_VAREF,
//.broken_wire_detect = 1,
.alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
.result_reg_number = 2, };

const XMC_VADC_CHANNEL_CONFIG_t g_g0_ch3_handle = {
//.broken_wire_detect_channel = XMC_VADC_CHANNEL_BWDCH_VAGND,
//.broken_wire_detect = 1,
.alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
.result_reg_number = 3, };


void Init_AnlIn(void)
{
XMC_GPIO_DisableDigitalInput(VADC_CH0);
XMC_GPIO_DisableDigitalInput(VADC_CH1);
XMC_GPIO_DisableDigitalInput(VADC_CH2);
XMC_GPIO_DisableDigitalInput(VADC_CH3);

XMC_GPIO_SetMode(VADC_CH0, XMC_GPIO_MODE_INPUT_SAMPLING); /*ADC0*/
XMC_GPIO_SetMode(VADC_CH1, XMC_GPIO_MODE_INPUT_SAMPLING); /*ADC1*/
XMC_GPIO_SetMode(VADC_CH2, XMC_GPIO_MODE_INPUT_SAMPLING); /*ADC2*/
XMC_GPIO_SetMode(VADC_CH3, XMC_GPIO_MODE_INPUT_SAMPLING); /*ADC3*/

/* Provide clock to VADC and initialize the VADC global registers. */
XMC_VADC_GLOBAL_Init(VADC, &g_global_handle);

/* Initialize the conversion kernel. */
XMC_VADC_GROUP_Init(VADC_G0, &g_group_handle);

/* Set VADC group to normal operation mode (VADC kernel). */
XMC_VADC_GROUP_SetPowerMode(VADC_G0, XMC_VADC_GROUP_POWERMODE_NORMAL);

/* Calibrate the VADC. Make sure you do this after all used VADC groups
* are set to normal operation mode. */
XMC_VADC_GLOBAL_StartupCalibration(VADC);

/* Initialize the background source hardware. The gating mode is set to
* ignore to pass external triggers unconditionally.*/
XMC_VADC_GLOBAL_BackgroundInit(VADC, &g_bgn_handle);

/* Initialize the channel unit. */
XMC_VADC_GROUP_ChannelInit(VADC_G0, 0, &g_g0_ch0_handle);
XMC_VADC_GROUP_ChannelInit(VADC_G0, 1, &g_g0_ch1_handle);
XMC_VADC_GROUP_ChannelInit(VADC_G0, 2, &g_g0_ch2_handle);
XMC_VADC_GROUP_ChannelInit(VADC_G0, 3, &g_g0_ch3_handle);
}


then, in the main

Init_AnlIn();

/* Add a channel to the background source. */
XMC_VADC_GLOBAL_BackgroundAddChannelToSequence(VADC, 0, 0);
XMC_VADC_GLOBAL_BackgroundAddChannelToSequence(VADC, 0, 1);
XMC_VADC_GLOBAL_BackgroundAddChannelToSequence(VADC, 0, 2);
XMC_VADC_GLOBAL_BackgroundAddChannelToSequence(VADC, 0, 3);

/* Enables autoscan feature for continuous conversion. */

XMC_VADC_GLOBAL_BackgroundEnableContinuousMode(VADC);

/* Generate conversion request (load event). */
XMC_VADC_GLOBAL_BackgroundTriggerConversion(VADC);

...

Ch0 = XMC_GPIO_GetInput(VADC_CH0);
Ch1 = XMC_GPIO_GetInput(VADC_CH1);
Ch2 = XMC_GPIO_GetInput(VADC_CH2);
Ch3 = XMC_GPIO_GetInput(VADC_CH3);

result[0] = XMC_VADC_GROUP_GetResult(VADC_G0, 0);
result[1] = XMC_VADC_GROUP_GetResult(VADC_G0, 1);
result[2] = XMC_VADC_GROUP_GetResult(VADC_G0, 2);
result[3] = XMC_VADC_GROUP_GetResult(VADC_G0, 3);


I hope it helps you
0 Likes
funkyluke
Level 2
Level 2
5 sign-ins First like received 10 replies posted
Hello Janet,

My configuration is similar to yours, and generally works.
Your code does not address the details of the background source behavior that are unclear to me.
0 Likes
User16529
Level 4
Level 4
First solution authored
The description in the xmc_vadc.h says

/**
* @param global_ptr Pointer to the VADC module
* @return
* None
*
* \parDescription:

* Enables continuous conversion mode.
\n
* Typically for a Background request source to generate conversion request, either a hardware trigger or a software
* request is needed. Using autoscan (continuous conversion)feature it is possible to start the conversion
* once and allow the sequence to repeat without any further triggers. Once all channels belonging to a Background
* request source have been converted, a request source completion event is generated. Generation of this event
* can restart the Background configure sequence. Every request source event will cause a load event to occur.
* A call to this API would access the register bit field BRSMR.SCAN.
*
* \parRelated APIs:

* XMC_VADC_GROUP_BackgroundDisableContinuousMode()

*/
__STATIC_INLINE void XMC_VADC_GLOBAL_BackgroundEnableContinuousMode(XMC_VADC_GLOBAL_t *const global_ptr)
{
XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundEnableContinuousMode:Wrong Module Pointer", (global_ptr == VADC))
global_ptr->BRSMR |= (uint32_t)VADC_BRSMR_SCAN_Msk;
}


So, once you've triggered the sampling on a channel, it goes on
0 Likes
funkyluke
Level 2
Level 2
5 sign-ins First like received 10 replies posted
Thanks Janet, I know this. I too have read the XMCLib Documentation.
But the behavior I described is not really documented there.

To my understanding it is may be caused by the WFR Mode blocking the request source from issuing a request, therefore the pending bit in BRSPND is not cleared and the Sequence never reloads (because it does when all BRSPND bits are reset).
0 Likes
User16529
Level 4
Level 4
First solution authored
Ok. I read the application note about VADC and it says that in wait-for-read mode the channel conversion requests can be made only when the result has been read. So you have to read the result before start a new conversion.
Maybe you can avoid the wait for read and use only the background conversion, i think it could be what you need.
0 Likes