| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- /*
- * Copyright (c) 2006-2024, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2022-05-16 shelton first version
- * 2024-07-21 liujianhua added mcxa153
- *
- */
- #include <rtconfig.h>
- #include <rtdevice.h>
- #include "fsl_adc12.h"
- #include "fsl_pmc.h"
- #define DBG_TAG "drv.adc"
- #define DBG_LVL DBG_INFO
- #include <rtdbg.h>
- #ifdef RT_USING_ADC
- #define ADC_VBG_CH 27
- #define ADC_VBG_VOLT 1000
- struct mcx_adc
- {
- struct rt_adc_device adc_device;
- ADC_Type *adc_base;
- clock_ip_name_t clock_ip_name;
- clock_ip_src_t clock_ip_src;
- uint8_t resolution_bits;
- uint8_t max_channels;
- uint32_t vref;
- char *name;
- };
- static struct mcx_adc mcx_adc_obj[] =
- {
- #ifdef BSP_USING_ADC0
- {
- .adc_base = ADC0,
- .clock_ip_name = kCLOCK_Adc0,
- .clock_ip_src = kCLOCK_IpSrcSysOscAsync,
- .resolution_bits = 12,
- .max_channels = 32,
- .name = "adc0",
- },
- #endif
- #ifdef BSP_USING_ADC1
- {
- .adc_base = ADC1,
- .clock_ip_name = kCLOCK_Adc1,
- .clock_ip_src = kCLOCK_IpSrcSysOscAsync,
- .resolution_bits = 12,
- .max_channels = 32,
- .name = "adc1",
- },
- #endif
- };
- static uint16_t mcx_adc_get_raw(struct mcx_adc *adc, uint32_t channel)
- {
- adc12_channel_config_t chnl_cfg = {0};
- chnl_cfg.channelNumber = channel;
- chnl_cfg.enableInterruptOnConversionCompleted = false;
- ADC12_SetChannelConfig(adc->adc_base, 0, &chnl_cfg);
- while ((ADC12_GetChannelStatusFlags(adc->adc_base, 0) & kADC12_ChannelConversionCompletedFlag) == 0U)
- {
- }
- return ADC12_GetChannelConversionValue(adc->adc_base, 0);
- }
- static rt_err_t mcx_adc_set_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
- {
- RT_ASSERT(device != RT_NULL);
- struct mcx_adc *adc = device->parent.user_data;
- /* ADC is enabled by global probe. */
- RT_UNUSED(adc);
- return RT_EOK;
- }
- static rt_int16_t mcx_get_vref(struct rt_adc_device *device)
- {
- RT_ASSERT(device != RT_NULL);
- struct mcx_adc *adc = device->parent.user_data;
- return (int16_t)adc->vref;
- }
- static rt_err_t mcx_adc_get_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
- {
- RT_ASSERT(device != RT_NULL);
- struct mcx_adc *adc = device->parent.user_data;
- *value = mcx_adc_get_raw(adc, channel);
- return RT_EOK;
- }
- static rt_uint8_t mcx_adc_get_resolution(struct rt_adc_device *device)
- {
- RT_ASSERT(device != RT_NULL);
- struct mcx_adc *adc = device->parent.user_data;
- return adc->resolution_bits;
- }
- static const struct rt_adc_ops mcx_adc_ops =
- {
- .get_resolution = mcx_adc_get_resolution,
- .enabled = mcx_adc_set_enabled,
- .convert = mcx_adc_get_value,
- .get_vref = mcx_get_vref,
- };
- static int rt_hw_adc_init(void)
- {
- int result = RT_EOK;
- int i = 0;
- for (i = 0; i < sizeof(mcx_adc_obj) / sizeof(mcx_adc_obj[0]); i++)
- {
- struct mcx_adc *adc = &mcx_adc_obj[i];
- CLOCK_SetIpSrc(adc->clock_ip_name, adc->clock_ip_src);
- adc12_config_t cfg;
- ADC12_GetDefaultConfig(&cfg);
- cfg.clockSource = kADC12_ClockSourceAlt0; /* Only available selection. */
- cfg.resolution = kADC12_Resolution12Bit;
- cfg.sampleClockCount = 64;
- ADC12_Init(adc->adc_base, &cfg);
- ADC12_EnableHardwareTrigger(adc->adc_base, false);
- if (ADC12_DoAutoCalibration(adc->adc_base) != kStatus_Success)
- {
- return -RT_ERROR;
- }
- uint32_t vref_raw = mcx_adc_get_raw(adc, ADC_VBG_CH);
- adc->vref = (1U << adc->resolution_bits) * ADC_VBG_VOLT / vref_raw;
- if (rt_hw_adc_register(&mcx_adc_obj[i].adc_device, mcx_adc_obj[i].name, &mcx_adc_ops, &mcx_adc_obj[i]) != RT_EOK)
- {
- return -RT_ERROR;
- }
- }
- return result;
- }
- INIT_BOARD_EXPORT(rt_hw_adc_init);
- #endif /* BSP_USING_ADC */
|