drivers: sensor: Add Atmel SAM QDEC (TC) Driver
Tested on Atmel SMART SAM E70 Xplained board Origin: Original Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
This commit is contained in:
parent
d6f2ba8011
commit
f5163e2ce2
5 changed files with 164 additions and 0 deletions
|
@ -63,6 +63,7 @@ add_subdirectory_ifdef(CONFIG_MS5837 ms5837)
|
|||
add_subdirectory_ifdef(CONFIG_OPT3001 opt3001)
|
||||
add_subdirectory_ifdef(CONFIG_PMS7003 pms7003)
|
||||
add_subdirectory_ifdef(CONFIG_QDEC_NRFX qdec_nrfx)
|
||||
add_subdirectory_ifdef(CONFIG_QDEC_SAM qdec_sam)
|
||||
add_subdirectory_ifdef(CONFIG_TEMP_NRF5 nrf5)
|
||||
add_subdirectory_ifdef(CONFIG_SHT3XD sht3xd)
|
||||
add_subdirectory_ifdef(CONFIG_SI7006 si7006)
|
||||
|
|
|
@ -168,6 +168,8 @@ source "drivers/sensor/pms7003/Kconfig"
|
|||
|
||||
source "drivers/sensor/qdec_nrfx/Kconfig"
|
||||
|
||||
source "drivers/sensor/qdec_sam/Kconfig"
|
||||
|
||||
source "drivers/sensor/sht3xd/Kconfig"
|
||||
|
||||
source "drivers/sensor/si7006/Kconfig"
|
||||
|
|
7
drivers/sensor/qdec_sam/CMakeLists.txt
Normal file
7
drivers/sensor/qdec_sam/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Copyright (c) 2021, Piotr Mienkowski
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources(qdec_sam.c)
|
12
drivers/sensor/qdec_sam/Kconfig
Normal file
12
drivers/sensor/qdec_sam/Kconfig
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Atmel SAM MCU family Quadrature Decoder (TC) driver configuration options
|
||||
#
|
||||
# Copyright (c) 2021, Piotr Mienkowski
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
config QDEC_SAM
|
||||
bool "Atmel SAM QDEC driver"
|
||||
depends on SOC_FAMILY_SAM
|
||||
default n
|
||||
help
|
||||
Atmel SAM MCU family Quadrature Decoder (TC) driver.
|
142
drivers/sensor/qdec_sam/qdec_sam.c
Normal file
142
drivers/sensor/qdec_sam/qdec_sam.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Piotr Mienkowski
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT atmel_sam_tc
|
||||
|
||||
/** @file
|
||||
* @brief Atmel SAM MCU family Quadrature Decoder (QDEC/TC) driver.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/__assert.h>
|
||||
#include <sys/util.h>
|
||||
#include <device.h>
|
||||
#include <init.h>
|
||||
#include <soc.h>
|
||||
#include <drivers/sensor.h>
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(qdec_sam, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
/* Device constant configuration parameters */
|
||||
struct qdec_sam_dev_cfg {
|
||||
Tc *regs;
|
||||
const struct soc_gpio_pin *pin_list;
|
||||
uint8_t pin_list_size;
|
||||
uint8_t periph_id[TCCHANNEL_NUMBER];
|
||||
};
|
||||
|
||||
/* Device run time data */
|
||||
struct qdec_sam_dev_data {
|
||||
uint16_t position;
|
||||
};
|
||||
|
||||
#define DEV_NAME(dev) ((dev)->name)
|
||||
#define DEV_CFG(dev) \
|
||||
((const struct qdec_sam_dev_cfg *const)(dev)->config)
|
||||
#define DEV_DATA(dev) \
|
||||
((struct qdec_sam_dev_data *const)(dev)->data)
|
||||
|
||||
static int qdec_sam_fetch(const struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
const struct qdec_sam_dev_cfg *const dev_cfg = DEV_CFG(dev);
|
||||
struct qdec_sam_dev_data *const dev_data = DEV_DATA(dev);
|
||||
Tc *const tc = dev_cfg->regs;
|
||||
TcChannel *tc_ch0 = &tc->TC_CHANNEL[0];
|
||||
|
||||
/* Read position register content */
|
||||
dev_data->position = tc_ch0->TC_CV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qdec_sam_get(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
struct qdec_sam_dev_data *const dev_data = DEV_DATA(dev);
|
||||
|
||||
if (chan == SENSOR_CHAN_ROTATION) {
|
||||
val->val1 = dev_data->position;
|
||||
val->val2 = 0;
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qdec_sam_start(Tc *const tc)
|
||||
{
|
||||
TcChannel *tc_ch0 = &tc->TC_CHANNEL[0];
|
||||
|
||||
/* Enable Channel 0 Clock and reset counter*/
|
||||
tc_ch0->TC_CCR = TC_CCR_CLKEN
|
||||
| TC_CCR_SWTRG;
|
||||
}
|
||||
|
||||
static void qdec_sam_configure(const struct device *dev)
|
||||
{
|
||||
const struct qdec_sam_dev_cfg *const dev_cfg = DEV_CFG(dev);
|
||||
Tc *const tc = dev_cfg->regs;
|
||||
TcChannel *tc_ch0 = &tc->TC_CHANNEL[0];
|
||||
|
||||
/* Clock, Trigger Edge, Trigger and Mode Selection */
|
||||
tc_ch0->TC_CMR = TC_CMR_TCCLKS_XC0
|
||||
| TC_CMR_ETRGEDG_RISING
|
||||
| TC_CMR_ABETRG;
|
||||
|
||||
/* Enable QDEC in Position Mode*/
|
||||
tc->TC_BMR = TC_BMR_QDEN
|
||||
| TC_BMR_POSEN
|
||||
| TC_BMR_EDGPHA
|
||||
| TC_BMR_MAXFILT(1);
|
||||
|
||||
qdec_sam_start(tc);
|
||||
}
|
||||
|
||||
static int qdec_sam_initialize(const struct device *dev)
|
||||
{
|
||||
__ASSERT_NO_MSG(dev != NULL);
|
||||
const struct qdec_sam_dev_cfg *const dev_cfg = DEV_CFG(dev);
|
||||
|
||||
/* Connect pins to the peripheral */
|
||||
soc_gpio_list_configure(dev_cfg->pin_list, dev_cfg->pin_list_size);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(dev_cfg->periph_id); i++) {
|
||||
/* Enable module's clock */
|
||||
soc_pmc_peripheral_enable(dev_cfg->periph_id[i]);
|
||||
}
|
||||
|
||||
qdec_sam_configure(dev);
|
||||
|
||||
LOG_INF("Device %s initialized", DEV_NAME(dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api qdec_sam_driver_api = {
|
||||
.sample_fetch = qdec_sam_fetch,
|
||||
.channel_get = qdec_sam_get,
|
||||
};
|
||||
|
||||
#define QDEC_SAM_INIT(n) \
|
||||
static const struct soc_gpio_pin pins_tc##n[] = ATMEL_SAM_DT_PINS(n); \
|
||||
\
|
||||
static const struct qdec_sam_dev_cfg qdec##n##_sam_config = { \
|
||||
.regs = (Tc *)DT_INST_REG_ADDR(n), \
|
||||
.pin_list = pins_tc##n, \
|
||||
.pin_list_size = ARRAY_SIZE(pins_tc##n), \
|
||||
.periph_id = DT_INST_PROP(n, peripheral_id), \
|
||||
}; \
|
||||
\
|
||||
static struct qdec_sam_dev_data qdec##n##_sam_data; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, qdec_sam_initialize, device_pm_control_nop, \
|
||||
&qdec##n##_sam_data, &qdec##n##_sam_config, \
|
||||
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
|
||||
&qdec_sam_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(QDEC_SAM_INIT)
|
Loading…
Add table
Add a link
Reference in a new issue