Continuous Mode
The example performs voltage detection by using the ADC in continuous sampling mode.
The example also includes configurable macros ADC_CONFIG_GDMA_MODE_EN
to control whether DMA is used for data handling.
If DMA handling is not enabled, the ADC_INT_FIFO_THD
interrupt is triggered after ADC sampling is complete, and within the interrupt function, raw data is read and voltage conversion calculations are performed.
If DMA handling is enabled, DMA handles the data from ADC FIFO to the array and triggers the GDMA_INT_Transfer
interrupt when the transfer is complete.
Requirements
The sample supports the following development kits:
Hardware Platforms |
Board Name |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
For more requirements, please refer to Quick Start.
Wiring
Connect P2_4 to external voltage input.
Configurations
The example configurable macros are as follows:
ADC_CONFIG_GDMA_MODE_EN
:select whether or not to use DMA for ADC sample data handling,1
indicates that DMA handling is used,0
indicates that DMA handling is not used.ADC_MODE_DIVIDE_OR_BYPASS
: selects the voltage sampling range of the ADC, and the selectable values are as follows:ADC_DIVIDE_MODE
:In Divide Mode, the ADC samples voltage values ranging from 0 to 3.3VADC_BYPASS_MODE
:In Bypass Mode, the ADC samples voltage values ranging from 0 to 0.9V
Building and Downloading
This sample can be found in the SDK folder:
Project file: samples\peripheral\adc\continuous_gdma\proj\rtl87x2g\mdk
Project file: samples\peripheral\adc\continuous_gdma\proj\rtl87x2g\gcc
To build and run the sample, follow the steps listed below:
Open sample project file.
To build the target, follow the steps listed on the Generating App Image in Quick Start.
After a successful compilation, the app bin
app_MP_xxx.bin
will be generated in the directorymdk\bin
orgcc\bin
.To download app bin into EVB board, follow the steps listed on the MP Tool Download in Quick Start.
Press reset button on EVB board and it will start running.
Experimental Verification
When the EVB starts, observe the following log within the Debug Analyzer.
Start ADC Continuous Mode test !
ADC Configurations:
If the ADC is configured as
ADC_DIVIDE_MODE
, print the following log.[ADC]ADC sample mode is divide mode !
If the ADC is configured as
ADC_BYPASS_MODE
, print the following log.[ADC]ADC sample mode is bypass mode !
After the ADC sampling is finished, the raw data collected and the converted voltage value will be printed in the Debug Analyzer. If the macro
ADC_CONFIG_GDMA_MODE_EN
is enabled, DMA interrupt information will be printed; if the macroADC_CONFIG_GDMA_MODE_EN
is not enabled, ADC interrupt information will be printed.[io_adc]io_adc_voltage_calculate: ADC rawdata_0 = xxx, voltage_0 = xxxmV [io_adc]io_adc_voltage_calculate: ADC rawdata_1 = xxx, voltage_1 = xxxmV ...
Code Overview
This chapter will be introduced according to the following several parts:
Peripheral initialization will be introduced in chapter Initialization .
Functional implementation after initialization will be introduced in chapter Functional Implementation .
Source Code Directory
Project Directory:
sdk\samples\peripheral\adc\continuous_gdma\proj
Source Code Directory:
sdk\samples\peripheral\adc\continuous_gdma\src
Source files are currently categorized into several groups as below.
└── Project: continuous_gdma
└── secure_only_app
└── Device includes startup code
├── startup_rtl.c
└── system_rtl.c
├── CMSIS includes CMSIS header files
├── CMSE Library Non-secure callable lib
├── Lib includes all binary symbol files that user application is built on
└── rtl87x2g_io.lib
├── Peripheral includes all peripheral drivers and module code used by the application
├── rtl_rcc.c
├── rtl_pinmux.c
├── rtl_gdma.c
└── rtl_adc.c
└── APP includes the ble_peripheral user application implementation
├── main_ns.c
└── io_adc.c
Initialization
The initialization process includes global_adc_init
, board_adc_init
, and driver_adc_init
If the macro ADC_CONFIG_GDMA_MODE_EN
is enabled, the initialization process should also include driver_gdma_adc_init
global_adc_init
contains the global settings.
Execute
ADC_CalibrationInit()
for ADC FT calibration.Initialize the receive buffer
ADC_Recv_Buffer
.
board_adc_init
contains the PAD settings.
Set pin as SW mode, PowerOn, internal Pull-None, disable output, output low level.
driver_adc_init
contains the initialization of ADC peripheral.
Enable PCC clock.
Config ADC sample channel, channel 0 of the ADC selects pin P2_4 of the ADC single-ended mode, the corresponding bitmap is 0x01.
If the macro
ADC_CONFIG_GDMA_MODE_EN
is enabled, it should configADC_WaterLevel
.Set
ADC_DataWriteToFifo
to ENABLE, SetADC_FifoThdLevel
.If configured as bypass mode, execute
ADC_BypassCmd()
to enable the high resistance mode of the corresponding channel.Config ADC interrupt.
If enabling the macro
ADC_CONFIG_GDMA_MODE_EN
, configureADC_INT_FIFO_RD_ERR
andADC_INT_FIFO_OVERFLOW
interrupts.If not enabling the macro
ADC_CONFIG_GDMA_MODE_EN
, configureADC_INT_FIFO_THD
interrupt.
RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
...
#if ADC_CONFIG_GDMA_MODE_EN
ADC_InitStruct.ADC_WaterLevel = 4;
#endif
ADC_InitStruct.ADC_DataWriteToFifo = ENABLE;
...
#if ADC_CONFIG_GDMA_MODE_EN
ADC_INTConfig(ADC, ADC_INT_FIFO_RD_ERR, ENABLE);
ADC_INTConfig(ADC, ADC_INT_FIFO_OVERFLOW, ENABLE);
#else
ADC_INTConfig(ADC, ADC_INT_FIFO_THD, ENABLE);
#endif
Note
In ADC Continuous mode, data is stored in the ADC FIFO by default.
driver_gdma_adc_init
contains the initialization of the GDMA peripheral.
GDMA transfer direction is peripheral to memory transfer.
Source address is set to ADC FIFO, destination address is set to
ADC_Recv_Buffer
.Set source address to fixed and destination address to increase.
Enable transmission completion interrupt
GDMA_INT_Transfer
.
GDMA_InitStruct.GDMA_DIR = GDMA_DIR_PeripheralToMemory;
GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Fix;
GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Inc;
GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)(&(ADC->ADC_FIFO_READ));
GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)ADC_Recv_Buffer;
...
GDMA_INTConfig(ADC_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE);
...
Functional Implementation
If enabling the macro
ADC_CONFIG_GDMA_MODE_EN
, executeGDMA_Cmd()
after initializing GDMA.Execute
ADC_ClearFIFO()
before ADC sampling to clear data in ADC FIFO.Execute
ADC_Cmd()
, start ADC sampling.If enabling the macro
ADC_CONFIG_GDMA_MODE_EN
, when the GDMA has finished handling the data, the GDMA_INT_Transfer interrupt is triggered, and the ADC_GDMA_Channel_Handler function is executed.Disable ADC continuous sampling mode.
Read ADC sample data. (Refer to 6)
Reset the GDMA information, including source address, destination address, and carry length.
Enable GDMA transfer, clear ADC FIFO, and enable ADC conversion.
void ADC_GDMA_Channel_Handler(void)
{
ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, DISABLE);
for (uint32_t i = 0; i < GDMA_TRANSFER_SIZE; i++)
{
...
}
GDMA_SetSourceAddress(ADC_GDMA_Channel, (uint32_t)(&(ADC->ADC_FIFO_READ)));
GDMA_SetDestinationAddress(ADC_GDMA_Channel, (uint32_t)(ADC_Recv_Buffer));
GDMA_SetBufferSize(ADC_GDMA_Channel, GDMA_TRANSFER_SIZE);
GDMA_ClearINTPendingBit(ADC_GDMA_CHANNEL_NUM, GDMA_INT_Transfer);
GDMA_Cmd(ADC_GDMA_CHANNEL_NUM, ENABLE);
ADC_ClearFIFO(ADC);
ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, ENABLE);
}
If not enabling the macro
ADC_CONFIG_GDMA_MODE_EN
, when the number of ADC FIFO exceeds the threshold value, trigger theADC_INT_FIFO_THD
interrupt and enter the interrupt handler function.Execute
ADC_GetFIFODataLen()
to read FIFO data length, executeADC_ReadFIFOData()
to read ADC FIFO data.Execute
ADC_ClearFIFO()
to clear ADC FIFO data.Execute
ADC_GetVoltage()
to calculate the sample voltage based on the sample data.
if (ADC_GetINTStatus(ADC, ADC_INT_FIFO_THD) == SET)
{
ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, DISABLE);
data_len = ADC_GetFIFODataLen(ADC);
ADC_ReadFIFOData(ADC, sample_data, data_len);
ADC_ClearFIFO(ADC);
...
ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, ENABLE);
}
Note
When ADC FIFO overflow triggers ADC_INT_FIFO_OVERFLOW
interrupt, enter the interrupt handling function SAR_ADC_Handler
, and clear ADC FIFO data.
Troubleshooting
If the IC obtained has not been verified by FT, the ADC will not be able to convert to the correct voltage value. The following message will be printed within the log tool.
[ADC]ADC_CalibrationInit fail!
If the ADC sample value is incorrect, print the error status.
[ADC]adc_sample_demo: ADC parameter or efuse data error! i = xxx, error_status = xxx