Skip to content

Commit

Permalink
imxrt-multi: add PCT2075 I2C temperature sensor
Browse files Browse the repository at this point in the history
Export functions from i2c.c to allow access to I2C busses from other
multidriver files.
Change some error codes returned from I2C driver.

JIRA: NIL-586
  • Loading branch information
jmaksymowicz authored and Darchiv committed Jul 23, 2024
1 parent 99a6833 commit 040859c
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 10 deletions.
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_ */

0 comments on commit 040859c

Please sign in to comment.