drivers: tach: initial device driver for ENE KB1200
Add tachmeter driver for ENE KB1200 Signed-off-by: Steven Chang <steven@ene.com.tw>
This commit is contained in:
parent
d0bfe81ce9
commit
1b028ca2ce
|
@ -172,6 +172,7 @@ add_subdirectory_ifdef(CONFIG_WSEN_PADS wsen_pads)
|
|||
add_subdirectory_ifdef(CONFIG_WSEN_PDUS wsen_pdus)
|
||||
add_subdirectory_ifdef(CONFIG_WSEN_TIDS wsen_tids)
|
||||
add_subdirectory_ifdef(CONFIG_XMC4XXX_TEMP xmc4xxx_temp)
|
||||
add_subdirectory_ifdef(CONFIG_TACH_ENE_KB1200 ene_tach_kb1200)
|
||||
|
||||
zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/sensor.h)
|
||||
|
||||
|
|
|
@ -252,5 +252,6 @@ source "drivers/sensor/wsen_pads/Kconfig"
|
|||
source "drivers/sensor/wsen_pdus/Kconfig"
|
||||
source "drivers/sensor/wsen_tids/Kconfig"
|
||||
source "drivers/sensor/xmc4xxx_temp/Kconfig"
|
||||
source "drivers/sensor/ene_tach_kb1200/Kconfig"
|
||||
|
||||
endif # SENSOR
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
zephyr_library_sources_ifdef(CONFIG_TACH_ENE_KB1200 tach_ene_kb1200.c)
|
|
@ -0,0 +1,12 @@
|
|||
# KB1200 tachometer sensor configuration options
|
||||
|
||||
# Copyright (c) 2024 ENE Technology Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config TACH_ENE_KB1200
|
||||
bool "ENE KB1200 tachometer sensor"
|
||||
default y
|
||||
depends on DT_HAS_ENE_KB1200_TACH_ENABLED
|
||||
select PINCTRL
|
||||
help
|
||||
Enable tachometer sensor for ENE KB1200.
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2024 ENE Technology Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT ene_kb1200_tach
|
||||
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <reg/tacho.h>
|
||||
|
||||
/* Device config */
|
||||
struct tach_kb1200_config {
|
||||
/* tachometer controller base address */
|
||||
struct tacho_regs *tacho;
|
||||
/* number of pulses (holes) per round of tachometer's input (encoder) */
|
||||
int pulses_per_round;
|
||||
/* sampling clock timing of tachometer (us) */
|
||||
int sample_time_us;
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
};
|
||||
|
||||
/* Driver data */
|
||||
struct tach_kb1200_data {
|
||||
/* Captured counts of tachometer */
|
||||
uint32_t capture;
|
||||
};
|
||||
|
||||
/* TACH local functions */
|
||||
static int tach_kb1200_configure(const struct device *dev)
|
||||
{
|
||||
const struct tach_kb1200_config *const config = dev->config;
|
||||
uint8_t sample_us = 0;
|
||||
|
||||
/* Configure clock module and its frequency of tachometer */
|
||||
switch (config->sample_time_us) {
|
||||
case 2:
|
||||
sample_us = TACHO_MONITOR_CLK_2US;
|
||||
break;
|
||||
case 8:
|
||||
sample_us = TACHO_MONITOR_CLK_8US;
|
||||
break;
|
||||
case 16:
|
||||
sample_us = TACHO_MONITOR_CLK_16US;
|
||||
break;
|
||||
case 64:
|
||||
sample_us = TACHO_MONITOR_CLK_64US;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
config->tacho->TACHOCFG = (sample_us << 4) | TACHO_FUNCTION_ENABLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TACH api functions */
|
||||
int tach_kb1200_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
ARG_UNUSED(chan);
|
||||
struct tach_kb1200_data *const data = dev->data;
|
||||
const struct tach_kb1200_config *const config = dev->config;
|
||||
|
||||
/* Check tachometer timeout flag*/
|
||||
if (config->tacho->TACHOPF & TACHO_TIMEOUT_EVENT) {
|
||||
/* Clear timeout flags and update flag */
|
||||
config->tacho->TACHOPF = (TACHO_TIMEOUT_EVENT | TACHO_UPDATE_EVENT);
|
||||
data->capture = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check tachometer update flag is set */
|
||||
if (config->tacho->TACHOPF & TACHO_UPDATE_EVENT) {
|
||||
/* Clear pending flags */
|
||||
config->tacho->TACHOPF = TACHO_UPDATE_EVENT;
|
||||
/* Save captured count */
|
||||
data->capture = config->tacho->TACHOCV & TACHO_CNT_MAX_VALUE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tach_kb1200_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
struct tach_kb1200_data *const data = dev->data;
|
||||
const struct tach_kb1200_config *const config = dev->config;
|
||||
|
||||
if (chan != SENSOR_CHAN_RPM) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (data->capture > 0) {
|
||||
/*
|
||||
* RPM = (60000000/t) / n
|
||||
* t: One Pulses length(us) = sample_time_us * cnt
|
||||
* n: One Round pulses Number
|
||||
*/
|
||||
val->val1 = (60000000 / (config->sample_time_us * data->capture)) /
|
||||
config->pulses_per_round;
|
||||
} else {
|
||||
val->val1 = 0U;
|
||||
}
|
||||
val->val2 = 0U;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TACH driver registration */
|
||||
static int tach_kb1200_init(const struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
const struct tach_kb1200_config *config = dev->config;
|
||||
|
||||
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
tach_kb1200_configure(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api tach_kb1200_driver_api = {
|
||||
.sample_fetch = tach_kb1200_sample_fetch,
|
||||
.channel_get = tach_kb1200_channel_get,
|
||||
};
|
||||
|
||||
#define KB1200_TACH_INIT(inst) \
|
||||
PINCTRL_DT_INST_DEFINE(inst); \
|
||||
static const struct tach_kb1200_config tach_cfg_##inst = { \
|
||||
.tacho = (struct tacho_regs *)DT_INST_REG_ADDR(inst), \
|
||||
.pulses_per_round = DT_INST_PROP(inst, pulses_per_round), \
|
||||
.sample_time_us = DT_INST_PROP(inst, sample_time_us), \
|
||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
|
||||
}; \
|
||||
static struct tach_kb1200_data tach_data_##inst; \
|
||||
SENSOR_DEVICE_DT_INST_DEFINE(inst, tach_kb1200_init, NULL, &tach_data_##inst, \
|
||||
&tach_cfg_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
|
||||
&tach_kb1200_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(KB1200_TACH_INIT)
|
Loading…
Reference in New Issue