<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic K10 DMA getting ADC value only once. in Kinetis Microcontrollers</title>
    <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/K10-DMA-getting-ADC-value-only-once/m-p/1228165#M59568</link>
    <description>&lt;P&gt;I'm trying something relatively simple but it doesn't work right and I don't know why. I'm trying to create a little sample code with ADC0 measuring the internal chip temp using DMA.&lt;/P&gt;&lt;P&gt;I'm using the config tools for configuring the ADC and DMA. This is the ADC0 configuration in the generated &lt;STRONG&gt;peripherals.c&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;adc16_channel_config_t adc0_channelsConfig[2] = {
  {
    .channelNumber = 27U,
    .enableDifferentialConversion = false,
    .enableInterruptOnConversionCompleted = true,
  },
  {
    .channelNumber = 26U,
    .enableDifferentialConversion = false,
    .enableInterruptOnConversionCompleted = true,
  }
};
const adc16_config_t adc0_config = {
  .referenceVoltageSource = kADC16_ReferenceVoltageSourceVref,
  .clockSource = kADC16_ClockSourceAlt0,
  .enableAsynchronousClock = true,
  .clockDivider = kADC16_ClockDivider8,
  .resolution = kADC16_ResolutionSE16Bit,
  .longSampleMode = kADC16_LongSampleCycle24,
  .enableHighSpeed = true,
  .enableLowPower = false,
  .enableContinuousConversion = false
};
const adc16_channel_mux_mode_t adc0_muxMode = kADC16_ChannelMuxA;
const adc16_hardware_average_mode_t adc0_hardwareAverageMode = kADC16_HardwareAverageCount32;

static void adc0_init(void) {
  /* Initialize ADC16 converter */
  ADC16_Init(ADC0_PERIPHERAL, &amp;amp;adc0_config);
  /* Make sure, that hardware trigger is used */
  ADC16_EnableHardwareTrigger(ADC0_PERIPHERAL, true);
  /* Configure hardware average mode */
  ADC16_SetHardwareAverage(ADC0_PERIPHERAL, adc0_hardwareAverageMode);
  /* Configure channel multiplexing mode */
  ADC16_SetChannelMuxMode(ADC0_PERIPHERAL, adc0_muxMode);
  /* Perform auto calibration */
  ADC16_DoAutoCalibration(ADC0_PERIPHERAL);
  /* Enable DMA requests from ADC0 peripheral */
  ADC16_EnableDMA(ADC0_PERIPHERAL, true);
  /* Enable interrupt ADC0_IRQn request in the NVIC. */
  EnableIRQ(ADC0_IRQN);
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This is the DMA configuration in the generated &lt;STRONG&gt;peripherals.c&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;const edma_config_t dma_config = {
  .enableContinuousLinkMode = false,
  .enableHaltOnError = false,
  .enableRoundRobinArbitration = false,
  .enableDebugMode = false
};

  /* Channel adc0_coco global variables */
edma_handle_t dma_adc0_coco_Handle;

static void dma_init(void) {

  /* Channel adc0_coco initialization */
  /* Set the source kDmaRequestMux0ADC0 request in the DMAMUX */
  DMAMUX_SetSource(DMA_DMAMUX_BASEADDR, DMA_ADC0_COCO_DMA_CHANNEL, DMA_ADC0_COCO_DMA_REQUEST);
  /* Enable the channel 0 in the DMAMUX */
  DMAMUX_EnableChannel(DMA_DMAMUX_BASEADDR, DMA_ADC0_COCO_DMA_CHANNEL);
  /* Create the eDMA dma_adc0_coco_Handle handle */
  EDMA_CreateHandle(&amp;amp;dma_adc0_coco_Handle, DMA_DMA_BASEADDR, DMA_ADC0_COCO_DMA_CHANNEL);
  EDMA_SetCallback(&amp;amp;dma_adc0_coco_Handle, adc0_val_dma_transfed_done, NULL);
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And this is the LPTMR configuration&amp;nbsp;in the generated &lt;STRONG&gt;peripherals.c&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;const lptmr_config_t lptmr_config = {
  .timerMode = kLPTMR_TimerModeTimeCounter,
  .pinSelect = kLPTMR_PinSelectInput_0,
  .pinPolarity = kLPTMR_PinPolarityActiveHigh,
  .enableFreeRunning = false,
  .bypassPrescaler = true,
  .prescalerClockSource = kLPTMR_PrescalerClock_1,
  .value = kLPTMR_Prescale_Glitch_0
};

static void lptmr_init(void) {
  /* Initialize the LPTMR */
  LPTMR_Init(LPTMR_PERIPHERAL, &amp;amp;lptmr_config);
  /* Set LPTMR period */
  LPTMR_SetTimerPeriod(LPTMR_PERIPHERAL, LPTMR_TICKS);
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Then I have the following in &lt;STRONG&gt;main.c&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;#define ADCR_VDD               (65535U) /* Maximum value when use 16b resolution */
#define STANDARD_TEMP          (25U)
#define V_BG                   (1000U)  /* BANDGAP voltage in mV (from datasheet p13) */
#define V_TEMP25               (716U)   /* Typical VTEMP25 in mV (from the datasheet p45) */
#define M                      (1620U)  /* Typical slope: (mV x 1000)/oC (from the datasheet p45) */

volatile bool adc0_val_dma_transfer_rdy = false;

volatile static uint32_t adc0_val = 0;      /*! ADC value from DMA */
volatile static uint32_t adc0_val_int = 0;  /*! ADC value from ADC int */
volatile static bool adc0_val_rdy = false; /*! Conversion completed Flag */
volatile static uint32_t adcrTemp25 = 0;    /*! Calibrated ADCR_TEMP25 */
volatile static uint32_t adcr100m = 0;

/*!
 * @brief ADC0 Interrupt handler
 *
 * Get current ADC value and set adc0_conv_rdy flag.
 */
void ADC0_IRQHandler(void)
{
    /* Get current ADC value */
    adc0_val_int = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP);
    /* Set conversionCompleted flag. This prevents an wrong conversion in main function */
    adc0_val_rdy = true;
}

/* eDMA callback function for the 0 channel.*/
void adc0_val_dma_transfed_done(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
    if (transferDone)
    {
        adc0_val_dma_transfer_rdy = true;
        EDMA_StartTransfer(&amp;amp;dma_adc0_coco_Handle);
    }
}

static int32_t adc_get_chip_temp(void)
{
    if (adc0_val_dma_transfer_rdy)
    {
        adc0_val_dma_transfer_rdy = false;
        adc0_val_rdy = false;
        return (int32_t)(STANDARD_TEMP - ((int32_t)adc0_val - (int32_t)adcrTemp25) * 100 / (int32_t)adcr100m);
    }

    return -1000;
}

int main(void)
{
    int32_t die_temp = 0;

    /* Init board hardware. */
    BOARD_InitBootPins ();
    BOARD_InitBootClocks ();
    BOARD_InitBootPeripherals ();

    PRINTF("\n\n\n");
    PRINTF("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
    PRINTF("┃      MK10DN512VLQ10 Started      ┃\n");
    PRINTF("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");

    if (kRCM_SourceWdog == RCM_GetPreviousResetSources(RCM))
    {
        PRINTF("\n\e[3;5;93mThe processor has been reset %u times by the WDOG\e[0m\n\n",
               WDOG_GetResetCount(WATCHDOG_PERIPHERAL));
    }

    /*********************************************************************
     *                      Configure the DMA
     *********************************************************************/
    edma_transfer_config_t transferConfig_ch0;

    EDMA_PrepareTransfer(&amp;amp;transferConfig_ch0,       /* Prepare TCD for CH0 */
                         (uint32_t*) (ADC0-&amp;gt;R),     /* Source Address (ADC0_RA) */
                         sizeof(uint32_t),          /* Source width (2 bytes) */
                         (uint32_t*)&amp;amp;adc0_val,      /* Destination Address (Internal buffer)*/
                         sizeof(uint32_t),          /* Destination width */
                         sizeof(uint32_t),          /* Bytes to transfer each minor loop */
                         sizeof(uint32_t),          /* Total of bytes to transfer */
                         kEDMA_PeripheralToMemory); /* From ADC to Memory */

    /* Push TCD for CH1 into hardware TCD Register */
    EDMA_SubmitTransfer(&amp;amp;dma_adc0_coco_Handle, &amp;amp;transferConfig_ch0);

    EDMA_StartTransfer(&amp;amp;dma_adc0_coco_Handle);

    /*********************************************************************
     *            Start the LPTimer to start ADC measurements.
     *********************************************************************/
    LPTMR_StartTimer(LPTMR_PERIPHERAL);

    /*********************************************************************
     *           Read bandgap for internal temp measurements.
     *********************************************************************/
    uint32_t adcr_bg = 0; /*! ADC value of BANDGAP */
    uint32_t vdd = 0;     /*! VDD in mV */
    pmc_bandgap_buffer_config_t pmcBandgapConfig;

    pmcBandgapConfig.enable = true;
    PMC_ConfigureBandgapBuffer(PMC, &amp;amp;pmcBandgapConfig);

    /* Set the channel to convert by ADC0 to bandgap */
    ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &amp;amp;adc0_channelsConfig[0]);

    /* Wait for the conversion to be done */
    //WDOG_Refresh(WATCHDOG_PERIPHERAL);
    while (!adc0_val_dma_transfer_rdy);

    /* Clear the flag */
    adc0_val_dma_transfer_rdy = false;
    adc0_val_rdy = false;

    /* Get current ADC BANDGAP value */
    adcr_bg = adc0_val;

    /* Get VREFH value measured in mV: VREFH = (ADCR_VDD x V_BG) / ADCR_BG
     * (Eqn. 3, AN3031, p9) */
    vdd = ADCR_VDD * V_BG / adcr_bg;

    /* Calibrate ADCR_TEMP25: ADCR_TEMP25 = ADCR_VDD x V_TEMP25 / VDD
     * (AN3031, @bottom of p10) */
    adcrTemp25 = ADCR_VDD * V_TEMP25 / vdd;

    /* ADCR_100M = ADCR_VDD x M x 100 / VDD
     * (Eqn.7, AN3031, p11) */
    adcr100m = (ADCR_VDD * M) / (vdd * 10);

    /* Disable BANDGAP reference voltage */
    pmcBandgapConfig.enable = false;
    PMC_ConfigureBandgapBuffer(PMC, &amp;amp;pmcBandgapConfig);

    /* Now set the channel to convert by AC0 to internal temp sensor */
    ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &amp;amp;adc0_channelsConfig[1]);

    //WDOG_Refresh(WATCHDOG_PERIPHERAL);
    while (1)
    {
        if ((die_temp = adc_get_chip_temp()) != -1000)
        {
            PRINTF("\e[92mDie Temperature = %ld °C\e[0m\n", die_temp);
        }

        PRINTF("\e[1F");

        //WDOG_Refresh(WATCHDOG_PERIPHERAL);
    }

    return 0;
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;When I debug the project and place a breakpoint on the&amp;nbsp;&lt;STRONG&gt;adc0_val_dma_transfer_rdy = false;&lt;/STRONG&gt; line right below the&amp;nbsp;&lt;STRONG&gt;while (!adc0_val_dma_transfer_rdy);&lt;/STRONG&gt; line, I see that the correct value for the bandgap is present in&amp;nbsp;&lt;EM&gt;&lt;STRONG&gt;adc0_val.&amp;nbsp;&lt;/STRONG&gt;&lt;/EM&gt;But then when I get to the&amp;nbsp;&lt;STRONG&gt;adc_get_chip_temp()&lt;/STRONG&gt; call, I see that the value for&amp;nbsp;&lt;EM&gt;&lt;STRONG&gt;adc0_val&amp;nbsp;&lt;/STRONG&gt;&lt;/EM&gt;is the same that the one for the bandgap channel despite having changed the channel to the temp sensor.&lt;/P&gt;&lt;P&gt;If fact, this value doesn't change at all even when the EDMA transfer done interrupt is being generated. In other words, the&amp;nbsp;&lt;STRONG&gt;adc0_val_dma_transfed_done&lt;/STRONG&gt; callback is being called correctly but the value in&amp;nbsp;&lt;EM&gt;&lt;STRONG&gt;adc0_val&amp;nbsp;&lt;/STRONG&gt;&lt;/EM&gt;is not updated at all. It keeps the very first value obtained the very first time&amp;nbsp;&lt;STRONG&gt;adc0_val_dma_transfed_done &lt;/STRONG&gt;is called.&lt;/P&gt;&lt;P&gt;What's happening? Isn't the value supposed to be updated every time the DMA transfer done callback &lt;EM&gt;(&lt;STRONG&gt;adc0_val_dma_transfed_done&lt;/STRONG&gt;)&lt;/EM&gt; is called?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;EDIT:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;I found out that if I run this:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    edma_transfer_config_t transferConfig_ch0;

    EDMA_PrepareTransfer(&amp;amp;transferConfig_ch0,       /* Prepare TCD for CH0 */
                         (uint32_t*) (ADC0-&amp;gt;R),     /* Source Address (ADC0_RA) */
                         sizeof(uint32_t),          /* Source width (2 bytes) */
                         (uint32_t*)&amp;amp;adc0_val,      /* Destination Address (Internal buffer)*/
                         sizeof(uint32_t),          /* Destination width (2 bytes) */
                         sizeof(uint32_t),          /* Bytes to transfer each minor loop (2 bytes) */
                         sizeof(uint32_t),          /* Total of bytes to transfer (12*2 bytes) */
                         kEDMA_PeripheralToMemory); /* From ADC to Memory */

    /* Push TCD for CH1 into hardware TCD Register */
    EDMA_SubmitTransfer(&amp;amp;dma_adc0_coco_Handle, &amp;amp;transferConfig_ch0);

    EDMA_StartTransfer(&amp;amp;dma_adc0_coco_Handle);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Every time a DMA transfer is complete everything works fine. But this seems highly inefficient and unnecessary. Or is that how it works? do I have to "&lt;STRONG&gt;Prepare the Transfer&lt;/STRONG&gt;", "&lt;STRONG&gt;Submit the Transfer&lt;/STRONG&gt;", and "&lt;STRONG&gt;Start the Transfer&lt;/STRONG&gt;" every time a DMA transfer is complete? That seems awful!&lt;/P&gt;&lt;P&gt;Of what am I doing wrong?&lt;/P&gt;</description>
    <pubDate>Mon, 08 Feb 2021 20:47:44 GMT</pubDate>
    <dc:creator>m4l490n</dc:creator>
    <dc:date>2021-02-08T20:47:44Z</dc:date>
    <item>
      <title>K10 DMA getting ADC value only once.</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/K10-DMA-getting-ADC-value-only-once/m-p/1228165#M59568</link>
      <description>&lt;P&gt;I'm trying something relatively simple but it doesn't work right and I don't know why. I'm trying to create a little sample code with ADC0 measuring the internal chip temp using DMA.&lt;/P&gt;&lt;P&gt;I'm using the config tools for configuring the ADC and DMA. This is the ADC0 configuration in the generated &lt;STRONG&gt;peripherals.c&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;adc16_channel_config_t adc0_channelsConfig[2] = {
  {
    .channelNumber = 27U,
    .enableDifferentialConversion = false,
    .enableInterruptOnConversionCompleted = true,
  },
  {
    .channelNumber = 26U,
    .enableDifferentialConversion = false,
    .enableInterruptOnConversionCompleted = true,
  }
};
const adc16_config_t adc0_config = {
  .referenceVoltageSource = kADC16_ReferenceVoltageSourceVref,
  .clockSource = kADC16_ClockSourceAlt0,
  .enableAsynchronousClock = true,
  .clockDivider = kADC16_ClockDivider8,
  .resolution = kADC16_ResolutionSE16Bit,
  .longSampleMode = kADC16_LongSampleCycle24,
  .enableHighSpeed = true,
  .enableLowPower = false,
  .enableContinuousConversion = false
};
const adc16_channel_mux_mode_t adc0_muxMode = kADC16_ChannelMuxA;
const adc16_hardware_average_mode_t adc0_hardwareAverageMode = kADC16_HardwareAverageCount32;

static void adc0_init(void) {
  /* Initialize ADC16 converter */
  ADC16_Init(ADC0_PERIPHERAL, &amp;amp;adc0_config);
  /* Make sure, that hardware trigger is used */
  ADC16_EnableHardwareTrigger(ADC0_PERIPHERAL, true);
  /* Configure hardware average mode */
  ADC16_SetHardwareAverage(ADC0_PERIPHERAL, adc0_hardwareAverageMode);
  /* Configure channel multiplexing mode */
  ADC16_SetChannelMuxMode(ADC0_PERIPHERAL, adc0_muxMode);
  /* Perform auto calibration */
  ADC16_DoAutoCalibration(ADC0_PERIPHERAL);
  /* Enable DMA requests from ADC0 peripheral */
  ADC16_EnableDMA(ADC0_PERIPHERAL, true);
  /* Enable interrupt ADC0_IRQn request in the NVIC. */
  EnableIRQ(ADC0_IRQN);
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This is the DMA configuration in the generated &lt;STRONG&gt;peripherals.c&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;const edma_config_t dma_config = {
  .enableContinuousLinkMode = false,
  .enableHaltOnError = false,
  .enableRoundRobinArbitration = false,
  .enableDebugMode = false
};

  /* Channel adc0_coco global variables */
edma_handle_t dma_adc0_coco_Handle;

static void dma_init(void) {

  /* Channel adc0_coco initialization */
  /* Set the source kDmaRequestMux0ADC0 request in the DMAMUX */
  DMAMUX_SetSource(DMA_DMAMUX_BASEADDR, DMA_ADC0_COCO_DMA_CHANNEL, DMA_ADC0_COCO_DMA_REQUEST);
  /* Enable the channel 0 in the DMAMUX */
  DMAMUX_EnableChannel(DMA_DMAMUX_BASEADDR, DMA_ADC0_COCO_DMA_CHANNEL);
  /* Create the eDMA dma_adc0_coco_Handle handle */
  EDMA_CreateHandle(&amp;amp;dma_adc0_coco_Handle, DMA_DMA_BASEADDR, DMA_ADC0_COCO_DMA_CHANNEL);
  EDMA_SetCallback(&amp;amp;dma_adc0_coco_Handle, adc0_val_dma_transfed_done, NULL);
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And this is the LPTMR configuration&amp;nbsp;in the generated &lt;STRONG&gt;peripherals.c&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;const lptmr_config_t lptmr_config = {
  .timerMode = kLPTMR_TimerModeTimeCounter,
  .pinSelect = kLPTMR_PinSelectInput_0,
  .pinPolarity = kLPTMR_PinPolarityActiveHigh,
  .enableFreeRunning = false,
  .bypassPrescaler = true,
  .prescalerClockSource = kLPTMR_PrescalerClock_1,
  .value = kLPTMR_Prescale_Glitch_0
};

static void lptmr_init(void) {
  /* Initialize the LPTMR */
  LPTMR_Init(LPTMR_PERIPHERAL, &amp;amp;lptmr_config);
  /* Set LPTMR period */
  LPTMR_SetTimerPeriod(LPTMR_PERIPHERAL, LPTMR_TICKS);
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Then I have the following in &lt;STRONG&gt;main.c&lt;/STRONG&gt;:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;#define ADCR_VDD               (65535U) /* Maximum value when use 16b resolution */
#define STANDARD_TEMP          (25U)
#define V_BG                   (1000U)  /* BANDGAP voltage in mV (from datasheet p13) */
#define V_TEMP25               (716U)   /* Typical VTEMP25 in mV (from the datasheet p45) */
#define M                      (1620U)  /* Typical slope: (mV x 1000)/oC (from the datasheet p45) */

volatile bool adc0_val_dma_transfer_rdy = false;

volatile static uint32_t adc0_val = 0;      /*! ADC value from DMA */
volatile static uint32_t adc0_val_int = 0;  /*! ADC value from ADC int */
volatile static bool adc0_val_rdy = false; /*! Conversion completed Flag */
volatile static uint32_t adcrTemp25 = 0;    /*! Calibrated ADCR_TEMP25 */
volatile static uint32_t adcr100m = 0;

/*!
 * @brief ADC0 Interrupt handler
 *
 * Get current ADC value and set adc0_conv_rdy flag.
 */
void ADC0_IRQHandler(void)
{
    /* Get current ADC value */
    adc0_val_int = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP);
    /* Set conversionCompleted flag. This prevents an wrong conversion in main function */
    adc0_val_rdy = true;
}

/* eDMA callback function for the 0 channel.*/
void adc0_val_dma_transfed_done(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
    if (transferDone)
    {
        adc0_val_dma_transfer_rdy = true;
        EDMA_StartTransfer(&amp;amp;dma_adc0_coco_Handle);
    }
}

static int32_t adc_get_chip_temp(void)
{
    if (adc0_val_dma_transfer_rdy)
    {
        adc0_val_dma_transfer_rdy = false;
        adc0_val_rdy = false;
        return (int32_t)(STANDARD_TEMP - ((int32_t)adc0_val - (int32_t)adcrTemp25) * 100 / (int32_t)adcr100m);
    }

    return -1000;
}

int main(void)
{
    int32_t die_temp = 0;

    /* Init board hardware. */
    BOARD_InitBootPins ();
    BOARD_InitBootClocks ();
    BOARD_InitBootPeripherals ();

    PRINTF("\n\n\n");
    PRINTF("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
    PRINTF("┃      MK10DN512VLQ10 Started      ┃\n");
    PRINTF("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");

    if (kRCM_SourceWdog == RCM_GetPreviousResetSources(RCM))
    {
        PRINTF("\n\e[3;5;93mThe processor has been reset %u times by the WDOG\e[0m\n\n",
               WDOG_GetResetCount(WATCHDOG_PERIPHERAL));
    }

    /*********************************************************************
     *                      Configure the DMA
     *********************************************************************/
    edma_transfer_config_t transferConfig_ch0;

    EDMA_PrepareTransfer(&amp;amp;transferConfig_ch0,       /* Prepare TCD for CH0 */
                         (uint32_t*) (ADC0-&amp;gt;R),     /* Source Address (ADC0_RA) */
                         sizeof(uint32_t),          /* Source width (2 bytes) */
                         (uint32_t*)&amp;amp;adc0_val,      /* Destination Address (Internal buffer)*/
                         sizeof(uint32_t),          /* Destination width */
                         sizeof(uint32_t),          /* Bytes to transfer each minor loop */
                         sizeof(uint32_t),          /* Total of bytes to transfer */
                         kEDMA_PeripheralToMemory); /* From ADC to Memory */

    /* Push TCD for CH1 into hardware TCD Register */
    EDMA_SubmitTransfer(&amp;amp;dma_adc0_coco_Handle, &amp;amp;transferConfig_ch0);

    EDMA_StartTransfer(&amp;amp;dma_adc0_coco_Handle);

    /*********************************************************************
     *            Start the LPTimer to start ADC measurements.
     *********************************************************************/
    LPTMR_StartTimer(LPTMR_PERIPHERAL);

    /*********************************************************************
     *           Read bandgap for internal temp measurements.
     *********************************************************************/
    uint32_t adcr_bg = 0; /*! ADC value of BANDGAP */
    uint32_t vdd = 0;     /*! VDD in mV */
    pmc_bandgap_buffer_config_t pmcBandgapConfig;

    pmcBandgapConfig.enable = true;
    PMC_ConfigureBandgapBuffer(PMC, &amp;amp;pmcBandgapConfig);

    /* Set the channel to convert by ADC0 to bandgap */
    ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &amp;amp;adc0_channelsConfig[0]);

    /* Wait for the conversion to be done */
    //WDOG_Refresh(WATCHDOG_PERIPHERAL);
    while (!adc0_val_dma_transfer_rdy);

    /* Clear the flag */
    adc0_val_dma_transfer_rdy = false;
    adc0_val_rdy = false;

    /* Get current ADC BANDGAP value */
    adcr_bg = adc0_val;

    /* Get VREFH value measured in mV: VREFH = (ADCR_VDD x V_BG) / ADCR_BG
     * (Eqn. 3, AN3031, p9) */
    vdd = ADCR_VDD * V_BG / adcr_bg;

    /* Calibrate ADCR_TEMP25: ADCR_TEMP25 = ADCR_VDD x V_TEMP25 / VDD
     * (AN3031, @bottom of p10) */
    adcrTemp25 = ADCR_VDD * V_TEMP25 / vdd;

    /* ADCR_100M = ADCR_VDD x M x 100 / VDD
     * (Eqn.7, AN3031, p11) */
    adcr100m = (ADCR_VDD * M) / (vdd * 10);

    /* Disable BANDGAP reference voltage */
    pmcBandgapConfig.enable = false;
    PMC_ConfigureBandgapBuffer(PMC, &amp;amp;pmcBandgapConfig);

    /* Now set the channel to convert by AC0 to internal temp sensor */
    ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &amp;amp;adc0_channelsConfig[1]);

    //WDOG_Refresh(WATCHDOG_PERIPHERAL);
    while (1)
    {
        if ((die_temp = adc_get_chip_temp()) != -1000)
        {
            PRINTF("\e[92mDie Temperature = %ld °C\e[0m\n", die_temp);
        }

        PRINTF("\e[1F");

        //WDOG_Refresh(WATCHDOG_PERIPHERAL);
    }

    return 0;
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;When I debug the project and place a breakpoint on the&amp;nbsp;&lt;STRONG&gt;adc0_val_dma_transfer_rdy = false;&lt;/STRONG&gt; line right below the&amp;nbsp;&lt;STRONG&gt;while (!adc0_val_dma_transfer_rdy);&lt;/STRONG&gt; line, I see that the correct value for the bandgap is present in&amp;nbsp;&lt;EM&gt;&lt;STRONG&gt;adc0_val.&amp;nbsp;&lt;/STRONG&gt;&lt;/EM&gt;But then when I get to the&amp;nbsp;&lt;STRONG&gt;adc_get_chip_temp()&lt;/STRONG&gt; call, I see that the value for&amp;nbsp;&lt;EM&gt;&lt;STRONG&gt;adc0_val&amp;nbsp;&lt;/STRONG&gt;&lt;/EM&gt;is the same that the one for the bandgap channel despite having changed the channel to the temp sensor.&lt;/P&gt;&lt;P&gt;If fact, this value doesn't change at all even when the EDMA transfer done interrupt is being generated. In other words, the&amp;nbsp;&lt;STRONG&gt;adc0_val_dma_transfed_done&lt;/STRONG&gt; callback is being called correctly but the value in&amp;nbsp;&lt;EM&gt;&lt;STRONG&gt;adc0_val&amp;nbsp;&lt;/STRONG&gt;&lt;/EM&gt;is not updated at all. It keeps the very first value obtained the very first time&amp;nbsp;&lt;STRONG&gt;adc0_val_dma_transfed_done &lt;/STRONG&gt;is called.&lt;/P&gt;&lt;P&gt;What's happening? Isn't the value supposed to be updated every time the DMA transfer done callback &lt;EM&gt;(&lt;STRONG&gt;adc0_val_dma_transfed_done&lt;/STRONG&gt;)&lt;/EM&gt; is called?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;EDIT:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;I found out that if I run this:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    edma_transfer_config_t transferConfig_ch0;

    EDMA_PrepareTransfer(&amp;amp;transferConfig_ch0,       /* Prepare TCD for CH0 */
                         (uint32_t*) (ADC0-&amp;gt;R),     /* Source Address (ADC0_RA) */
                         sizeof(uint32_t),          /* Source width (2 bytes) */
                         (uint32_t*)&amp;amp;adc0_val,      /* Destination Address (Internal buffer)*/
                         sizeof(uint32_t),          /* Destination width (2 bytes) */
                         sizeof(uint32_t),          /* Bytes to transfer each minor loop (2 bytes) */
                         sizeof(uint32_t),          /* Total of bytes to transfer (12*2 bytes) */
                         kEDMA_PeripheralToMemory); /* From ADC to Memory */

    /* Push TCD for CH1 into hardware TCD Register */
    EDMA_SubmitTransfer(&amp;amp;dma_adc0_coco_Handle, &amp;amp;transferConfig_ch0);

    EDMA_StartTransfer(&amp;amp;dma_adc0_coco_Handle);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Every time a DMA transfer is complete everything works fine. But this seems highly inefficient and unnecessary. Or is that how it works? do I have to "&lt;STRONG&gt;Prepare the Transfer&lt;/STRONG&gt;", "&lt;STRONG&gt;Submit the Transfer&lt;/STRONG&gt;", and "&lt;STRONG&gt;Start the Transfer&lt;/STRONG&gt;" every time a DMA transfer is complete? That seems awful!&lt;/P&gt;&lt;P&gt;Of what am I doing wrong?&lt;/P&gt;</description>
      <pubDate>Mon, 08 Feb 2021 20:47:44 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/K10-DMA-getting-ADC-value-only-once/m-p/1228165#M59568</guid>
      <dc:creator>m4l490n</dc:creator>
      <dc:date>2021-02-08T20:47:44Z</dc:date>
    </item>
    <item>
      <title>Re: K10 DMA getting ADC value only once.</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/K10-DMA-getting-ADC-value-only-once/m-p/1269637#M60420</link>
      <description>&lt;P&gt;Please refer to frdmk64f_adc16_continuous_edma demo.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Regards&lt;/P&gt;
&lt;P&gt;Daniel&lt;/P&gt;</description>
      <pubDate>Wed, 28 Apr 2021 12:20:58 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/K10-DMA-getting-ADC-value-only-once/m-p/1269637#M60420</guid>
      <dc:creator>danielchen</dc:creator>
      <dc:date>2021-04-28T12:20:58Z</dc:date>
    </item>
  </channel>
</rss>

