ADC triggered by PWM is not getting the ADC Complete interrupt.

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

cross mob
Not applicable
Hello Forum.

Well, I'm becoming quiet dependent on this forum.

I am trying to do something very similar to what is outlined in the application note AP32287 section 4.2: Example use case: triggering ADC conversion using CCU4 single shot.

I trigger the CCU4 by an event not a push button.

The CCU4 trigger is working because I CC4yINTS status shows that a period match was detected AND an event 0 was detected.

And the CC4ySRS register is configured for forward Event 0 Service requests to CC4ySR2 which is hooked up to ADC input selector.

I have the ADC queue ready to receive the trigger event and start doing it's conversion, and I think it does it, but I get no interrupt at the end.
I think the ADC is getting it because if I configure the queue to not refill, I get a QUEUE EMPTY in the QSR0.

Any pointers would be great....

Here is my code snips...


/* ADC */
#define RES_REG_NUMBER (0)
#define CHANNEL_NUMBER (2U)
#define VADC_GROUP_PTR (VADC_G0) /* P14.2 */
#define VADC_GROUP_ID (0)
#define IRQ_PRIORITY (10U)

/* CCU4 */
#define SLICE_PTR CCU40_CC43
#define MODULE_PTR CCU40
#define MODULE_NUMBER (0U)
#define SLICE_NUMBER (3U)
#define CAPCOM_MASK (SCU_GENERAL_CCUCON_GSC40_Msk)

/* ADC */


XMC_VADC_GLOBAL_CONFIG_t g_global_handle =
{
.disable_sleep_mode_control = false,
.clock_config = {
.analog_clock_divider = 3,
.msb_conversion_clock = 0,
.arbiter_clock_divider = 1
},
.class0 = {
.conversion_mode_standard = XMC_VADC_CONVMODE_12BIT,
.sample_time_std_conv = 3U,
.conversion_mode_emux = XMC_VADC_CONVMODE_12BIT,
.sampling_phase_emux_channel = 3U
},
.class1 = {
.conversion_mode_standard = XMC_VADC_CONVMODE_12BIT,
.sample_time_std_conv = 3U,
.conversion_mode_emux = XMC_VADC_CONVMODE_12BIT,
.sampling_phase_emux_channel = 3U
},
.data_reduction_control = 0,
.wait_for_read_mode = true,
.event_gen_enable = false,
.boundary0 = 0,
.boundary1 = 0
};


XMC_VADC_GROUP_CONFIG_t g_group_handle = {
.class0 = {
.conversion_mode_standard = XMC_VADC_CONVMODE_12BIT,
.sample_time_std_conv = 3U,
.conversion_mode_emux = XMC_VADC_CONVMODE_12BIT,
.sampling_phase_emux_channel = 3U
},
.class1 = {
.conversion_mode_standard = XMC_VADC_CONVMODE_12BIT,
.sample_time_std_conv = 3U,
.conversion_mode_emux = XMC_VADC_CONVMODE_12BIT,
.sampling_phase_emux_channel = 3U
},
.arbitration_round_length = 0x0U,
.arbiter_mode = XMC_VADC_GROUP_ARBMODE_ALWAYS,
.boundary0 = 0,
.boundary1 = 0,
.emux_config = {
.emux_mode = XMC_VADC_GROUP_EMUXMODE_SWCTRL,
.stce_usage = 0,
.emux_coding = XMC_VADC_GROUP_EMUXCODE_BINARY,
.starting_external_channel = 0,
.connected_channel = 0
}
};

XMC_VADC_GROUP_t *g_group_identifier = VADC_GROUP_PTR;

XMC_VADC_CHANNEL_CONFIG_t g_channel_handle =
{
.channel_priority = 1U,
.input_class = XMC_VADC_CHANNEL_CONV_GROUP_CLASS1,
.alias_channel = -1,
.bfl = 0,
.event_gen_criteria = XMC_VADC_CHANNEL_EVGEN_ALWAYS,
.alternate_reference = XMC_VADC_CHANNEL_REF_INTREF,
.result_reg_number = (uint8_t) RES_REG_NUMBER,
.use_global_result = false,
.broken_wire_detect_channel = false,
.broken_wire_detect = false
};


XMC_VADC_RESULT_CONFIG_t g_result_handle = {
.post_processing_mode = XMC_VADC_DMM_REDUCTION_MODE,
.data_reduction_control = 0,
.part_of_fifo = false,
.wait_for_read_mode = true,
.event_gen_enable = false
};

/* Queue hardware configuration data */
XMC_VADC_QUEUE_CONFIG_t g_queue_handle =
{
.req_src_priority = (uint8_t)3, /* 3 = highest, 0 = lowest */
.conv_start_mode = XMC_VADC_STARTMODE_WFS,
.external_trigger = (bool) true, /* external trigger enabled */
.trigger_signal = XMC_CCU_40_SR2,
.trigger_edge = XMC_VADC_TRIGGER_EDGE_ANY,
.gate_signal = XMC_VADC_REQ_GT_A,
.timer_mode = (bool) false /* no timer mode */
};

XMC_VADC_QUEUE_ENTRY_t g_queue_entry =
{
.channel_num = CHANNEL_NUMBER,
.refill_needed = true,
.generate_interrupt = true,
.external_trigger = true
};

/* CCU4 */
XMC_CCU4_SLICE_COMPARE_CONFIG_t g_timer_object =
{
.timer_mode = XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA,
.monoshot = true,
.shadow_xfer_clear = 0U,
.dither_timer_period = 0U,
.dither_duty_cycle = 0U,
.prescaler_mode = XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
.mcm_enable = 0U,
.prescaler_initval = 0U,
.float_limit = 0U,
.dither_limit = 0U,
.passive_level = XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
.timer_concatenation = 0U
};


/* CCU Slice Capture Initialization Data */
XMC_CCU4_SLICE_CAPTURE_CONFIG_t g_capture_object =
{
.fifo_enable = false,
.timer_clear_mode = XMC_CCU4_SLICE_TIMER_CLEAR_MODE_NEVER,
.same_event = false,
.ignore_full_flag = false,
.prescaler_mode = XMC_CCU4_SLICE_PRESCALER_MODE_NORMAL,
.prescaler_initval = 0,
.float_limit = 0,
.timer_concatenation = false
};



void ConifgureADC(void)
{
/* init VADC global registers */
XMC_VADC_GLOBAL_Init(VADC,&g_global_handle);

/* Configure a conversion kernel */
XMC_VADC_GROUP_Init(g_group_identifier, &g_group_handle);

/* Configure the queue request source of the aforsaid conversion kernel */
XMC_VADC_GROUP_QueueInit(g_group_identifier,&g_queue_handle);

/* Configure the channel belong to aforesaid conversion kernel */
XMC_VADC_GROUP_ChannelInit(g_group_identifier,CHANNEL_NUMBER,&g_channel_handle);

/* Conifgure a result resource belonging to the aforesaid conversion kernel */
XMC_VADC_GROUP_ResultInit(g_group_identifier, RES_REG_NUMBER, &g_result_handle);

/* Add the channel to the queue */
XMC_VADC_GROUP_QueueInsertChannel(g_group_identifier, g_queue_entry);


/* Connect RS Event to the NVICE nodes */
XMC_VADC_GROUP_QueueSetReqSrcEventInterruptNode(g_group_identifier, XMC_VADC_SR_GROUP_SR0);


/* Config the NVIC */
/* Set Priority */
NVIC_SetPriority(VADC0_G0_3_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_3_IRQn);


/* enabled the analog converters */
XMC_VADC_GROUP_SetPowerMode(g_group_identifier,XMC_VADC_GROUP_POWERMODE_NORMAL);

/* Perform calibration of the converter */
XMC_VADC_GLOBAL_StartupCalibration(VADC);
}


/* CCU4 */

XMC_CCU4_SLICE_EVENT_CONFIG_t config;

config.duration = XMC_CCU4_SLICE_EVENT_FILTER_5_CYCLES;
config.edge = XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_DUAL_EDGE;
config.level = XMC_CCU4_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_HIGH; /* Not needed */
config.mapped_input = XMC_CCU4_SLICE_INPUT_I;

/* Enable clock, enable prescaler block and configure global control */
XMC_CCU4_Init(MODULE_PTR, XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR);

/* Start the prescaler and restore clocks to slices */
XMC_CCU4_StartPrescaler(MODULE_PTR);

/* Ensure fCCU reaches CCU40 */
XMC_CCU4_SetModuleClock(MODULE_PTR, XMC_CCU4_CLOCK_SCU);

/* Initialize the Slice */
XMC_CCU4_SLICE_CompareInit(SLICE_PTR, &g_timer_object);

/* Set a duty cycle [33.3%] and frequency of [24kHz] */
XMC_CCU4_SLICE_SetTimerCompareMatch(SLICE_PTR,1777);
XMC_CCU4_SLICE_SetTimerPeriodMatch(SLICE_PTR, 2665U);

XMC_CCU4_SLICE_EnableEvent(SLICE_PTR, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
XMC_CCU4_SLICE_EnableEvent(SLICE_PTR, XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_UP);


/* Enable shadow transfer for PWM Slice */
XMC_CCU4_EnableShadowTransfer(MODULE_PTR,(uint32_t)XMC_CCU4_SHADOW_TRANSFER_SLICE_3);

/* Configure events -- Start */
/* Configure Event-1 and map it to Input-I */
XMC_CCU4_SLICE_ConfigureEvent(SLICE_PTR, XMC_CCU4_SLICE_EVENT_0, &config);

/* Map Event-1 to Start function */
XMC_CCU4_SLICE_StartConfig(SLICE_PTR, XMC_CCU4_SLICE_EVENT_0, XMC_CCU4_SLICE_START_MODE_TIMER_START_CLEAR);

/* Enable events */
XMC_CCU4_SLICE_EnableEvent(SLICE_PTR, XMC_CCU4_SLICE_IRQ_ID_EVENT0);

/* Connect the event to SR2, which is the ADC */
XMC_CCU4_SLICE_SetInterruptNode(SLICE_PTR,XMC_CCU4_SLICE_IRQ_ID_EVENT0,XMC_CCU4_SLICE_SR_ID_2);

/* Take SLICE out of idle mode */
XMC_CCU4_EnableClock(MODULE_PTR,SLICE_NUMBER);

XMC_SCU_SetCcuTriggerHigh(CAPCOM_MASK);

while(1);



}


Right after the XMC_SCU_SetCcuTriggerHigh(..) I'm expecting the interrupt to hit.

Again, any help would be really appreciated.

-Steve
0 Likes
9 Replies
Not applicable
no one? I know it's long...
0 Likes
Not applicable
Hi stv,

Could you please check if changing the enabled NVIC IRQ to VADC0_G0_0_IRQn will change anything?

	NVIC_SetPriority(VADC0_G0_0_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_0_IRQn);


Best regards,
Andrey
0 Likes
Not applicable
Hi Andrey,

I don't understand what you mean by changing the enabled NVIC IRQ. What would I change it to?
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi -Steve,

I believe Andrey meant that you should try to replace your code section:

NVIC_SetPriority(VADC0_G0_3_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_3_IRQn);


with the code he suggested:
	NVIC_SetPriority(VADC0_G0_0_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_0_IRQn);


of course, it would be best if Andrey could confirm my post 🙂

Regards,
Deni
0 Likes
Not applicable
Hi,

Basically the one thing that looks off is that you've enabled XMC_VADC_SR_GROUP_SR0 in the ADC configuration, but when you call NVIC_EnableIRQ, you give it the parameter VADC0_G0_3_IRQn, which will handle a service request on SR3 line. In other words, try calling the two NVIC APIs with VADC0_G0_0_IRQn instead of what you have right now.

What you have right now:


NVIC_SetPriority(VADC0_G0_3_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_3_IRQn);


What you can try changing it to:


NVIC_SetPriority(VADC0_G0_0_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_0_IRQn);


Best regards,
Andrey
0 Likes
Not applicable
Deni, It seems like we were writing the answer at the same time 🙂 You are right - this is exactly what I meant. Does that seem like this is what the issue is to you, too?
0 Likes
Not applicable
Thanks..

Ugh.. what a doof you are right.. Somehow when I looked at my code I saw it as
NVIC_SetPriority(VADC0_G0_0_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_0_IRQn);

I'll go back and change it... and let you know...

again.. thanks.!
0 Likes
Not applicable
No problem, it's often a fresh pair that helps in a lot of problems! Let us know if that fixed the problem.

Best regards,
Andrey
0 Likes
Not applicable
Did not work. I actually, for fun, enabled these IRQ's.. None of them hit.

/* Config the NVIC */
/* Set Priority */
NVIC_SetPriority(VADC0_G0_3_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_3_IRQn);

/* Set Priority */
NVIC_SetPriority(VADC0_G0_2_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_2_IRQn);

/* Set Priority */
NVIC_SetPriority(VADC0_G0_1_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_1_IRQn);

/* Set Priority */
NVIC_SetPriority(VADC0_G0_0_IRQn,IRQ_PRIORITY);
/* Enable */
NVIC_EnableIRQ(VADC0_G0_0_IRQn);
0 Likes