164 lines
3.2 KiB
C
164 lines
3.2 KiB
C
|
/*
|
||
|
* Copyright (c) 2020-2021, Bluetrum Development Team
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 2021-02-01 greedyhao first version
|
||
|
*/
|
||
|
|
||
|
#include "drv_gpio.h"
|
||
|
|
||
|
#ifdef BSP_USING_ADC0
|
||
|
|
||
|
#include "adc_config.h"
|
||
|
|
||
|
// #define DRV_DEBUG
|
||
|
#define LOG_TAG "drv.adc"
|
||
|
#include <drv_log.h>
|
||
|
|
||
|
struct ab32_adc
|
||
|
{
|
||
|
struct rt_adc_device ab32_adc_device;
|
||
|
hal_sfr_t adc_dat_handle;
|
||
|
char *name;
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
#ifdef BSP_USING_ADC0
|
||
|
ADC0_INDEX,
|
||
|
#endif
|
||
|
|
||
|
ADC_INDEX_END
|
||
|
};
|
||
|
|
||
|
static struct ab32_adc ab32_adc_obj[] =
|
||
|
{
|
||
|
#ifdef BSP_USING_ADC0
|
||
|
ADC0_CONFIG,
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
static rt_err_t ab32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
|
||
|
{
|
||
|
RT_ASSERT(device != RT_NULL);
|
||
|
|
||
|
hal_adc_enable(enabled);
|
||
|
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
|
||
|
static rt_uint32_t ab32_adc_get_channel(rt_uint32_t channel)
|
||
|
{
|
||
|
rt_uint32_t ab32_channel = 0;
|
||
|
|
||
|
switch (channel)
|
||
|
{
|
||
|
case 0:
|
||
|
ab32_channel = ADC_CHANNEL_0;
|
||
|
break;
|
||
|
case 1:
|
||
|
ab32_channel = ADC_CHANNEL_1;
|
||
|
break;
|
||
|
case 2:
|
||
|
ab32_channel = ADC_CHANNEL_2;
|
||
|
break;
|
||
|
case 3:
|
||
|
ab32_channel = ADC_CHANNEL_3;
|
||
|
break;
|
||
|
case 4:
|
||
|
ab32_channel = ADC_CHANNEL_4;
|
||
|
break;
|
||
|
case 5:
|
||
|
ab32_channel = ADC_CHANNEL_5;
|
||
|
break;
|
||
|
case 6:
|
||
|
ab32_channel = ADC_CHANNEL_6;
|
||
|
break;
|
||
|
case 7:
|
||
|
ab32_channel = ADC_CHANNEL_7;
|
||
|
break;
|
||
|
case 8:
|
||
|
ab32_channel = ADC_CHANNEL_8;
|
||
|
break;
|
||
|
case 9:
|
||
|
ab32_channel = ADC_CHANNEL_9;
|
||
|
break;
|
||
|
case 10:
|
||
|
ab32_channel = ADC_CHANNEL_10;
|
||
|
break;
|
||
|
case 11:
|
||
|
ab32_channel = ADC_CHANNEL_11;
|
||
|
break;
|
||
|
case 12:
|
||
|
ab32_channel = ADC_CHANNEL_12;
|
||
|
break;
|
||
|
case 13:
|
||
|
ab32_channel = ADC_CHANNEL_13;
|
||
|
break;
|
||
|
case 14:
|
||
|
ab32_channel = ADC_CHANNEL_14;
|
||
|
break;
|
||
|
case 15:
|
||
|
ab32_channel = ADC_CHANNEL_15;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return ab32_channel;
|
||
|
}
|
||
|
|
||
|
static rt_err_t ab32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
|
||
|
{
|
||
|
hal_sfr_t ab32_adc_handler;
|
||
|
|
||
|
RT_ASSERT(device != RT_NULL);
|
||
|
RT_ASSERT(value != RT_NULL);
|
||
|
|
||
|
ab32_adc_handler = device->parent.user_data;
|
||
|
|
||
|
hal_adc_start(ab32_adc_get_channel(channel));
|
||
|
hal_adc_poll_for_conversion(1000);
|
||
|
|
||
|
*value = ab32_adc_handler[channel];
|
||
|
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
|
||
|
static const struct rt_adc_ops _adc_ops =
|
||
|
{
|
||
|
.enabled = ab32_adc_enabled,
|
||
|
.convert = ab32_get_adc_value,
|
||
|
};
|
||
|
|
||
|
static int ab32_adc_init(void)
|
||
|
{
|
||
|
int result = RT_EOK;
|
||
|
int i = 0;
|
||
|
|
||
|
if (ADC_INDEX_END == 0) {
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
CLKCON0 |= BIT(28); // enable adc clock
|
||
|
|
||
|
for (i = 0; i < sizeof(ab32_adc_obj) / sizeof(ab32_adc_obj[0]); i++) {
|
||
|
if (rt_hw_adc_register(&ab32_adc_obj[i].ab32_adc_device, ab32_adc_obj[i].name, &_adc_ops, (const void *)ab32_adc_obj[i].adc_dat_handle) == RT_EOK)
|
||
|
{
|
||
|
LOG_D("%s init success", ab32_adc_obj[i].name);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LOG_E("%s register failed", ab32_adc_obj[i].name);
|
||
|
result = -RT_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
INIT_BOARD_EXPORT(ab32_adc_init);
|
||
|
|
||
|
#endif
|
||
|
|