Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

imxrt-multi: add PCT2075 I2C temperature sensor #506

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion multi/imxrt-multi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions multi/imxrt-multi/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
52 changes: 46 additions & 6 deletions multi/imxrt-multi/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
#include <i2c-msg.h>
#include <errno.h>

#include <board_config.h>
#include "common.h"
#include "config.h"
#include "trace.h"


Expand Down Expand Up @@ -232,7 +230,7 @@ static inline int _i2c_getAndClearStatus(volatile uint32_t *base)
*(base + msr) = status;

if ((status & STATUS_PIN_LOW_TIMEOUT) != 0) {
return -ETIME;
return -ETIMEDOUT;
}
else if ((status & STATUS_FIFO_ERROR) != 0) {
return -EIO;
Expand All @@ -241,7 +239,7 @@ static inline int _i2c_getAndClearStatus(volatile uint32_t *base)
return -EIO;
}
else if ((status & STATUS_NACK) != 0) {
return -ENOENT;
return -ENXIO;
}
else if ((status & STATUS_STOP) != 0) {
return RET_STOP;
Expand All @@ -266,7 +264,7 @@ static int _i2c_waitForInterrupt(int pos, uint32_t bitWait)
*(base + mier) = 0;
/* More cleanup will be done by _i2c_finishTransaction */
mutexUnlock(i2c_common[pos].irqMutex);
return -ETIME;
return -ETIMEDOUT;
}
} while (i2c_common[pos].state != i2c_stateReady);

Expand Down Expand Up @@ -375,7 +373,7 @@ static int _i2c_finishTransaction(int pos, int ret)
ret = -EIO;
}

if (ret == -ETIME) {
if (ret == -ETIMEDOUT) {
mutexLock(i2c_common[pos].irqMutex);
i2c_common[pos].state = i2c_stateReady;
/* cond may have been signalled before we turned off IRQ - try to take it to ensure it's
Expand Down Expand Up @@ -491,6 +489,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) {
Expand Down
13 changes: 11 additions & 2 deletions multi/imxrt-multi/i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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
16 changes: 16 additions & 0 deletions multi/imxrt-multi/imxrt-multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
#include <pseudodev.h>
#endif

#if PCT2075
#include "pct2075.h"
#endif

#define MULTI_THREADS_NO 2
#define UART_THREADS_NO 2

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion multi/imxrt-multi/imxrt-multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
83 changes: 83 additions & 0 deletions multi/imxrt-multi/pct2075.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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 <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include "common.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 */
25 changes: 25 additions & 0 deletions multi/imxrt-multi/pct2075.h
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>
#include <stddef.h>
#include <sys/msg.h>


void pct2075_handleMsg(msg_t *msg);


#endif /* _PCT2075_H_ */
Loading