infineon4engineers Facebook

infineon@google+ Google+

infineon@linkedin linkedin

infineon4engi@twitter twitter

infineon@youtube youtube

+ Reply to Thread
Results 1 to 2 of 2

Thread: DMA transfer of ADC results to RAM

  1. #1
    New Member New Member tamirmichael is on a distinguished road
    Join Date
    May 2018
    Posts
    2
    Points
    37.5

    DMA transfer of ADC results to RAM

    Hello and thanks for taking the time to read this post,

    I am working with a XMC4500 and I need to trigger an ADC conversion + DMA transfer to RAM upon GPIO falling edge detection.
    The first part works fine: CCU8 triggers the ADC conversion, but I just don't seem to get the DMA transfer to work.
    Could you perhaps take a look at the code below - namely the functions configureDMA and configureADC - and tell me why my DMA transfers are never triggered? There are 2 buffers there to host up to 1024 ADC samples each. Otherwise it pretty standard code.
    Thanks in advance!

    Code:
    #define PICAN_PULSES                     (1024)
    #define DMA_BUFFER_SIZE                  (PICAN_PULSES * sizeof(U16))
    #define DMA_BUFFER_1_ADDRESS             (0x60100000)
    #define DMA_BUFFER_2_ADDRESS             (DMA_BUFFER_1_ADDRESS + DMA_BUFFER_SIZE)
    #define ADC_MEASUREMENT_TRANSFER_CHANNEL (1)
    #define ADC_MEASUREMENT_TRANSFER_GROUP   (0)
    #define SLICE_NUMBER                     (2)
    #define DMA_CHANNEL                      (0)
    #define ADC_RESULT_REGISTER              (1)
    
    // ADC
    const XMC_VADC_GLOBAL_CONFIG_t g_global_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
        }
    } ;
    
    /* VADC group data configuration. No configuration needed, standard values
     * are used. */
    const XMC_VADC_GROUP_CONFIG_t g_group_handle = {0};
    
    /* Data configuration for background source. */
    const XMC_VADC_BACKGROUND_CONFIG_t g_bgn_handle =
    {
        .conv_start_mode   = XMC_VADC_STARTMODE_WFS,
        .req_src_priority  = XMC_VADC_GROUP_RS_PRIORITY_3,
        .trigger_signal    = XMC_VADC_REQ_TR_K,
        .trigger_edge      = XMC_VADC_TRIGGER_EDGE_FALLING,
        .external_trigger  = true,
        .req_src_interrupt = false,
        .enable_auto_scan  = false,
        .load_mode         = XMC_VADC_SCAN_LOAD_OVERWRITE,
    } ;
    
    /* Channel data configuration. Channel does NOT use alias feature and uses
     * desired result register. */
    const XMC_VADC_CHANNEL_CONFIG_t g_g0_ch1_handle =
    {
        .alias_channel = XMC_VADC_CHANNEL_ALIAS_DISABLED,
        .result_reg_number = ADC_RESULT_REGISTER,
    } ;
    
    // DMA
    
    XMC_DMA_CH_CONFIG_t GPDMA0_Ch0_config =
    {
       .enable_interrupt = false, 																/* Interrupts enabled */
       .dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_16, 										/* Destination transfer width */
       .src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_16, 										/* Source transfer width */
       .dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, 						/* Destination address count mode */
       .src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE, 						/* Source address count mode */
       .dst_burst_length = XMC_DMA_CH_BURST_LENGTH_8, 											/* Destination burst length */
       .src_burst_length = XMC_DMA_CH_BURST_LENGTH_8, 											/* Source burst length */
       .enable_src_gather = false, 																/* Source gather enabled? */
       .enable_dst_scatter = false, 															/* Destination scatter enabled? */
       .transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_P2M_DMA, 										/* Transfer flow */
    
       .src_addr = (uint32_t) &VADC_G0->RES[ADC_RESULT_REGISTER],           					/* Source address */
       .dst_addr = (uint32_t) adc_results_buffer_1,         								    /* Destination address*/
       .linked_list_pointer = NULL,                                                             /* Linked list pointer */
    
       .src_gather_interval = 1,																/* Gather interval */
       .src_gather_count = 1,																	/* Gather count */
    
       .dst_scatter_interval = 0,																/* Scatter interval */
       .dst_scatter_count = 0,																	/* Scatter count*/
    
       .block_size = 1,																			/* Block size */
       .transfer_type = XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK, 		                            /* Transfer type */
       .priority = XMC_DMA_CH_PRIORITY_7, 														/* Priority level */
    
       .src_handshaking = XMC_DMA_CH_SRC_HANDSHAKING_HARDWARE, 									/* Source handshaking */
       .src_peripheral_request = DMA0_PERIPHERAL_REQUEST_VADC_G0SR2_1,
    };
    
    /* Result configuration data */
    XMC_VADC_RESULT_CONFIG_t adc_result_handle =
    {
    	.post_processing_mode   = XMC_VADC_DMM_REDUCTION_MODE,
        .data_reduction_control = 0,
        .part_of_fifo           = false, 	/* No FIFO */
        .wait_for_read_mode     = false, 	/* WFS */
        .event_gen_enable       = true  	/* No result event */
    };
    
    static void configureADC(void)
    {
        /* 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, ADC_MEASUREMENT_TRANSFER_CHANNEL, &g_g0_ch1_handle);
    
        /* Add a channel to the background source. */
        XMC_VADC_GLOBAL_BackgroundAddChannelToSequence(VADC, ADC_MEASUREMENT_TRANSFER_GROUP, ADC_MEASUREMENT_TRANSFER_CHANNEL);
    
        XMC_VADC_GLOBAL_ResultInit(VADC, &adc_result_handle) ;
        
        XMC_VADC_GROUP_SetResultInterruptNode(VADC_G0, ADC_RESULT_REGISTER, XMC_VADC_SR_GROUP_SR2) ;
    
        XMC_VADC_GROUP_EnableResultEvent(VADC_G0, ADC_RESULT_REGISTER) ;
        
        /* Disables autoscan feature for continuous conversion - conversion is triggered by a falling edge on P5.0 (PT_RX) */
        XMC_VADC_GLOBAL_BackgroundDisableContinuousMode(VADC) ;
    }
    //------------------------------------------------------------------------------------------------//
    static void configureDMA(void)
    {
        memset(adc_results_buffer_1, 0, sizeof(adc_results_buffer_1)) ;
        memset(adc_results_buffer_2, 0, sizeof(adc_results_buffer_2)) ;
        
        active_adc_results_buffer_ptr = adc_results_buffer_1 ;
        
        XMC_DMA_Init(XMC_DMA0);
    	XMC_DMA_CH_Init(XMC_DMA0, DMA_CHANNEL, &GPDMA0_Ch0_config);
    	XMC_DMA_CH_EnableEvent(XMC_DMA0, DMA_CHANNEL, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE);
    	XMC_DMA_CH_Enable(XMC_DMA0, DMA_CHANNEL);
    }

  2. #2
    New Member New Member tamirmichael is on a distinguished road
    Join Date
    May 2018
    Posts
    2
    Points
    37.5
    XMC_DMA_CH_BURST_LENGTH_8 -> XMC_DMA_CH_BURST_LENGTH_1

    .block_size = 1 -> .block_size = 1024

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