Quantcast
Channel: Infineon Forums
Viewing all articles
Browse latest Browse all 9892

Problems with synchronized ADC

$
0
0
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?!


Code:

/***************************************************************************
 * HEADER FILES
 **************************************************************************/
#include <xmc_vadc.h>
#include <xmc_ccu8.h>

/***************************************************************************
 * 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

Viewing all articles
Browse latest Browse all 9892


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>