aboutsummaryrefslogtreecommitdiff
path: root/src/sample/io_sample/ADC/ContinuousMode/io_adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sample/io_sample/ADC/ContinuousMode/io_adc.c')
-rw-r--r--src/sample/io_sample/ADC/ContinuousMode/io_adc.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/src/sample/io_sample/ADC/ContinuousMode/io_adc.c b/src/sample/io_sample/ADC/ContinuousMode/io_adc.c
new file mode 100644
index 0000000..49e1c61
--- /dev/null
+++ b/src/sample/io_sample/ADC/ContinuousMode/io_adc.c
@@ -0,0 +1,200 @@
+/**
+*********************************************************************************************************
+* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
+*********************************************************************************************************
+* @file io_adc.c
+* @brief This file provides demo code of adc continuous mode.
+* @details
+* @author yuan
+* @date 2018-12-07
+* @version v1.0
+*********************************************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "io_adc.h"
+
+#include "app_task.h"
+
+/* Globals ------------------------------------------------------------------*/
+ADC_Data_TypeDef ADC_Global_Data;
+
+/**
+ * @brief Initialization adc global data.
+ * @param No parameter.
+ * @return void
+ */
+void global_data_adc_init(void)
+{
+ /* Initialize adc k value! */
+ APP_PRINT_INFO0("[io_adc] global_data_adc_init");
+ bool adc_k_status = false;
+ adc_k_status = ADC_CalibrationInit();
+ if (false == adc_k_status)
+ {
+ APP_PRINT_ERROR0("[io_adc] global_data_adc_init: ADC_CalibrationInit fail!");
+ }
+ memset(&ADC_Global_Data, 0, sizeof(ADC_Global_Data));
+}
+
+/**
+ * @brief Initialization of pinmux settings and pad settings.
+ * @param No parameter.
+ * @return void
+*/
+void board_adc_init(void)
+{
+ Pad_Config(ADC_SAMPLE_PIN_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+ Pad_Config(ADC_SAMPLE_PIN_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
+ PAD_OUT_LOW);
+}
+
+/**
+ * @brief Initialize ADC peripheral.
+ * @param No parameter.
+ * @return void
+ */
+void driver_adc_init(void)
+{
+ RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
+
+ ADC_InitTypeDef ADC_InitStruct;
+ ADC_StructInit(&ADC_InitStruct);
+ /* Configure the ADC sampling schedule, a schedule represents an ADC channel data,
+ up to 16, i.e. schIndex[0] ~ schIndex[15] */
+ ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_0);
+ ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL_1);
+ /* Set the bitmap corresponding to schedule, 15 bits, LSB,
+ schIndex[0-15] corresponding to 16 bits of bitmap bit0-bit15.
+ For example, if config schIndex[0] and schIndex [1], then bitmap is 0000 0000 0011 (that is, 0x0003);
+ if config schIndex [0] and schIndex [2], then bitmap is 0000 0000 0101 (that is, 0x0005).
+ */
+ ADC_InitStruct.ADC_Bitmap = 0x03;
+ ADC_InitStruct.ADC_SampleTime = ADC_CONTINUOUS_SAMPLE_PERIOD;
+ /* Configure the interrupt of ADC_INT_FIFO_TH threshold value. */
+ ADC_InitStruct.ADC_FifoThdLevel = 16;
+ ADC_Init(ADC, &ADC_InitStruct);
+
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ /* High bypass resistance mode config, please notice that the input voltage of
+ adc channel using high bypass mode should not be over 0.9V */
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, ENABLE);
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_1, ENABLE);
+ APP_PRINT_INFO0("[ADC] ADC sample mode is bypass mode !");
+#else
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_0, DISABLE);
+ ADC_BypassCmd(ADC_SAMPLE_CHANNEL_1, DISABLE);
+ APP_PRINT_INFO0("[ADC] ADC sample mode is divide mode !");
+#endif
+
+ ADC_INTConfig(ADC, ADC_INT_FIFO_THD, ENABLE);
+
+ NVIC_InitTypeDef NVIC_InitStruct;
+ NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;
+ NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
+ NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStruct);
+ /* When ADC is enabled, sampling will be done quickly and interruption will occur.
+ After initialization, ADC can be enabled when sampling is needed.*/
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, ENABLE);
+}
+
+/**
+ * @brief Calculate adc sample voltage.
+ * @param No parameter.
+ * @return void
+ */
+static void io_adc_voltage_calculate(T_IO_MSG *io_adc_msg)
+{
+ uint8_t sample_data_len = 0;
+ uint16_t sample_data[ADC_FIFO_MAX] = {0};
+ float sample_voltage[ADC_FIFO_MAX] = {0};
+ ADC_ErrorStatus error_status = NO_ERROR;
+
+ uint16_t *p_buf = io_adc_msg->u.buf;
+
+ sample_data_len = p_buf[0];
+ for (uint8_t i = 0; i < sample_data_len; i++)
+ {
+ sample_data[i] = p_buf[i + 1];
+ }
+ for (uint8_t i = 0; i < sample_data_len; i++)
+ {
+#if (ADC_MODE_DIVIDE_OR_BYPASS == ADC_BYPASS_MODE)
+ sample_voltage[i] = ADC_GetVoltage(BYPASS_SINGLE_MODE, (int32_t)sample_data[i], &error_status);
+#else
+ sample_voltage[i] = ADC_GetVoltage(DIVIDE_SINGLE_MODE, (int32_t)sample_data[i], &error_status);
+#endif
+ if (error_status < 0)
+ {
+ APP_PRINT_INFO2("[io_adc] io_adc_voltage_calculate: ADC parameter or efuse data error! i = %d, error_status = %d",
+ i, error_status);
+ }
+ else
+ {
+ APP_PRINT_INFO4("[io_adc] io_adc_voltage_calculate: ADC rawdata_%-4d = %d, voltage_%-4d = %dmV ", i,
+ sample_data[i], i, (uint32_t)sample_voltage[i]);
+
+ }
+ }
+ memset(&ADC_Global_Data, 0, sizeof(ADC_Global_Data));
+ for (uint32_t i = 0; i < 1000000; i++);
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, ENABLE);
+}
+
+/**
+ * @brief Handle adc data function.
+ * @param No parameter.
+ * @return void
+ */
+void io_handle_adc_msg(T_IO_MSG *io_adc_msg)
+{
+ io_adc_voltage_calculate(io_adc_msg);
+}
+
+/**
+ * @brief ADC interrupt handler function.
+ * @param No parameter.
+ * @return void
+ */
+void ADC_Handler(void)
+{
+ uint8_t data_len = 0;
+ uint16_t sample_data[ADC_FIFO_MAX] = {0};
+
+ if (ADC_GetINTStatus(ADC, ADC_INT_FIFO_THD) == SET)
+ {
+ ADC_Cmd(ADC, ADC_CONTINUOUS_MODE, DISABLE);
+
+ data_len = ADC_GetFIFODataLen(ADC);
+ /* ADC continuous sampling mode, read data from FIFO.
+ In multi-channel sampling,
+ the data order in FIFO corresponds to the channel order set by schedule index.
+ */
+ ADC_ReadFIFOData(ADC, sample_data, data_len);
+
+ ADC_ClearFIFO(ADC);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_THD);
+
+ T_IO_MSG int_adc_msg;
+
+ int_adc_msg.type = IO_MSG_TYPE_ADC;
+ int_adc_msg.subtype = 0;
+ ADC_Global_Data.RawData[0] = data_len;
+ for (uint8_t i = 0; i < data_len; i++)
+ {
+ ADC_Global_Data.RawData[i + 1] = sample_data[i];
+ }
+ int_adc_msg.u.buf = (void *)(ADC_Global_Data.RawData);
+ if (false == app_send_msg_to_apptask(&int_adc_msg))
+ {
+ APP_PRINT_ERROR0("[io_adc] ADC_Handler: Send int_adc_msg failed!");
+ //Add user code here!
+ ADC_ClearFIFO(ADC);
+ ADC_ClearINTPendingBit(ADC, ADC_INT_FIFO_THD);
+ return;
+ }
+ }
+}
+