ADC Continuous Mode

This sample code guide is designed to help users easily and comprehensively understand ADC sample. This sample demonstrates how ADC samples data in continuous mode with charger and discharger enabled. This sample uses continuous mode of the ADC peripheral to measure voltage on P0_0 with charger and discharger enabled.

Requirements

For hardware requirements, please refer to the Requirements.

Wiring

Connect P0_0 of EVB to an external DC voltage source. Input voltage of P0_0 must range from 0 to 3.3V.

Configurations

  1. The following macros can be configured to modify the sampling interval.

    • #define ADC_TIMER_PERIOD  2000

  2. The entry function is as follows, call this function in main() to run this sample code. For more details, please refer to the Initialization.

    adc_continuous_mode_demo();
    

Building and Downloading

For building and downloading, please refer to the Building and Downloading.

Experimental Verification

  1. Disconnect VADP and 5V of EVB, press the Reset button on the EVB. After initialization is complete, the ADC begins sampling. Once ADC sampling is finished, the raw data collected and the converted voltage values will be printed in Debug Analyzer.

    adc_dma_handler: adc_dma_buffer[xxx] xxx, result[xxx] xxx
    ...
    
  2. Connect VADP and 5V of EVB, ADC stops continuous sampling and the charger is enabled.

  3. Disconnect VADP and 5V of EVB, ADC starts continuous sampling and prints the raw data collected and the converted voltage values in Debug Analyzer.

    adc_dma_handler: adc_dma_buffer[xxx] xxx, result[xxx] xxx
    ...
    

Code Overview

This section introduces the code and process description for initialization and corresponding function implementation in the sample.

Note

To use the mode, please turn off Charger auto enable and Battery detection support on the MCUConfig Tool. As shown in Turn Off Charger on the MCUConfig Tool.

../../../_images/Turn_Off_Charger_on_the_McuConfig_Tool.jpg

Turn Off Charger on the MCUConfig Tool

Source Code Directory

  • For project directory, please refer to Source Code Directory.

  • Source code directory: sdk\src\sample\io_demo\adc\adc_continuous_mode\adc_continuous_mode_demo.c.

ADC Initialization

The initialization flow for peripherals can refer to Initialization Flow.

ADC continuous mode initialization flow is shown in the following figure.

../../../_images/ADC_Continuous_Sampling_by_DMA_Mode.png

ADC Continuous Mode Initialization Flow Chart

  1. Call adp_register_state_change_cb() to register ADP 5V callback.

  2. Call os_timer_create() to create a software timer.

  3. Call Pad_Config() and Pinmux_Config() to initialize the pin.

    static void board_adc_init(void)
    {
       Pad_Config(ADC_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
       Pinmux_Config(ADC_0, IDLE_MODE);
    }
    
  4. Call RCC_PeriphClockCmd() to enable the ADC clock and function.

  5. Initialize the ADC peripheral:

    1. Define the ADC_InitTypeDef type adc_init_struct, and call ADC_StructInit() to pre-fill adc_init_struct with default values.

    2. Modify the adc_init_struct parameters as needed. The ADC initialization parameter configuration is shown in the table below.

    3. Call ADC_Init() to initialize the ADC peripheral.

    ADC Initialization Parameters

    ADC Hardware Parameters

    Setting in the adc_init_struct Variables

    ADC

    Bit Map

    ADC_InitTypeDef::bitmap

    0x01

    Schedule Index

    ADC_InitTypeDef::schIndex

    Index 0 is set to EXT_SINGLE_ENDED(0).

    Burst Size

    ADC_InitTypeDef::adcBurstSize

    8

  6. Call ADC_INTConfig() to enable ADC FIFO read error interrupt ADC_INT_FIFO_RD_ERR.

  7. Call NVIC_Init() to enable NVIC of ADC.

GDMA Initialization

GDMA initialization flow is shown in the following figure.

../../../_images/ADC_Continuous_GDMA_Initialization_Flow_Chart.png

GDMA Initialization Flow Chart

  1. Call RCC_PeriphClockCmd() to enable the GDMA clock and function.

  2. Call GDMA_channel_request to request an unused GDMA channel.

  3. Initialize the GDMA peripheral:

    1. Define the GDMA_InitTypeDef type GDMA_InitStruct, and call GDMA_StructInit() to pre-fill GDMA_InitStruct with default values.

    2. Modify the GDMA_InitStruct parameters as needed. The GDMA initialization parameter configuration is shown in the table below.

    3. Call GDMA_Init() to initialize the GDMA peripheral.

    GDMA Initialization Parameters

    GDMA Hardware Parameters

    Setting in the GDMA_InitStruct Variables

    GDMA

    Channel Num

    GDMA_InitTypeDef::GDMA_ChannelNum

    ADC_DMA_CHANNEL_NUM

    Transfer Direction

    GDMA_InitTypeDef::GDMA_DIR

    GDMA_DIR_PeripheralToMemory

    Buffer Size

    GDMA_InitTypeDef::GDMA_BufferSize

    80

    Source Address Increment or Fix

    GDMA_InitTypeDef::GDMA_SourceInc

    DMA_SourceInc_Fix

    Destination Address Increment or Fix

    GDMA_InitTypeDef::GDMA_DestinationInc

    DMA_DestinationInc_Inc

    Source Data Size

    GDMA_InitTypeDef::GDMA_SourceDataSize

    GDMA_DataSize_HalfWord

    Destination Data Size

    GDMA_InitTypeDef::GDMA_DestinationDataSize

    GDMA_DataSize_HalfWord

    Source Burst Transaction Length

    GDMA_InitTypeDef::GDMA_SourceMsize

    GDMA_Msize_8

    Destination Burst Transaction Length

    GDMA_InitTypeDef::GDMA_DestinationMsize

    GDMA_Msize_8

    Source Address

    GDMA_InitTypeDef::GDMA_SourceAddr

    (uint32_t)(&(ADC->FIFO))

    Destination Address

    GDMA_InitTypeDef::GDMA_DestinationAddr

    (uint32_t)(&adc_dma_buffer[0])

    Source Handshake

    GDMA_InitTypeDef::GDMA_SourceHandshake

    GDMA_Handshake_ADC

  4. Call GDMA_INTConfig() to enable GDMA transfer complete interrupt GDMA_INT_Transfer.

  5. Call NVIC_Init() to enable NVIC of GDMA.

Functional Implementation

Enable ADC Contiunous Sampling

  1. Call GDMA_Cmd() to enable GDMA.

  2. Call ADC_Cmd() to enable ADC contiunous sampling.

ADP 5V Callback Handle

  1. If ADP plug in:

    1. Deinitialize ADC peripheral:

      1. Call os_timer_stop() to stop software timer.

      2. Call os_timer_stop() to delete software timer.

      3. Call RCC_PeriphClockCmd() to disable the ADC clock and function.

      4. Call Pinmux_Deinit() to deinitialize the pin.

      5. Call NVIC_Init() to disable NVIC of ADC.

      6. Call GDMA_Cmd() to disable GDMA.

      7. Call GDMA_channel_release() to release GDMA channel used by ADC continuous mode.

    2. Call adc_mgr_init() to initialize ADC manager module.

    3. Call charger_api_enable_charger() to enable charger.

  2. If ADP plug out:

    1. Call charger_api_disable_charger() to disable charger.

    2. Call adc_mgr_deinit() to close ADC manager module.

    3. Initialize software timer and ADC and GDMA, please refer to steps 2 to 14 of Source Code Directory.

ADC Interrupt Handle

When read the empty FIFO, ADC FIFO read error interrupt is triggered:

  1. Call ADC_GetIntFlagStatus() to check ADC_INT_FIFO_RD_ERR interrupt status flag.

  2. Call ADC_ClearINTPendingBit() to clear ADC_INT_FIFO_RD_ERR interrupt.

GDMA Interrupt Handle

When GDMA transfer is completed, transfer complete interrupt is triggered:

  1. Call GDMA_ClearINTPendingBit() to clear GDMA_INT_Transfer interrupt.

  2. Call ADC_Cmd() to disable ADC.

  3. Call GDMA_GetTransferLen() to get GDMA transfer data length.

  4. Call ADC_GetRes() to get conversion result.

  5. Call ADC_ClearFifo() to clear ADC FIFO.

  6. Call os_timer_start() to start software timer.

Software Timer Callback Handle

When the software timer expires, the software timer callback function will be executed:

  1. Call GDMA_SetDestinationAddress() to set GDMA transmission destination address.

  2. Call GDMA_Cmd() to enable GDMA.

  3. Call ADC_Cmd() to enable ADC contiunous sampling.