+ Reply to Thread
Results 1 to 2 of 2

Thread: Problems with synchronized ADC

  1. #1
    New Member New Member gera is on a distinguished road
    Join Date
    Nov 2016
    Posts
    2
    Points
    40

    Problems with synchronized ADC

    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. Its 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

  2. #2
    Beginner Beginner ADCGuy is on a distinguished road
    Join Date
    Jun 2017
    Posts
    7
    Points
    85
    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.

+ Reply to Thread

Tags for this Thread

Disclaimer

All content and materials on this site are provided as is. Infineon makes no warranties or representations with regard to this content and these materials of any kind, whether express or implied, including without limitation, warranties or representations of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, whether express or implied, is granted by Infineon. Use of the information on this site may require a license from a third party, or a license from Infineon.


Infineon accepts no liability for the content and materials on this site being accurate, complete or up- to-date or for the contents of external links. Infineon distances itself expressly from the contents of the linked pages, over the structure of which Infineon has no control.


Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Usage Terms of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Usage Terms of this site. Infineon reserves the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.