I have been trying to interface the Witmotion WT901 sensor with the nRF5340 using the I2C interface. I have previously run the exact code on the nRF52DK and it was working perfectly well. However, when I try the same code for nRF5340, the sensor values I get are 0. I originally got the code by converting the provided STM SDK for the nRF52. I have also tried using the TWIM as an alternative but with the same results. Is there a hardware or project settings issue? I am using the i2c1 with P1.02 as SDA and P1.03 as the SCL.
Here is my main.c code.
#include <zephyr/kernel.h>
#include <stdio.h>
#include <dk_buttons_and_leds.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/shell/shell.h>
#include <zephyr/shell/shell_uart.h>
#include <drivers/include/nrfx_twim.h>
#include <string.h>
#include "REG.h"
#define ACC_UPDATE 0x01
#define GYRO_UPDATE 0x02
#define ANGLE_UPDATE 0x04
#define MAG_UPDATE 0x08
#define READ_UPDATE 0x80
// Return message
#define WIT_HAL_OK (0) /**< There is no error */
#define WIT_HAL_BUSY (-1) /**< Busy */
#define WIT_HAL_TIMEOUT (-2) /**< Timed out */
#define WIT_HAL_ERROR (-3) /**< A generic error happens */
#define WIT_HAL_NOMEM (-4) /**< No memory */
#define WIT_HAL_EMPTY (-5) /**< The resource is empty */
#define WIT_HAL_INVAL (-6) /**< Invalid argument */
#define WIT_DATA_BUFF_SIZE 256
// Protocols selection
#define WIT_PROTOCOL_NORMAL 0
#define WIT_PROTOCOL_MODBUS 1
#define WIT_PROTOCOL_CAN 2
#define WIT_PROTOCOL_I2C 3
// Nordic related declarations
#define I2C1_NODE DT_NODELABEL(witsensor)
// static const nrfx_twim_t dev_i2c = NRF_TWIM_INSTANCE(I2C1_NODE);
static const struct i2c_dt_spec dev_i2c = I2C_DT_SPEC_GET(I2C1_NODE);
// Wit related declarations
int16_t sReg[REGSIZE];
static volatile char s_cDataUpdate = 0, s_cCmd = 0xff;
static uint8_t s_ucAddr = 0xff;
static uint8_t s_ucWitDataBuff[WIT_DATA_BUFF_SIZE];
static uint32_t s_uiWitDataCnt = 0, s_uiProtoclo = 0, s_uiReadRegIndex = 0;
// Function prototypes
typedef int32_t (*WitI2cWrite)(const struct i2c_dt_spec *spec, const uint8_t *buf,
uint32_t num_bytes);
typedef int32_t (*WitI2cRead)(const struct i2c_dt_spec *spec, uint8_t *buf, uint32_t num_bytes);
typedef void (*RegUpdateCb)(uint32_t uiReg, uint32_t uiRegNum);
int32_t WitInit(uint32_t uiProtocol, uint8_t ucAddr);
int32_t WitI2cFuncRegister(WitI2cWrite write_func, WitI2cRead read_func);
int32_t WitRegisterCallBack(RegUpdateCb update_func);
static void SensorDataUpdata(uint32_t uiReg, uint32_t uiRegNum);
// Protocol states
static WitI2cWrite p_WitI2cWriteFunc = NULL;
static WitI2cRead p_WitI2cReadFunc = NULL;
static RegUpdateCb p_WitRegUpdateCbFunc = NULL;
int32_t WitInit(uint32_t uiProtocol, uint8_t ucAddr)
{
if (uiProtocol > WIT_PROTOCOL_I2C) {
return WIT_HAL_INVAL;
}
s_uiProtoclo = uiProtocol;
s_ucAddr = ucAddr;
s_uiWitDataCnt = 0;
return WIT_HAL_OK;
}
int32_t WitI2cFuncRegister(WitI2cWrite write_func, WitI2cRead read_func)
{
if (!write_func) {
return WIT_HAL_INVAL;
}
if (!read_func) {
return WIT_HAL_INVAL;
}
p_WitI2cWriteFunc = write_func;
p_WitI2cReadFunc = read_func;
return WIT_HAL_OK;
}
int32_t WitRegisterCallBack(RegUpdateCb update_func)
{
if (!update_func) {
return WIT_HAL_INVAL;
}
p_WitRegUpdateCbFunc = update_func;
return WIT_HAL_OK;
}
static void SensorDataUpdata(uint32_t uiReg, uint32_t uiRegNum)
{
int i;
for (i = 0; i < uiRegNum; i++) {
switch (uiReg) {
// case AX:
// case AY:
case AZ:
s_cDataUpdate |= ACC_UPDATE;
break;
// case GX:
// case GY:
case GZ:
s_cDataUpdate |= GYRO_UPDATE;
break;
// case HX:
// case HY:
case HZ:
s_cDataUpdate |= MAG_UPDATE;
break;
// case Roll:
// case Pitch:
case Yaw:
s_cDataUpdate |= ANGLE_UPDATE;
break;
default:
s_cDataUpdate |= READ_UPDATE;
break;
}
uiReg++;
}
}
int32_t WitReadReg(uint32_t uiReg, uint32_t uiReadNum)
{
uint16_t usTemp, i;
uint8_t ucBuff[8];
if ((uiReg + uiReadNum) >= REGSIZE) {
return WIT_HAL_INVAL;
}
if (p_WitI2cReadFunc == NULL) {
return WIT_HAL_EMPTY;
}
usTemp = uiReadNum << 1;
if (WIT_DATA_BUFF_SIZE < usTemp) {
return WIT_HAL_NOMEM;
}
if (i2c_write_read_dt(&dev_i2c, &uiReg, 1, s_ucWitDataBuff, usTemp) == 0) {
if (p_WitRegUpdateCbFunc == NULL) {
return WIT_HAL_EMPTY;
}
for (i = 0; i < uiReadNum; i++) {
sReg[i + uiReg] = ((uint16_t)s_ucWitDataBuff[(i << 1) + 1] << 8) |
s_ucWitDataBuff[i << 1];
}
p_WitRegUpdateCbFunc(uiReg, uiReadNum);
} else {
("Failed to write / read I2C device address %x at Reg. %x \n\r ", dev_i2c.addr,
uiReg);
s_uiReadRegIndex = uiReg;
}
s_uiReadRegIndex = uiReg;
return WIT_HAL_OK;
}
int main(void)
{
// 0x50 is the default sensor target address
WitInit(WIT_PROTOCOL_I2C, 0x50);
// Store the write and read functions
WitI2cFuncRegister(i2c_write_dt, i2c_read_dt);
// register to get sensor data callback function
WitRegisterCallBack(SensorDataUpdata);
int i;
float fAcc[3], fGyro[3], fAngle[3];
while (1) {
// Read sensor data at intervals
WitReadReg(AX, 12);
for (i = 0; i < 3; i++) {
fAcc[i] = sReg[AX + i] / 32768.0f * 16.0f;
fGyro[i] = sReg[GX + i] / 32768.0f * 2000.0f;
fAngle[i] = sReg[Roll + i] / 32768.0f * 180.0f;
}
if (s_cDataUpdate & ACC_UPDATE) {
printf("acc:%.3f %.3f %.3f\r\n", fAcc[0], fAcc[1], fAcc[2]);
s_cDataUpdate &= ~ACC_UPDATE;
}
if (s_cDataUpdate & GYRO_UPDATE) {
printf("gyro:%.3f %.3f %.3f\r\n", fGyro[0], fGyro[1], fGyro[2]);
s_cDataUpdate &= ~GYRO_UPDATE;
}
if (s_cDataUpdate & ANGLE_UPDATE) {
printf("angle:%.3f %.3f %.3f\r\n", fAngle[0], fAngle[1], fAngle[2]);
s_cDataUpdate &= ~ANGLE_UPDATE;
}
if (s_cDataUpdate & MAG_UPDATE) {
printf("mag:%d %d %d\r\n", sReg[HX], sReg[HY], sReg[HZ]);
s_cDataUpdate &= ~MAG_UPDATE;
}
printf("angle:%.3f %.3f %.3f\r\n", fAngle[0], fAngle[1], fAngle[2]);
}
return 0;
}
My overlay file:
&i2c1 {
compatible = "nordic,nrf-twim";
status = "okay";
clock-frequency = <I2C_BITRATE_STANDARD>;
witsensor: witsensor@50 {
compatible = "i2c-device";
reg = <0x50>;
label = "witsensor";
};
};
And for my prj.conf
CONFIG_I2C=y CONFIG_CBPRINTF_FP_SUPPORT=y