125 lines
3.2 KiB
C
125 lines
3.2 KiB
C
|
/*
|
||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 2021-08-23 AisinoChip first implementation
|
||
|
*/
|
||
|
|
||
|
#include <board.h>
|
||
|
#include <rtthread.h>
|
||
|
#include <rtdevice.h>
|
||
|
|
||
|
#define ADC_NAME "adc"
|
||
|
|
||
|
#if defined(BSP_USING_ADC)
|
||
|
|
||
|
struct acm32_adc
|
||
|
{
|
||
|
ADC_HandleTypeDef handle;
|
||
|
struct rt_adc_device acm32_adc_device;
|
||
|
};
|
||
|
|
||
|
static struct acm32_adc acm32_adc_obj = {0};
|
||
|
|
||
|
static rt_err_t acm32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
|
||
|
{
|
||
|
struct acm32_adc *adcObj = RT_NULL;
|
||
|
|
||
|
RT_ASSERT(device != RT_NULL);
|
||
|
|
||
|
adcObj = rt_container_of(device, struct acm32_adc, acm32_adc_device);
|
||
|
|
||
|
if (enabled)
|
||
|
{
|
||
|
/* channel enabled */
|
||
|
if (0 != (adcObj->handle.Init.ChannelEn & (1 << channel)))
|
||
|
{
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
|
||
|
adcObj->handle.Instance = ADC;
|
||
|
adcObj->handle.Init.ClockDiv = ADC_CLOCK_DIV8;
|
||
|
adcObj->handle.Init.ConConvMode = ADC_CONCONVMODE_DISABLE;
|
||
|
adcObj->handle.Init.JChannelMode = ADC_JCHANNELMODE_DISABLE;
|
||
|
adcObj->handle.Init.DiffMode = ADC_DIFFMODE_DISABLE;
|
||
|
adcObj->handle.Init.DMAMode = ADC_DMAMODE_DISABLE;
|
||
|
adcObj->handle.Init.OverMode = ADC_OVERMODE_DISABLE;
|
||
|
adcObj->handle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;
|
||
|
adcObj->handle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;
|
||
|
adcObj->handle.Init.ExTrigMode.ExTrigSel = ADC_SOFTWARE_START;
|
||
|
adcObj->handle.Init.ChannelEn |= 1 << channel;
|
||
|
|
||
|
HAL_ADC_Init(&adcObj->handle);
|
||
|
|
||
|
adcObj->handle.ChannelNum ++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* channel disabled */
|
||
|
if (0 == (adcObj->handle.Init.ChannelEn & (1 << channel)))
|
||
|
{
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
adcObj->handle.Init.ChannelEn &= ~(1 << channel);
|
||
|
adcObj->handle.ChannelNum --;
|
||
|
}
|
||
|
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
|
||
|
static rt_err_t acm32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
|
||
|
{
|
||
|
struct acm32_adc *adcObj = RT_NULL;
|
||
|
ADC_ChannelConfTypeDef channelConf = {0};
|
||
|
|
||
|
RT_ASSERT(device != RT_NULL);
|
||
|
RT_ASSERT(value != RT_NULL);
|
||
|
if (channel > ADC_CHANNEL_15)
|
||
|
{
|
||
|
return -RT_ERROR;
|
||
|
}
|
||
|
*value = RT_UINT32_MAX;
|
||
|
adcObj = rt_container_of(device, struct acm32_adc, acm32_adc_device);
|
||
|
|
||
|
/* channel disabled */
|
||
|
if (0 == (adcObj->handle.Init.ChannelEn & (1 << channel)))
|
||
|
{
|
||
|
return -RT_ERROR;
|
||
|
}
|
||
|
|
||
|
channelConf.Channel = channel;
|
||
|
channelConf.RjMode = 0;
|
||
|
channelConf.Sq = ADC_SEQUENCE_SQ1;
|
||
|
channelConf.Smp = ADC_SMP_CLOCK_320;
|
||
|
HAL_ADC_ConfigChannel(&adcObj->handle, &channelConf);
|
||
|
|
||
|
if (HAL_OK != HAL_ADC_Polling(&adcObj->handle, (uint32_t *)value, 1, 100))
|
||
|
{
|
||
|
return -RT_ERROR;
|
||
|
}
|
||
|
*value &= ~(HAL_ADC_EOC_FLAG);
|
||
|
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
|
||
|
static const struct rt_adc_ops acm_adc_ops =
|
||
|
{
|
||
|
.enabled = acm32_adc_enabled,
|
||
|
.convert = acm32_get_adc_value,
|
||
|
};
|
||
|
|
||
|
static int acm32_adc_init(void)
|
||
|
{
|
||
|
return rt_hw_adc_register(&acm32_adc_obj.acm32_adc_device,
|
||
|
ADC_NAME,
|
||
|
&acm_adc_ops,
|
||
|
RT_NULL);
|
||
|
}
|
||
|
INIT_BOARD_EXPORT(acm32_adc_init);
|
||
|
|
||
|
#endif /* BSP_USING_ADC */
|
||
|
|