support linux system

This commit is contained in:
ZYQ-FEIYUE
2022-08-09 22:38:26 +08:00
parent ef453b4ba6
commit d2816d24b5
130 changed files with 22 additions and 24 deletions

255
cores/arduino/libcore/adc.c Normal file
View File

@@ -0,0 +1,255 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "adc.h"
#include <stdbool.h>
#define ADC_DMA_REGMAX 18
#define IS_ADC_CHANNEL(channel) (channel <= ADC_CHANNEL_17)
/*引脚注册个数*/
static uint8_t ADC_DMA_RegCnt = 0;
/*ADC通道注册列表*/
static uint8_t ADC_DMA_RegChannelList[ADC_DMA_REGMAX] = {0};
/*ADC DMA缓存数组*/
static uint16_t ADC_DMA_ConvertedValue[ADC_DMA_REGMAX] = {0};
/**
* @brief 搜索注册列表找出ADC通道对应的索引号
* @param ADC_Channel:ADC通道号
* @retval ADC通道注册列表对应索引号-1:未找到对应通道号
*/
static int16_t ADC_DMA_SearchChannel(uint16_t ADC_Channel)
{
uint8_t index;
for(index = 0; index < ADC_DMA_RegCnt; index++)
{
if(ADC_Channel == ADC_DMA_RegChannelList[index])
{
return index;
}
}
return -1;
}
/**
* @brief ADC 配置
* @param ADCx: ADC地址
* @retval 无
*/
void ADCx_Init(adc_type* ADCx)
{
adc_base_config_type adc_base_struct;
if(ADCx == ADC1)
{
crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
}
else if(ADCx == ADC2)
{
crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, TRUE);
}
#ifdef ADC3
else if(ADCx == ADC3)
{
crm_periph_clock_enable(CRM_ADC3_PERIPH_CLOCK, TRUE);
}
#endif
else
{
return;
}
crm_adc_clock_div_set(CRM_ADC_DIV_8);
adc_combine_mode_select(ADC_INDEPENDENT_MODE);
adc_base_default_para_init(&adc_base_struct);
adc_base_struct.sequence_mode = FALSE;
adc_base_struct.repeat_mode = FALSE;
adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct.ordinary_channel_length = 1;
adc_base_config(ADCx, &adc_base_struct);
if (ADCx != ADC3)
adc_ordinary_conversion_trigger_set(ADCx, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
else
adc_ordinary_conversion_trigger_set(ADCx, ADC3_ORDINARY_TRIG_SOFTWARE, TRUE);
adc_enable(ADCx, TRUE);
adc_calibration_init(ADCx);
while(adc_calibration_init_status_get(ADCx));
adc_calibration_start(ADCx);
while(adc_calibration_status_get(ADCx));
}
/**
* @brief 获取 ADC 值
* @param ADCx: ADC地址
* @param ADC_Channel: ADC通道
* @retval 无
*/
uint16_t ADCx_GetValue(adc_type* ADCx, uint16_t ADC_Channel)
{
adc_ordinary_channel_set(ADCx, (adc_channel_select_type)ADC_Channel, 1, ADC_SAMPLETIME_41_5);
adc_ordinary_software_trigger_enable(ADCx, TRUE);
while(!adc_flag_get(ADCx, ADC_CCE_FLAG));
return adc_ordinary_conversion_data_get(ADCx);
}
/**
* @brief 注册需要DMA搬运的ADC通道
* @param ADC_Channel:ADC通道号
* @retval 见ADC_DMA_Res_Type
*/
ADC_DMA_Res_Type ADC_DMA_Register(uint8_t ADC_Channel)
{
/*初始化ADC通道列表*/
static bool isInit = false;
if(!isInit)
{
uint8_t i;
for(i = 0; i < ADC_DMA_REGMAX; i++)
{
ADC_DMA_RegChannelList[i] = 0xFF;
}
isInit = true;
}
/*是否是合法ADC通道*/
if(!IS_ADC_CHANNEL(ADC_Channel))
return ADC_DMA_RES_NOT_ADC_CHANNEL;
/*是否已在引脚列表重复注册*/
if(ADC_DMA_SearchChannel(ADC_Channel) != -1)
return ADC_DMA_RES_DUPLICATE_REGISTRATION;
/*是否超出最大注册个数*/
if(ADC_DMA_RegCnt >= ADC_DMA_REGMAX)
return ADC_DMA_RES_MAX_NUM_OF_REGISTRATIONS_EXCEEDED;
/*写入注册列表*/
ADC_DMA_RegChannelList[ADC_DMA_RegCnt] = ADC_Channel;
/*注册个数+1*/
ADC_DMA_RegCnt++;
return ADC_DMA_RES_OK;
}
/**
* @brief 获取已注册的ADC DMA通道数量
* @param 无
* @retval ADC DMA通道数量
*/
uint8_t ADC_DMA_GetRegisterCount(void)
{
return ADC_DMA_RegCnt;
}
/**
* @brief ADC DMA 配置
* @param 无
* @retval 无
*/
void ADC_DMA_Init(void)
{
dma_init_type dma_init_structure;
adc_base_config_type adc_base_struct;
uint8_t index;
crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
dma_reset(DMA1_CHANNEL1);
dma_default_para_init(&dma_init_structure);
dma_init_structure.buffer_size = ADC_DMA_RegCnt;
dma_init_structure.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
dma_init_structure.memory_base_addr = (uint32_t)ADC_DMA_ConvertedValue;
dma_init_structure.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
dma_init_structure.memory_inc_enable = TRUE;
dma_init_structure.peripheral_base_addr = (uint32_t) (&(ADC1->odt));
dma_init_structure.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
dma_init_structure.peripheral_inc_enable = FALSE;
dma_init_structure.priority = DMA_PRIORITY_HIGH;
dma_init_structure.loop_mode_enable = TRUE;
dma_init(DMA1_CHANNEL1, &dma_init_structure);
adc_combine_mode_select(ADC_INDEPENDENT_MODE);
adc_base_default_para_init(&adc_base_struct);
adc_base_struct.sequence_mode = FALSE;
adc_base_struct.repeat_mode = FALSE;
adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct.ordinary_channel_length = 1;
adc_base_config(ADC1, &adc_base_struct);
adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
crm_adc_clock_div_set(CRM_ADC_DIV_8);
for(index = 0; index < ADC_DMA_RegCnt; index++)
{
adc_ordinary_channel_set(
ADC1,
ADC_DMA_RegChannelList[index],
index + 1,
ADC_SAMPLETIME_41_5
);
if(ADC_DMA_RegChannelList[index] == ADC_CHANNEL_16)
{
adc_tempersensor_vintrv_enable(true);
}
}
adc_dma_mode_enable(ADC1, TRUE);
adc_enable(ADC1, TRUE);
adc_calibration_init(ADC1);
while(adc_calibration_init_status_get(ADC1));
adc_calibration_start(ADC1);
while(adc_calibration_status_get(ADC1));
}
/**
* @brief 获取DMA搬运的ADC值
* @param ADC_Channel:ADC通道号
* @retval ADC值
*/
uint16_t ADC_DMA_GetValue(uint8_t ADC_Channel)
{
int16_t index;
if(!IS_ADC_CHANNEL(ADC_Channel))
return 0;
index = ADC_DMA_SearchChannel(ADC_Channel);
if(index == -1)
return 0;
return ADC_DMA_ConvertedValue[index];
}