Problems with synchronized ADC

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

cross mob
Not applicable
Hello all,

im working on a synchronous conversion like in the Infineon example in AP32305 p.24++.
I only want the synchronous ADC (just group 0, 1 with channel 0 and 1). So i set the external Trigger on the first channel of the master G0CH0. It works properly.
But when i activate Interrupts (no matter if result event or queue source event) one of the four results is always 0. It´s the corresponding slave channel of the triggered master channel.
What is wrong with this configuration?!


 /***************************************************************************
* HEADER FILES
**************************************************************************/
#include
#include

/***************************************************************************
* CONFIGURATION
**************************************************************************/
/* VADC Global resources data configuration. Divider factor for the analog
* internal clock is set => fADCI = 120 MHz / (DIVA+1) */
const XMC_VADC_GLOBAL_CONFIG_t g_global_handle = {
.clock_config = {
.analog_clock_divider = 3,
},
};

/* VADC group data configuration. No configuration needed, standard values
* are used. */
const XMC_VADC_GROUP_CONFIG_t g_group_handle = { };

/* Data configuration for queue source. The trigger input I is used to
* trigger the conversion on any edge (see also "Digital Connections in the
* XMC4500" in the Reference Manual). */
const XMC_VADC_QUEUE_CONFIG_t g_queue_handle = {
.trigger_signal = XMC_VADC_REQ_TR_I,
.trigger_edge = XMC_VADC_TRIGGER_EDGE_ANY,
.external_trigger = 1 };

/* Channel data configuration. Channels do NOT use alias feature and use
* desired result register. Channel 1 and 0 trigger a synchronous
* conversion of the same numbered channels on group 1. */

const XMC_VADC_CHANNEL_CONFIG_t g_g0_ch1_handle = {
.alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
.result_reg_number = 1,
.sync_conversion = 1,};
const XMC_VADC_CHANNEL_CONFIG_t g_g0_ch0_handle = {
.alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
.result_reg_number = 0,
.sync_conversion = 1, };
const XMC_VADC_CHANNEL_CONFIG_t g_g1_ch1_handle = {
.alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
.result_reg_number = 1, };
const XMC_VADC_CHANNEL_CONFIG_t g_g1_ch0_handle = {
.alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
.result_reg_number = 0, };

/* Queue entry configuration. For each entry a channel is configured. All
* entries are configured to be refilled automatically. Entry 0 can be
* triggered externally. */

const XMC_VADC_QUEUE_ENTRY_t g_queue_entry_1_handle = {
.channel_num = 1,
.refill_needed = 1,
.external_trigger = 1,
};
const XMC_VADC_QUEUE_ENTRY_t g_queue_entry_2_handle = {
.channel_num = 0,
.refill_needed = 1,
.external_trigger = 0,
.generate_interrupt= 1,
};

/* Timer (CCU8) configuration. The CCU8 is configured to use center aligned
* mode and a prescaler divider value of 7. */
const XMC_CCU8_SLICE_COMPARE_CONFIG_t g_timer_object = {
.timer_mode = XMC_CCU8_SLICE_TIMER_COUNT_MODE_CA,
.prescaler_initval = (uint32_t) 7, };
/***************************************************************************
* GLOBAL DATA
**************************************************************************/
XMC_VADC_RESULT_SIZE_t result_0; // VADC_G0_CH4
XMC_VADC_RESULT_SIZE_t result_1; // VADC_G0_CH1
XMC_VADC_RESULT_SIZE_t result_2; // VADC_G0_CH0
XMC_VADC_RESULT_SIZE_t result_3; // VADC_G1_CH1
XMC_VADC_RESULT_SIZE_t result_4; // VADC_G1_CH0

/***************************************************************************
* Function declarations
**************************************************************************/
unsigned int adc_values[6];

int main(void)
{
/* Clock is already initialized by startup code. */

/* ****************************** VADC ****************************** */
/* 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);
XMC_VADC_GROUP_Init(VADC_G1, &g_group_handle);

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

/* Calibrate the VADC. */
XMC_VADC_GLOBAL_StartupCalibration(VADC);

/* Initialize the scan source hardware. The gating mode is set to
* ignore to pass external triggers unconditionally. As group 1 is the
* slave group, there has NO source to be configured for group 1. */
XMC_VADC_GROUP_QueueInit(VADC_G0, &g_queue_handle);

/* Initialize the channel unit. */
XMC_VADC_GROUP_ChannelInit(VADC_G0, 1, &g_g0_ch1_handle);
XMC_VADC_GROUP_ChannelInit(VADC_G0, 0, &g_g0_ch0_handle);
XMC_VADC_GROUP_ChannelInit(VADC_G1, 1, &g_g1_ch1_handle);
XMC_VADC_GROUP_ChannelInit(VADC_G1, 0, &g_g1_ch0_handle);

/* Add a channel to the scan source. */
XMC_VADC_GROUP_QueueInsertChannel(VADC_G0, g_queue_entry_1_handle);
XMC_VADC_GROUP_QueueInsertChannel(VADC_G0, g_queue_entry_2_handle);

/*NOTE:
* The master has to wait for all slaves and all slaves have to send the ready signal to the master AND
* to all other slaves.*/

/* Set a group as master group during sync conversion. */
XMC_VADC_GROUP_SetSyncMaster(VADC_G0);

/* Set a group as slave group during sync conversion. */
XMC_VADC_GROUP_SetSyncSlave(VADC_G1, 0, 1);

/* Check if slave is ready. */
XMC_VADC_GROUP_CheckSlaveReadiness(VADC_G1, 1); /*Master wait until slave is ready.*/
XMC_VADC_GROUP_CheckSlaveReadiness(VADC_G0, 1); /*Slave send ready signal to master.*/

XMC_VADC_GROUP_QueueSetReqSrcEventInterruptNode(VADC_G0, XMC_VADC_SR_GROUP_SR2);
/* Set priority of NVIC node meant to e connected to Kernel Request source event */
NVIC_SetPriority(VADC0_G0_2_IRQn, 10U); // Table 4-3 Interrupt Node assignment
/* Enable IRQ */
NVIC_EnableIRQ(VADC0_G0_2_IRQn);

/* ****************************** CCU8 ****************************** */
/* Initialize CCU8 global resources. */
XMC_CCU8_Init(CCU80, XMC_CCU8_SLICE_MCMS_ACTION_TRANSFER_PR_CR);

/* Start the prescaler and restore clocks to the timer slices. */
XMC_CCU8_StartPrescaler(CCU80);

/* Configure CC8 Slice in compare mode. */
XMC_CCU8_SLICE_CompareInit(CCU80_CC80, &g_timer_object);

/* Program period match value of the timer. */
XMC_CCU8_SLICE_SetTimerPeriodMatch(CCU80_CC80, 0xFFFE);

/* Program compare match value of the timer. */
XMC_CCU8_SLICE_SetTimerCompareMatch(CCU80_CC80,
XMC_CCU8_SLICE_COMPARE_CHANNEL_1, 0x1FFF);
XMC_CCU8_SLICE_SetTimerCompareMatch(CCU80_CC80,
XMC_CCU8_SLICE_COMPARE_CHANNEL_2, 0xEFFF);

/* Transfer value from shadow timer registers to actual timer
* registers. */
XMC_CCU8_EnableShadowTransfer(CCU80, CCU8_GCSS_S0SE_Msk);

/* Enable period/compare match event. */
XMC_CCU8_SLICE_EnableEvent(CCU80_CC80,
XMC_CCU8_SLICE_IRQ_ID_COMPARE_MATCH_UP_CH_1);
XMC_CCU8_SLICE_EnableEvent(CCU80_CC80,
XMC_CCU8_SLICE_IRQ_ID_COMPARE_MATCH_UP_CH_2);

/* Bind capcom event to an NVIC nodes (see also "Digital Connections in
* the XMC4500" in the Reference Manual). */
XMC_CCU8_SLICE_SetInterruptNode(CCU80_CC80,
XMC_CCU8_SLICE_IRQ_ID_COMPARE_MATCH_UP_CH_1,
XMC_CCU8_SLICE_SR_ID_2);
XMC_CCU8_SLICE_SetInterruptNode(CCU80_CC80,
XMC_CCU8_SLICE_IRQ_ID_COMPARE_MATCH_UP_CH_2,
XMC_CCU8_SLICE_SR_ID_2);

/* Enable the slice timer clock. */
XMC_CCU8_EnableClock(CCU80, 0);

/* Start the timer counting operation. */
XMC_CCU8_SLICE_StartTimer(CCU80_CC80);

/* ****************************** Loop ****************************** */
while (1U) {}
return 1;
}

void VADC0_G0_2_IRQHandler(void)
{
NVIC_ClearPendingIRQ(VADC0_G0_2_IRQn);
/* Retrieve result from result register. */
result_1 = XMC_VADC_GROUP_GetResult(VADC_G0, 1);
result_2 = XMC_VADC_GROUP_GetResult(VADC_G0, 0);
result_3 = XMC_VADC_GROUP_GetResult(VADC_G1, 1);
result_4 = XMC_VADC_GROUP_GetResult(VADC_G1, 0);
}


best regards
0 Likes
1 Reply
User13476
Level 1
Level 1
Hello

I used to have similar problem where the last channel of the slave is always giving the Zero value. This is is because channel was not participating the conversion
as it was not synched properly.
Solution I got is: Turn OFF Arbitrar ==> Set up Master Slave VADC group Configuration ==> Turn ON Master Group conversion.
Sync issue between master and slave will be resolved by this. All configured channels should show conversion happening correctly.
0 Likes