From 4dffe8afa30e25f133cdccef7b6b1f1d32286ed7 Mon Sep 17 00:00:00 2001 From: Jacek Maksymowicz Date: Tue, 9 Jul 2024 11:32:36 +0200 Subject: [PATCH] imxrt-multi: add PCT2075 I2C temperature sensor JIRA: NIL-586 --- multi/imxrt-multi/Makefile | 2 +- multi/imxrt-multi/config.h | 12 +++++ multi/imxrt-multi/i2c.c | 42 +++++++++++++++++ multi/imxrt-multi/i2c.h | 13 ++++- multi/imxrt-multi/imxrt-multi.c | 16 +++++++ multi/imxrt-multi/imxrt-multi.h | 2 +- multi/imxrt-multi/pct2075.c | 84 +++++++++++++++++++++++++++++++++ multi/imxrt-multi/pct2075.h | 25 ++++++++++ 8 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 multi/imxrt-multi/pct2075.c create mode 100644 multi/imxrt-multi/pct2075.h diff --git a/multi/imxrt-multi/Makefile b/multi/imxrt-multi/Makefile index b286613b..f970cdc2 100644 --- a/multi/imxrt-multi/Makefile +++ b/multi/imxrt-multi/Makefile @@ -8,7 +8,7 @@ NAME := imxrt-multi LOCAL_PATH := $(call my-dir) -LOCAL_SRCS = imxrt-multi.c common.c uart.c gpio.c spi.c i2c.c fs.c posixsrv.c +LOCAL_SRCS = imxrt-multi.c common.c uart.c gpio.c spi.c i2c.c fs.c posixsrv.c pct2075.c ifneq ($(TARGET_SUBFAMILY), imxrt117x) LOCAL_SRCS += trng.c else diff --git a/multi/imxrt-multi/config.h b/multi/imxrt-multi/config.h index 45d19225..26b06c6e 100644 --- a/multi/imxrt-multi/config.h +++ b/multi/imxrt-multi/config.h @@ -1223,6 +1223,18 @@ #endif /* #ifndef __CPU_IMXRT117X */ +/* Temperature */ + +#ifndef PCT2075 +#define PCT2075 0 +#elif !ISBOOLEAN(PCT2075) +#error "PCT2075 must have a value of 0, 1, or be undefined" +#elif !defined(PCT2075_BUS_NUM) +#error "PCT2075_BUS_NUM must be defined" +#elif !defined(PCT2075_DEV_ADDR) +#error "PCT2075_DEV_ADDR must be defined" +#endif + /* libdummyfs */ #ifndef BUILTIN_DUMMYFS #define BUILTIN_DUMMYFS 0 diff --git a/multi/imxrt-multi/i2c.c b/multi/imxrt-multi/i2c.c index d898650f..c6f4a0a4 100644 --- a/multi/imxrt-multi/i2c.c +++ b/multi/imxrt-multi/i2c.c @@ -491,6 +491,48 @@ void i2c_handleMsg(msg_t *msg, int dev) } +int multi_i2c_busWrite(unsigned bus, uint8_t dev_addr, const uint8_t *data, uint32_t len) +{ + if (bus >= N_PERIPHERALS) { + return -EINVAL; + } + + unsigned pos = i2cPreConfig[bus].pos; + mutexLock(i2c_common[pos].mutex); + int ret = _i2c_busWrite(pos, dev_addr, data, len); + mutexUnlock(i2c_common[pos].mutex); + return ret; +} + + +int multi_i2c_busRead(unsigned bus, uint8_t dev_addr, uint8_t *data_out, uint32_t len) +{ + if (bus >= N_PERIPHERALS) { + return -EINVAL; + } + + unsigned pos = i2cPreConfig[bus].pos; + mutexLock(i2c_common[pos].mutex); + int ret = _i2c_busRead(pos, dev_addr, data_out, len); + mutexUnlock(i2c_common[pos].mutex); + return ret; +} + + +int multi_i2c_regRead(unsigned bus, uint8_t dev_addr, uint8_t reg_addr, uint8_t *data_out, uint32_t len) +{ + if (bus >= N_PERIPHERALS) { + return -EINVAL; + } + + unsigned pos = i2cPreConfig[bus].pos; + mutexLock(i2c_common[pos].mutex); + int ret = _i2c_regRead(pos, dev_addr, reg_addr, data_out, len); + mutexUnlock(i2c_common[pos].mutex); + return ret; +} + + static int i2c_getMuxData(int mux, int *mode, int *isel, int *daisy) { switch (mux) { diff --git a/multi/imxrt-multi/i2c.h b/multi/imxrt-multi/i2c.h index 6aad9adb..2446be5a 100644 --- a/multi/imxrt-multi/i2c.h +++ b/multi/imxrt-multi/i2c.h @@ -3,8 +3,8 @@ * * i.MX RT i2c driver * - * Copyright 2019 Phoenix Systems - * Author: Andrzej Glowinski + * Copyright 2019, 2024 Phoenix Systems + * Author: Andrzej Glowinski, Jacek Maksymowicz * * This file is part of Phoenix-RTOS. * @@ -23,4 +23,13 @@ void i2c_handleMsg(msg_t *msg, int dev); int i2c_init(void); +int multi_i2c_busWrite(unsigned bus, uint8_t dev_addr, const uint8_t *data, uint32_t len); + + +int multi_i2c_busRead(unsigned bus, uint8_t dev_addr, uint8_t *data_out, uint32_t len); + + +int multi_i2c_regRead(unsigned bus, uint8_t dev_addr, uint8_t reg_addr, uint8_t *data_out, uint32_t len); + + #endif diff --git a/multi/imxrt-multi/imxrt-multi.c b/multi/imxrt-multi/imxrt-multi.c index 8fa68bc4..39c126a3 100644 --- a/multi/imxrt-multi/imxrt-multi.c +++ b/multi/imxrt-multi/imxrt-multi.c @@ -43,6 +43,10 @@ #include #endif +#if PCT2075 +#include "pct2075.h" +#endif + #define MULTI_THREADS_NO 2 #define UART_THREADS_NO 2 @@ -145,6 +149,12 @@ static void multi_dispatchMsg(msg_t *msg) break; #endif +#if PCT2075 + case id_temp1: + pct2075_handleMsg(msg); + break; +#endif + default: msg->o.err = -ENODEV; break; @@ -443,6 +453,12 @@ static int createDevFiles(void) } #endif +#endif + +#if PCT2075 + if (mkFile(&dir, id_temp1, "temp1", multi_port) < 0) { + return -1; + } #endif return 0; diff --git a/multi/imxrt-multi/imxrt-multi.h b/multi/imxrt-multi/imxrt-multi.h index 13256301..13f768d2 100644 --- a/multi/imxrt-multi/imxrt-multi.h +++ b/multi/imxrt-multi/imxrt-multi.h @@ -31,7 +31,7 @@ enum { id_console = 0, id_uart1, id_uart2, id_uart3, id_uart4, id_uart5, id_uart id_i2c5, id_i2c6, id_cm4_0, id_cm4_1, id_cm4_2, id_cm4_3, #endif - id_trng, id_pseudoNull, id_pseudoZero, id_pseudoFull, id_pseudoRandom, id_kmsgctrl, + id_trng, id_pseudoNull, id_pseudoZero, id_pseudoFull, id_pseudoRandom, id_kmsgctrl, id_temp1 }; /* clang-format on */ diff --git a/multi/imxrt-multi/pct2075.c b/multi/imxrt-multi/pct2075.c new file mode 100644 index 00000000..a2d7436c --- /dev/null +++ b/multi/imxrt-multi/pct2075.c @@ -0,0 +1,84 @@ +/* + * Phoenix-RTOS + * + * i.MX RT integrated PCT2075 driver + * + * Copyright 2021, 2024 Phoenix Systems + * Author: Marek Bialowas, Jacek Maksymowicz + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + + +#include +#include +#include +#include +#include + +#include +#include "config.h" +#include "i2c.h" +#if PCT2075 + + +static const uint8_t TEMP_REG_ADDR = 0x00u; /* stored temperature value - 16bit */ + + +/* Get temperature in miliCelsius */ +static int pct2075_getTemp(int32_t *tempOut) +{ + uint8_t tempBytes[2]; + int busNum = PCT2075_BUS_NUM; + if (busNum <= 0) { + return -EINVAL; + } + + int ret = multi_i2c_regRead(busNum - 1, PCT2075_DEV_ADDR, TEMP_REG_ADDR, tempBytes, sizeof(tempBytes)); + if (ret < 0) { + return ret; + } + + int16_t tempRaw = ((int16_t)tempBytes[0] << 8) | tempBytes[1]; + *tempOut = (tempRaw >> 5) * 125; + return EOK; +} + + +void pct2075_handleMsg(msg_t *msg) +{ + switch (msg->type) { + case mtOpen: + case mtClose: + msg->o.err = EOK; + break; + case mtWrite: + msg->o.err = -EINVAL; + break; + case mtRead: + /* don't support partial reads, signal EOF */ + if (msg->i.io.offs > 0) { + msg->o.err = 0; /* EOF */ + } + else { + int32_t temp; + int ret = pct2075_getTemp(&temp); + if (ret == EOK) { + ret = snprintf(msg->o.data, msg->o.size, "%d\n", temp); + if ((ret > 0) && ((size_t)ret > msg->o.size)) { + ret = msg->o.size; + } + } + + msg->o.err = ret; + } + break; + default: + msg->o.err = -ENOSYS; + break; + } +} + +#endif /* PCT2075 */ diff --git a/multi/imxrt-multi/pct2075.h b/multi/imxrt-multi/pct2075.h new file mode 100644 index 00000000..b0a56057 --- /dev/null +++ b/multi/imxrt-multi/pct2075.h @@ -0,0 +1,25 @@ +/* + * Phoenix-RTOS + * + * i.MX RT integrated PCT2075 driver + * + * Copyright 2024 Phoenix Systems + * Author: Jacek Maksymowicz + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#ifndef _PCT2075_H_ +#define _PCT2075_H_ + +#include +#include +#include + + +void pct2075_handleMsg(msg_t *msg); + + +#endif /* _PCT2075_H_ */