From 08b0c392ef661bf64e4ac24958b010d08624d681 Mon Sep 17 00:00:00 2001 From: Vinicius Miguel Date: Fri, 30 Aug 2024 13:35:53 +0200 Subject: [PATCH] drivers: adc: Includes MagnTek MT6701 Adds support to the Magnetic Angle Sensor. Signed-off-by: Vinicius Miguel --- CODEOWNERS | 2 + drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/magntek/CMakeLists.txt | 6 + drivers/sensor/magntek/Kconfig | 6 + .../magntek/magntek_mt6701/CMakeLists.txt | 5 + drivers/sensor/magntek/magntek_mt6701/Kconfig | 12 ++ .../magntek/magntek_mt6701/magntek_mt6701.c | 169 ++++++++++++++++++ dts/bindings/sensor/magntek,mt6701.yaml | 9 + dts/bindings/vendor-prefixes.txt | 1 + .../zephyr/drivers/sensor/magntek_mt6701.h | 25 +++ tests/drivers/build_all/sensor/spi.dtsi | 7 + 12 files changed, 244 insertions(+) create mode 100644 drivers/sensor/magntek/CMakeLists.txt create mode 100644 drivers/sensor/magntek/Kconfig create mode 100644 drivers/sensor/magntek/magntek_mt6701/CMakeLists.txt create mode 100644 drivers/sensor/magntek/magntek_mt6701/Kconfig create mode 100644 drivers/sensor/magntek/magntek_mt6701/magntek_mt6701.c create mode 100644 dts/bindings/sensor/magntek,mt6701.yaml create mode 100644 include/zephyr/drivers/sensor/magntek_mt6701.h diff --git a/CODEOWNERS b/CODEOWNERS index b867a245bdfe..d1fab7b9a416 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -318,6 +318,7 @@ /drivers/sensor/lps*/ @avisconti /drivers/sensor/lsm*/ @avisconti /drivers/sensor/mpr/ @sven-hm +/drivers/sensor/magntek/mt6701/magntek_mt6701.c @viniciusmiguel /drivers/sensor/qdec_stm32/ @valeriosetti /drivers/sensor/rpi_pico_temp/ @soburi /drivers/sensor/st*/ @avisconti @@ -487,3 +488,4 @@ /dts/bindings/gpio/*ads114s0x* @benediktibk /dts/bindings/pwm/*max31790* @benediktibk /dts/bindings/dac/*ad56* @benediktibk +/dts/bindings/sensor/magntek,mt6701.yaml @viniciusmiguel diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 0458ed616661..3260180b455a 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory(honeywell) add_subdirectory(infineon) add_subdirectory(ite) add_subdirectory(jedec) +add_subdirectory(magntek) add_subdirectory(maxim) add_subdirectory(meas) add_subdirectory(microchip) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index ad3e8af27d3f..1375b0b6107c 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -95,6 +95,7 @@ source "drivers/sensor/honeywell/Kconfig" source "drivers/sensor/infineon/Kconfig" source "drivers/sensor/ite/Kconfig" source "drivers/sensor/jedec/Kconfig" +source "drivers/sensor/magntek/Kconfig" source "drivers/sensor/maxim/Kconfig" source "drivers/sensor/meas/Kconfig" source "drivers/sensor/microchip/Kconfig" diff --git a/drivers/sensor/magntek/CMakeLists.txt b/drivers/sensor/magntek/CMakeLists.txt new file mode 100644 index 000000000000..a28607f95fe5 --- /dev/null +++ b/drivers/sensor/magntek/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Vinicius Miguel +# SPDX-License-Identifier: Apache-2.0 + +# zephyr-keep-sorted-start +add_subdirectory_ifdef(CONFIG_MAGNTEK_MT6701 magntek_mt6701) +# zephyr-keep-sorted-stop diff --git a/drivers/sensor/magntek/Kconfig b/drivers/sensor/magntek/Kconfig new file mode 100644 index 000000000000..6f6781bdc07b --- /dev/null +++ b/drivers/sensor/magntek/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Vinicius Miguel +# SPDX-License-Identifier: Apache-2.0 + +# zephyr-keep-sorted-start +source "drivers/sensor/magntek/magntek_mt6701/Kconfig" +# zephyr-keep-sorted-stop diff --git a/drivers/sensor/magntek/magntek_mt6701/CMakeLists.txt b/drivers/sensor/magntek/magntek_mt6701/CMakeLists.txt new file mode 100644 index 000000000000..db4621ae0965 --- /dev/null +++ b/drivers/sensor/magntek/magntek_mt6701/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(magntek_mt6701.c) diff --git a/drivers/sensor/magntek/magntek_mt6701/Kconfig b/drivers/sensor/magntek/magntek_mt6701/Kconfig new file mode 100644 index 000000000000..fec835a0c6fc --- /dev/null +++ b/drivers/sensor/magntek/magntek_mt6701/Kconfig @@ -0,0 +1,12 @@ +# MT6701 Angular position sensor configuration option + +# Copyright (c) 2024, Vinicius Miguel +# SPDX-License-Identifier: Apache-2.0 + +config MAGNTEK_MT6701 + bool "MT6701 Angular position sensor" + default y + depends on DT_HAS_MAGNTEK_MT6701_ENABLED + select SPI + help + Enable driver for MT6701 Angular position sensor. diff --git a/drivers/sensor/magntek/magntek_mt6701/magntek_mt6701.c b/drivers/sensor/magntek/magntek_mt6701/magntek_mt6701.c new file mode 100644 index 000000000000..1977df2b9e96 --- /dev/null +++ b/drivers/sensor/magntek/magntek_mt6701/magntek_mt6701.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2024, Vinicius Miguel + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT magntek_mt6701 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(magntek_mt6701, CONFIG_SENSOR_LOG_LEVEL); + +#define MT6701_SPI_CONFIG SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(8) +#define MT6701_FULL_ANGLE 360 +#define MT6701_PULSES_PER_REV 4096 +#define MT6701_MILLION_UNIT 1000000 + +struct mt6701_dev_cfg { + struct spi_dt_spec spi_port; +}; + +struct mt6701_dev_data { + uint32_t position; + uint8_t field_status; + int8_t push_status; + uint8_t loss_status; +}; + +static uint8_t table_crc[64] = {0x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09, 0x18, 0x1B, 0x1E, + 0x1D, 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, + 0x3A, 0x39, 0x28, 0x2B, 0x2E, 0x2D, 0x24, 0x27, 0x22, 0x21, 0x23, + 0x20, 0x25, 0x26, 0x2F, 0x2C, 0x29, 0x2A, 0x3B, 0x38, 0x3D, 0x3E, + 0x37, 0x34, 0x31, 0x32, 0x13, 0x10, 0x15, 0x16, 0x1F, 0x1C, 0x19, + 0x1A, 0x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02}; + +static uint8_t mt6701_crc_check(uint32_t input) +{ + uint8_t index = 0; + uint8_t crc = 0; + + index = (uint8_t)(((uint32_t)input >> 12u) & 0x0000003Fu); + + crc = (uint8_t)(((uint32_t)input >> 6u) & 0x0000003Fu); + index = crc ^ table_crc[index]; + + crc = (uint8_t)((uint32_t)input & 0x0000003Fu); + index = crc ^ table_crc[index]; + + crc = table_crc[index]; + + return crc; +} + +static int mt6701_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct mt6701_dev_data *dev_data = dev->data; + const struct mt6701_dev_cfg *dev_cfg = dev->config; + + uint32_t spi_32 = 0; + uint32_t angle_spi = 0; + uint8_t received_crc = 0; + + uint8_t read_data[3] = {0, 0, 0}; + + const struct spi_buf rx_buf[] = {{ + .buf = read_data, + .len = ARRAY_SIZE(read_data), + }}; + + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(read_data), + }; + + int err = spi_read_dt(&dev_cfg->spi_port, &rx); + + /* an invalid reading preserves the last good value */ + if (!err) { + + /* + * [0:13] Angle data + * [14:17] Magnetic field status + * [18:23] CRC + */ + + spi_32 = (read_data[0] << 16) | (read_data[1] << 8) | read_data[2]; + angle_spi = spi_32 >> 10; + received_crc = spi_32 & 0x3F; + + if (received_crc == mt6701_crc_check(spi_32 >> 6)) { + dev_data->field_status = (spi_32 >> 6) & 0x3; + dev_data->push_status = (spi_32 >> 8) & 0x1; + dev_data->loss_status = (spi_32 >> 9) & 0x1; + dev_data->position = angle_spi; + } else { + err = -EILSEQ; + } + } + + return err; +} + +static int mt6701_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) +{ + struct mt6701_dev_data *dev_data = dev->data; + float new_angle = 0; + double integer = 0; + + switch ((int16_t)chan) { + case SENSOR_CHAN_ROTATION: + new_angle = ((float)dev_data->position / MT6701_PULSES_PER_REV) * MT6701_FULL_ANGLE; + val->val2 = (int32_t)(modf(new_angle, &integer) * MT6701_MILLION_UNIT); + val->val1 = (int32_t)integer; + break; + case SENSOR_CHAN_FIELD_STATUS: + val->val1 = dev_data->field_status; + val->val2 = 0; + break; + case SENSOR_CHAN_PUSH_STATUS: + val->val1 = dev_data->push_status; + val->val2 = 0; + break; + case SENSOR_CHAN_LOSS_STATUS: + val->val1 = dev_data->loss_status; + val->val2 = 0; + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static int mt6701_initialize(const struct device *dev) +{ + struct mt6701_dev_data *const dev_data = dev->data; + + dev_data->position = 0; + + LOG_INF("Device %s initialized", dev->name); + + return 0; +} + +static const struct sensor_driver_api mt6701_driver_api = { + .sample_fetch = mt6701_fetch, + .channel_get = mt6701_get, +}; + +#define MT6701_INIT(n) \ + static struct mt6701_dev_data mt6701_data##n; \ + static const struct mt6701_dev_cfg mt6701_cfg##n = { \ + .spi_port = SPI_DT_SPEC_INST_GET(n, MT6701_SPI_CONFIG, 0), \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(n, mt6701_initialize, NULL, &mt6701_data##n, &mt6701_cfg##n, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &mt6701_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MT6701_INIT) diff --git a/dts/bindings/sensor/magntek,mt6701.yaml b/dts/bindings/sensor/magntek,mt6701.yaml new file mode 100644 index 000000000000..00308b436556 --- /dev/null +++ b/dts/bindings/sensor/magntek,mt6701.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Vinicius Miguel +# SPDX-License-Identifier: Apache-2.0 + +description: | + MagnTek MT6701 Angular position sensor + +compatible: "magntek,mt6701" + +include: [sensor-device.yaml, spi-device.yaml] diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index b243c8e61162..5ff0be79d3b9 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -393,6 +393,7 @@ lxa Linux Automation GmbH m5stack M5Stack macnica Macnica Americas madmachine Shenzhen FeiKaiTe Technology Co., Ltd. +magntek Shanghai MagnTek Microelectronics Inc. makerdiary Shenzhen Zaowubang Technology Co., Ltd. mantix Mantix Display Technology Co.,Ltd. mapleboard Mapleboard.org diff --git a/include/zephyr/drivers/sensor/magntek_mt6701.h b/include/zephyr/drivers/sensor/magntek_mt6701.h new file mode 100644 index 000000000000..93885f205e95 --- /dev/null +++ b/include/zephyr/drivers/sensor/magntek_mt6701.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Vinicius Miguel + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_MAGNTEK_MT6701_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_MAGNTEK_MT6701_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +enum sensor_channel_mt6701 { + SENSOR_CHAN_FIELD_STATUS = SENSOR_CHAN_PRIV_START, + SENSOR_CHAN_PUSH_STATUS, + SENSOR_CHAN_LOSS_STATUS +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index c173c5ccecb6..6088ae5ab920 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -379,3 +379,10 @@ test_spi_tle9104: tle9104@2e { #sensor-cells = <0>; }; }; + +test_spi_mt6701: mt6701@2f { + compatible = "magntek,mt6701"; + reg = <0x2f>; + spi-max-frequency = <0>; + status = "okay"; +};