Skip to content

Commit 42ed3ba

Browse files
committed
bsp/nxp/mcx/mcxe: Add ADC driver.
Signed-off-by: Yilin Sun <[email protected]>
1 parent c53c578 commit 42ed3ba

File tree

5 files changed

+180
-1044
lines changed

5 files changed

+180
-1044
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Copyright (c) 2006-2024, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-05-16 shelton first version
9+
* 2024-07-21 liujianhua added mcxa153
10+
*
11+
*/
12+
#include <rtconfig.h>
13+
#include <rtdevice.h>
14+
15+
#include "fsl_adc12.h"
16+
#include "fsl_pmc.h"
17+
18+
#define DBG_TAG "drv.adc"
19+
#define DBG_LVL DBG_INFO
20+
#include <rtdbg.h>
21+
22+
#ifdef RT_USING_ADC
23+
24+
#define ADC_VBG_CH 27
25+
#define ADC_VBG_VOLT 1000
26+
27+
struct mcx_adc
28+
{
29+
struct rt_adc_device adc_device;
30+
ADC_Type *adc_base;
31+
clock_ip_name_t clock_ip_name;
32+
clock_ip_src_t clock_ip_src;
33+
uint8_t resolution_bits;
34+
uint8_t max_channels;
35+
uint32_t vref;
36+
char *name;
37+
};
38+
39+
static struct mcx_adc mcx_adc_obj[] =
40+
{
41+
#ifdef BSP_USING_ADC0
42+
{
43+
.adc_base = ADC0,
44+
.clock_ip_name = kCLOCK_Adc0,
45+
.clock_ip_src = kCLOCK_IpSrcSysOscAsync,
46+
.resolution_bits = 12,
47+
.max_channels = 32,
48+
.name = "adc0",
49+
},
50+
#endif
51+
#ifdef BSP_USING_ADC1
52+
{
53+
.adc_base = ADC1,
54+
.clock_ip_name = kCLOCK_Adc1,
55+
.clock_ip_src = kCLOCK_IpSrcSysOscAsync,
56+
.resolution_bits = 12,
57+
.max_channels = 32,
58+
.name = "adc1",
59+
},
60+
#endif
61+
};
62+
63+
static uint16_t mcx_adc_get_raw(struct mcx_adc *adc, uint32_t channel)
64+
{
65+
adc12_channel_config_t chnl_cfg = {0};
66+
67+
chnl_cfg.channelNumber = channel;
68+
chnl_cfg.enableInterruptOnConversionCompleted = false;
69+
70+
ADC12_SetChannelConfig(adc->adc_base, 0, &chnl_cfg);
71+
while ((ADC12_GetChannelStatusFlags(adc->adc_base, 0) & kADC12_ChannelConversionCompletedFlag) == 0U)
72+
{
73+
}
74+
75+
return ADC12_GetChannelConversionValue(adc->adc_base, 0);
76+
}
77+
78+
static rt_err_t mcx_adc_set_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
79+
{
80+
RT_ASSERT(device != RT_NULL);
81+
82+
struct mcx_adc *adc = device->parent.user_data;
83+
/* ADC is enabled by global probe. */
84+
85+
RT_UNUSED(adc);
86+
87+
return RT_EOK;
88+
}
89+
90+
static rt_int16_t mcx_get_vref(struct rt_adc_device *device)
91+
{
92+
RT_ASSERT(device != RT_NULL);
93+
94+
struct mcx_adc *adc = device->parent.user_data;
95+
96+
return (int16_t)adc->vref;
97+
}
98+
99+
static rt_err_t mcx_adc_get_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
100+
{
101+
RT_ASSERT(device != RT_NULL);
102+
103+
struct mcx_adc *adc = device->parent.user_data;
104+
105+
*value = mcx_adc_get_raw(adc, channel);
106+
107+
return RT_EOK;
108+
}
109+
110+
static rt_uint8_t mcx_adc_get_resolution(struct rt_adc_device *device)
111+
{
112+
RT_ASSERT(device != RT_NULL);
113+
114+
struct mcx_adc *adc = device->parent.user_data;
115+
116+
return adc->resolution_bits;
117+
}
118+
119+
static const struct rt_adc_ops mcx_adc_ops =
120+
{
121+
.get_resolution = mcx_adc_get_resolution,
122+
.enabled = mcx_adc_set_enabled,
123+
.convert = mcx_adc_get_value,
124+
.get_vref = mcx_get_vref,
125+
};
126+
127+
static int rt_hw_adc_init(void)
128+
{
129+
int result = RT_EOK;
130+
int i = 0;
131+
132+
for (i = 0; i < sizeof(mcx_adc_obj) / sizeof(mcx_adc_obj[0]); i++)
133+
{
134+
struct mcx_adc *adc = &mcx_adc_obj[i];
135+
136+
CLOCK_SetIpSrc(adc->clock_ip_name, adc->clock_ip_src);
137+
138+
adc12_config_t cfg;
139+
ADC12_GetDefaultConfig(&cfg);
140+
141+
cfg.clockSource = kADC12_ClockSourceAlt0; /* Only available selection. */
142+
cfg.resolution = kADC12_Resolution12Bit;
143+
cfg.sampleClockCount = 64;
144+
145+
ADC12_Init(adc->adc_base, &cfg);
146+
ADC12_EnableHardwareTrigger(adc->adc_base, false);
147+
148+
if (ADC12_DoAutoCalibration(adc->adc_base) != kStatus_Success)
149+
{
150+
return RT_ERROR;
151+
}
152+
153+
uint32_t vref_raw = mcx_adc_get_raw(adc, ADC_VBG_CH);
154+
adc->vref = (1U << adc->resolution_bits) * ADC_VBG_VOLT / vref_raw;
155+
156+
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)
157+
{
158+
return RT_ERROR;
159+
}
160+
}
161+
162+
return result;
163+
}
164+
165+
INIT_BOARD_EXPORT(rt_hw_adc_init);
166+
167+
#endif /* BSP_USING_ADC */

bsp/nxp/mcx/mcxe/Libraries/drivers/drv_spi.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,8 @@ struct mcx_spi_bus
3434
LPSPI_Type *spi_base;
3535
clock_ip_name_t clock_ip_name;
3636
clock_ip_src_t clock_ip_src;
37-
clock_name_t clock_name;
38-
39-
40-
rt_sem_t sem;
41-
char *name;
37+
rt_sem_t sem;
38+
char *name;
4239
};
4340

4441
static struct mcx_spi_bus mcx_spi_buses[] =
@@ -150,7 +147,7 @@ int rt_hw_spi_init(void)
150147
masterConfig.lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig.baudRate * 1U;
151148
masterConfig.betweenTransferDelayInNanoSec = 1000000000U / masterConfig.baudRate * 1U;
152149

153-
LPSPI_MasterInit(priv->spi_base, &masterConfig, CLOCK_GetFreq(priv->clock_name));
150+
LPSPI_MasterInit(priv->spi_base, &masterConfig, CLOCK_GetIpFreq(priv->clock_ip_name));
154151

155152
rt_spi_bus_register(&priv->spi_bus, priv->name, &lpc_spi_ops);
156153
}

0 commit comments

Comments
 (0)