Skip to content

Commit f5163e2

Browse files
mnkpcarlescufi
authored andcommitted
drivers: sensor: Add Atmel SAM QDEC (TC) Driver
Tested on Atmel SMART SAM E70 Xplained board Origin: Original Signed-off-by: Piotr Mienkowski <[email protected]>
1 parent d6f2ba8 commit f5163e2

File tree

5 files changed

+164
-0
lines changed

5 files changed

+164
-0
lines changed

drivers/sensor/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ add_subdirectory_ifdef(CONFIG_MS5837 ms5837)
6363
add_subdirectory_ifdef(CONFIG_OPT3001 opt3001)
6464
add_subdirectory_ifdef(CONFIG_PMS7003 pms7003)
6565
add_subdirectory_ifdef(CONFIG_QDEC_NRFX qdec_nrfx)
66+
add_subdirectory_ifdef(CONFIG_QDEC_SAM qdec_sam)
6667
add_subdirectory_ifdef(CONFIG_TEMP_NRF5 nrf5)
6768
add_subdirectory_ifdef(CONFIG_SHT3XD sht3xd)
6869
add_subdirectory_ifdef(CONFIG_SI7006 si7006)

drivers/sensor/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ source "drivers/sensor/pms7003/Kconfig"
168168

169169
source "drivers/sensor/qdec_nrfx/Kconfig"
170170

171+
source "drivers/sensor/qdec_sam/Kconfig"
172+
171173
source "drivers/sensor/sht3xd/Kconfig"
172174

173175
source "drivers/sensor/si7006/Kconfig"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright (c) 2021, Piotr Mienkowski
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
zephyr_library()
6+
7+
zephyr_library_sources(qdec_sam.c)

drivers/sensor/qdec_sam/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Atmel SAM MCU family Quadrature Decoder (TC) driver configuration options
2+
#
3+
# Copyright (c) 2021, Piotr Mienkowski
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
config QDEC_SAM
8+
bool "Atmel SAM QDEC driver"
9+
depends on SOC_FAMILY_SAM
10+
default n
11+
help
12+
Atmel SAM MCU family Quadrature Decoder (TC) driver.

drivers/sensor/qdec_sam/qdec_sam.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright (c) 2021, Piotr Mienkowski
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT atmel_sam_tc
8+
9+
/** @file
10+
* @brief Atmel SAM MCU family Quadrature Decoder (QDEC/TC) driver.
11+
*/
12+
13+
#include <errno.h>
14+
#include <sys/__assert.h>
15+
#include <sys/util.h>
16+
#include <device.h>
17+
#include <init.h>
18+
#include <soc.h>
19+
#include <drivers/sensor.h>
20+
21+
#include <logging/log.h>
22+
LOG_MODULE_REGISTER(qdec_sam, CONFIG_SENSOR_LOG_LEVEL);
23+
24+
/* Device constant configuration parameters */
25+
struct qdec_sam_dev_cfg {
26+
Tc *regs;
27+
const struct soc_gpio_pin *pin_list;
28+
uint8_t pin_list_size;
29+
uint8_t periph_id[TCCHANNEL_NUMBER];
30+
};
31+
32+
/* Device run time data */
33+
struct qdec_sam_dev_data {
34+
uint16_t position;
35+
};
36+
37+
#define DEV_NAME(dev) ((dev)->name)
38+
#define DEV_CFG(dev) \
39+
((const struct qdec_sam_dev_cfg *const)(dev)->config)
40+
#define DEV_DATA(dev) \
41+
((struct qdec_sam_dev_data *const)(dev)->data)
42+
43+
static int qdec_sam_fetch(const struct device *dev, enum sensor_channel chan)
44+
{
45+
const struct qdec_sam_dev_cfg *const dev_cfg = DEV_CFG(dev);
46+
struct qdec_sam_dev_data *const dev_data = DEV_DATA(dev);
47+
Tc *const tc = dev_cfg->regs;
48+
TcChannel *tc_ch0 = &tc->TC_CHANNEL[0];
49+
50+
/* Read position register content */
51+
dev_data->position = tc_ch0->TC_CV;
52+
53+
return 0;
54+
}
55+
56+
static int qdec_sam_get(const struct device *dev, enum sensor_channel chan,
57+
struct sensor_value *val)
58+
{
59+
struct qdec_sam_dev_data *const dev_data = DEV_DATA(dev);
60+
61+
if (chan == SENSOR_CHAN_ROTATION) {
62+
val->val1 = dev_data->position;
63+
val->val2 = 0;
64+
} else {
65+
return -ENOTSUP;
66+
}
67+
68+
return 0;
69+
}
70+
71+
static void qdec_sam_start(Tc *const tc)
72+
{
73+
TcChannel *tc_ch0 = &tc->TC_CHANNEL[0];
74+
75+
/* Enable Channel 0 Clock and reset counter*/
76+
tc_ch0->TC_CCR = TC_CCR_CLKEN
77+
| TC_CCR_SWTRG;
78+
}
79+
80+
static void qdec_sam_configure(const struct device *dev)
81+
{
82+
const struct qdec_sam_dev_cfg *const dev_cfg = DEV_CFG(dev);
83+
Tc *const tc = dev_cfg->regs;
84+
TcChannel *tc_ch0 = &tc->TC_CHANNEL[0];
85+
86+
/* Clock, Trigger Edge, Trigger and Mode Selection */
87+
tc_ch0->TC_CMR = TC_CMR_TCCLKS_XC0
88+
| TC_CMR_ETRGEDG_RISING
89+
| TC_CMR_ABETRG;
90+
91+
/* Enable QDEC in Position Mode*/
92+
tc->TC_BMR = TC_BMR_QDEN
93+
| TC_BMR_POSEN
94+
| TC_BMR_EDGPHA
95+
| TC_BMR_MAXFILT(1);
96+
97+
qdec_sam_start(tc);
98+
}
99+
100+
static int qdec_sam_initialize(const struct device *dev)
101+
{
102+
__ASSERT_NO_MSG(dev != NULL);
103+
const struct qdec_sam_dev_cfg *const dev_cfg = DEV_CFG(dev);
104+
105+
/* Connect pins to the peripheral */
106+
soc_gpio_list_configure(dev_cfg->pin_list, dev_cfg->pin_list_size);
107+
108+
for (int i = 0; i < ARRAY_SIZE(dev_cfg->periph_id); i++) {
109+
/* Enable module's clock */
110+
soc_pmc_peripheral_enable(dev_cfg->periph_id[i]);
111+
}
112+
113+
qdec_sam_configure(dev);
114+
115+
LOG_INF("Device %s initialized", DEV_NAME(dev));
116+
117+
return 0;
118+
}
119+
120+
static const struct sensor_driver_api qdec_sam_driver_api = {
121+
.sample_fetch = qdec_sam_fetch,
122+
.channel_get = qdec_sam_get,
123+
};
124+
125+
#define QDEC_SAM_INIT(n) \
126+
static const struct soc_gpio_pin pins_tc##n[] = ATMEL_SAM_DT_PINS(n); \
127+
\
128+
static const struct qdec_sam_dev_cfg qdec##n##_sam_config = { \
129+
.regs = (Tc *)DT_INST_REG_ADDR(n), \
130+
.pin_list = pins_tc##n, \
131+
.pin_list_size = ARRAY_SIZE(pins_tc##n), \
132+
.periph_id = DT_INST_PROP(n, peripheral_id), \
133+
}; \
134+
\
135+
static struct qdec_sam_dev_data qdec##n##_sam_data; \
136+
\
137+
DEVICE_DT_INST_DEFINE(n, qdec_sam_initialize, device_pm_control_nop, \
138+
&qdec##n##_sam_data, &qdec##n##_sam_config, \
139+
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
140+
&qdec_sam_driver_api);
141+
142+
DT_INST_FOREACH_STATUS_OKAY(QDEC_SAM_INIT)

0 commit comments

Comments
 (0)