drivers/sensors: Add CXD5602PWBIMU driver for IMU Add-on board

Add CXD5602PWBIMU driver for IMU Add-on board.

Signed-off-by: SPRESENSE <41312067+SPRESENSE@users.noreply.github.com>
This commit is contained in:
SPRESENSE
2025-03-24 16:22:26 +09:00
committed by Alan C. Assis
parent 0bbdeb4b22
commit 64b97bda5d
12 changed files with 2423 additions and 0 deletions
+4
View File
@@ -189,5 +189,9 @@ if(CONFIG_ARCH_BOARD_COMMON)
list(APPEND SRCS src/cxd56_gnss_addon.c)
endif()
if(CONFIG_SENSORS_CXD5602PWBIMU)
list(APPEND SRCS src/cxd56_cxd5602pwbimu.c)
endif()
target_sources(board PRIVATE ${SRCS})
endif()
+4
View File
@@ -190,6 +190,10 @@ ifeq ($(CONFIG_CXD56_GNSS_ADDON),y)
CSRCS += cxd56_gnss_addon.c
endif
ifeq ($(CONFIG_SENSORS_CXD5602PWBIMU),y)
CSRCS += cxd56_cxd5602pwbimu.c
endif
DEPPATH += --dep-path src
VPATH += :src
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src
@@ -0,0 +1,261 @@
/****************************************************************************
* boards/arm/cxd56xx/common/src/cxd56_cxd5602pwbimu.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/board.h>
#include <nuttx/spi/spi.h>
#include <arch/chip/pin.h>
#include <arch/board/board.h>
#include "cxd56_gpio.h"
#include "cxd56_gpioint.h"
#include "cxd56_spi.h"
#include "cxd56_dmac.h"
#include "cxd56_i2c.h"
#include <nuttx/sensors/cxd5602pwbimu.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define PIN_POWER PIN_EMMC_DATA2
#define PIN_XRST PIN_I2S0_BCK
#define PIN_SPI_DRDY PIN_EMMC_DATA3
#define PIN_SPI_CSX PIN_I2S0_DATA_IN
#define SETUP_PIN_INPUT(pin) \
do \
{ \
board_gpio_write(pin, -1); \
board_gpio_config(pin, 0, true, false, PIN_PULLDOWN); \
} \
while (0)
#define SETUP_PIN_OUTPUT(pin) \
do \
{ \
board_gpio_write(pin, -1); \
board_gpio_config(pin, 0, false, true, PIN_FLOAT); \
} \
while (0)
#if defined(CONFIG_CXD56_CXD5602PWBIMU_SPI5_DMAC)
#define PWBIMU_MAX_PACKET_SIZE (34)
#define PWBIMU_DMA_TXCH (4)
#define PWBIMU_DMA_RXCH (5)
#define PWBIMU_DMA_TXCHCHG (CXD56_DMA_PERIPHERAL_SPI5_TX)
#define PWBIMU_DMA_RXCHCFG (CXD56_DMA_PERIPHERAL_SPI5_RX)
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int cxd5602pwbimu_irq_attach(const cxd5602pwbimu_config_t *state,
xcpt_t isr, void *arg);
static void cxd5602pwbimu_irq_enable(const cxd5602pwbimu_config_t *state,
bool enable);
static void cxd5602pwbimu_csx(const cxd5602pwbimu_config_t *state,
bool pol);
static void cxd5602pwbimu_power(const cxd5602pwbimu_config_t *state,
bool pol);
static void cxd5602pwbimu_reset(const cxd5602pwbimu_config_t *state,
bool assert);
/****************************************************************************
* Private Data
****************************************************************************/
static cxd5602pwbimu_config_t g_config =
{
.irq_attach = cxd5602pwbimu_irq_attach,
.irq_enable = cxd5602pwbimu_irq_enable,
.csx = cxd5602pwbimu_csx,
.power = cxd5602pwbimu_power,
.reset = cxd5602pwbimu_reset,
};
/****************************************************************************
* Private Functions
****************************************************************************/
/* Attach the CXD5602PWBIMU interrupt handler to the GPIO interrupt */
static int cxd5602pwbimu_irq_attach(const cxd5602pwbimu_config_t *state,
xcpt_t isr, void *arg)
{
sninfo("cxd5602pwbimu_irq_attach\n");
cxd56_gpioint_config(PIN_SPI_DRDY, GPIOINT_LEVEL_HIGH, isr, arg);
return OK;
}
/* Enable or disable the GPIO interrupt */
static void cxd5602pwbimu_irq_enable(const cxd5602pwbimu_config_t *state,
bool enable)
{
sninfo("%d\n", enable);
board_gpio_int(PIN_SPI_DRDY, enable);
}
/* Toggle the csx pin level */
static void cxd5602pwbimu_csx(const cxd5602pwbimu_config_t *state,
bool pol)
{
sninfo("%d\n", pol);
/* delay for csx rising edge */
if (pol == true)
{
up_udelay(5);
}
/* toggle csx pin */
board_gpio_write(PIN_SPI_CSX, pol);
/* delay for csx falling edge */
if (pol == false)
{
up_udelay(5);
}
}
static void cxd5602pwbimu_power(const cxd5602pwbimu_config_t *state,
bool pol)
{
sninfo("%d\n", pol);
/* toggle power pin */
board_gpio_write(PIN_POWER, pol);
/* wait power level settling */
up_mdelay(2);
}
static void cxd5602pwbimu_reset(const cxd5602pwbimu_config_t *state,
bool assert)
{
board_gpio_write(PIN_XRST, !assert);
}
/****************************************************************************
* Public Functions
****************************************************************************/
#if defined(CONFIG_CXD56_SPI) && defined(CONFIG_SENSORS_CXD5602PWBIMU)
int board_cxd5602pwbimu_initialize(int bus)
{
int ret;
struct spi_dev_s *spi;
struct i2c_master_s *i2c;
#if defined(CONFIG_CXD56_CXD5602PWBIMU_SPI5_DMAC)
DMA_HANDLE hdl;
dma_config_t conf;
#endif
cxd5602pwbimu_config_t *config = &g_config;
sninfo("Initializing CXD5602PWBIMU..\n");
/* Initialize pins */
SETUP_PIN_OUTPUT(PIN_POWER);
SETUP_PIN_OUTPUT(PIN_XRST);
config->reset(config, true);
SETUP_PIN_OUTPUT(PIN_SPI_CSX);
config->csx(config, true);
SETUP_PIN_INPUT(PIN_SPI_DRDY);
/* Initialize spi device */
spi = cxd56_spibus_initialize(bus);
if (!spi)
{
snerr("ERROR: Failed to initialize spi%d.\n", bus);
return -ENODEV;
}
#if defined(CONFIG_CXD56_CXD5602PWBIMU_SPI5_DMAC)
hdl = cxd56_dmachannel(PWBIMU_DMA_TXCH,
PWBIMU_MAX_PACKET_SIZE);
if (hdl)
{
conf.channel_cfg = PWBIMU_DMA_TXCHCHG;
conf.dest_width = CXD56_DMAC_WIDTH8;
conf.src_width = CXD56_DMAC_WIDTH8;
cxd56_spi_dmaconfig(bus, CXD56_SPI_DMAC_CHTYPE_TX, hdl, &conf);
}
hdl = cxd56_dmachannel(PWBIMU_DMA_RXCH,
PWBIMU_MAX_PACKET_SIZE);
if (hdl)
{
conf.channel_cfg = PWBIMU_DMA_RXCHCFG;
conf.dest_width = CXD56_DMAC_WIDTH8;
conf.src_width = CXD56_DMAC_WIDTH8;
cxd56_spi_dmaconfig(bus, CXD56_SPI_DMAC_CHTYPE_RX, hdl, &conf);
}
#endif
/* Initialize i2c device */
i2c = cxd56_i2cbus_initialize(0);
if (!i2c)
{
snerr("ERROR: Failed to initialize i2c%d.\n", 0);
return -ENODEV;
}
ret = cxd5602pwbimu_register("/dev/imu0", spi, i2c, config);
if (ret < 0)
{
snerr("Error registering CXD5602PWBIMU\n");
}
return ret;
}
#endif
+19
View File
@@ -871,4 +871,23 @@ config CXD56_GNSS_ADDON_LATE_INITIALIZE
endif # CXD56_GNSS_ADDON
menu "CXD5602PWBIMU Add-on board"
depends on SENSORS_CXD5602PWBIMU
config CXD56_CXD5602PWBIMU_SPI5_DMAC
bool "Use DMAC on data transfer"
default y
select CXD56_SPI5
select CXD56_DMAC_SPI5_TX
select CXD56_DMAC_SPI5_RX
config CXD56_CXD5602PWBIMU_LATE_INITIALIZE
bool "CXD5602PWBIMU driver late initialization"
default n
---help---
The CXD5602PWBIMU driver can be initialized on an application code
after system booted up by enabling this configuration switch.
endmenu # CXD5602PWBIMU Add-on board
endif
@@ -69,6 +69,7 @@
#include "cxd56_scd41.h"
#include "cxd56_sensors.h"
#include "cxd56_gnss_addon.h"
#include "cxd56_cxd5602pwbimu.h"
#ifdef CONFIG_VIDEO_ISX012
# include "cxd56_isx012.h"
@@ -0,0 +1,71 @@
/****************************************************************************
* boards/arm/cxd56xx/spresense/include/cxd56_cxd5602pwbimu.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_CXD5602PWBIMU_H
#define __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_CXD5602PWBIMU_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: board_cxd5602pwbimu_initialize
*
* Description:
* Initialize CXD5602PWBIMU spi driver and register the CXD5602PWBIMU device.
*
****************************************************************************/
int board_cxd5602pwbimu_initialize(int bus);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_CXD5602PWBIMU_H */
@@ -267,6 +267,15 @@ int cxd56_bringup(void)
scu_initialize();
#endif
#if defined(CONFIG_SENSORS_CXD5602PWBIMU) && \
!defined(CONFIG_CXD56_CXD5602PWBIMU_LATE_INITIALIZE)
ret = board_cxd5602pwbimu_initialize(5);
if (ret < 0)
{
_err("ERROR: Failed to initialize CXD5602PWBIMU.\n");
}
#endif
#ifdef CONFIG_CXD56_I2C_DRIVER
#ifdef CONFIG_CXD56_I2C0
ret = board_i2cdev_initialize(0);
+6
View File
@@ -450,5 +450,11 @@ if(CONFIG_SENSORS)
list(APPEND SRCS hdc1008.c)
endif()
# SONY CXD5602PWBIMU
if(CONFIG_SENSORS_CXD5602PWBIMU)
list(APPEND SRCS cxd5602pwbimu.c)
endif()
target_sources(drivers PRIVATE ${SRCS})
endif()
+55
View File
@@ -432,6 +432,61 @@ config SENSORS_BMM150_THREAD_STACKSIZE
endif # SENSORS_BMM150
config SENSORS_CXD5602PWBIMU
bool "SONY CXD5602PWBIMU Inertial Measurement Sensor support"
default n
select SPI
select I2C
---help---
Enable driver support for the SONY CXD5602PWBIMU Inertial
Measurement sensor
if SENSORS_CXD5602PWBIMU
config SENSORS_CXD5602PWBIMU_NR_BUFFERS
int "Number of buffers to retrieve sensing data"
default 16
config SENSORS_CXD5602PWBIMU_OVERWRITE
bool "Overwrite circular buffer"
default y
config SENSORS_CXD5602PWBIMU_NPOLLWAITERS
int "Number of waiters to poll"
default 1
---help---
Number of waiters to poll
config SENSORS_CXD5602PWBIMU_I2C_ADDRS_AUTO
bool "I2C address auto detection"
default y
---help---
Number of waiters to poll
if !SENSORS_CXD5602PWBIMU_I2C_ADDRS_AUTO
choice
prompt "I2C address selection"
default SENSORS_CXD5602PWBIMU_I2C_ADDRS_PRIMARY
config SENSORS_CXD5602PWBIMU_I2C_ADDRS_PRIMARY
bool "Primary address series"
---help---
DipSW[2] -> off
Using address: 0x10, 0x11, 0x12, 0x13
config SENSORS_CXD5602PWBIMU_I2C_ADDRS_SECONDARY
bool "Secondary address series"
---help---
DipSW[2] -> on
Using address: 0x30, 0x31, 0x32, 0x33
endchoice
endif # !SENSORS_CXD5602PWBIMU_I2C_ADDRS_AUTO
endif # SENSORS_CXD5602PWBIMU
config SENSORS_BMP180
bool "Bosch BMP180 Barometer Sensor support"
default n
+6
View File
@@ -450,6 +450,12 @@ ifeq ($(CONFIG_SENSORS_MAX31865),y)
CSRCS += max31865.c
endif
# SONY CXD5602PWBIMU
ifeq ($(CONFIG_SENSORS_CXD5602PWBIMU),y)
CSRCS += cxd5602pwbimu.c
endif
# Include sensor driver build support
DEPPATH += --dep-path sensors
File diff suppressed because it is too large Load Diff
+172
View File
@@ -0,0 +1,172 @@
/****************************************************************************
* include/nuttx/sensors/cxd5602pwbimu.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_SENSORS_CXD5602PWBIMU_H
#define __INCLUDE_NUTTX_SENSORS_CXD5602PWBIMU_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/fs/ioctl.h>
#include <sys/types.h>
#include <nuttx/spi/spi.h>
#include <nuttx/i2c/i2c_master.h>
#if defined(CONFIG_SENSORS_CXD5602PWBIMU)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* IOCTL Commands ***********************************************************/
#define SNIOC_ENABLE _SNIOC(0x0001)
#define SNIOC_SSAMPRATE _SNIOC(0x0002)
#define SNIOC_SDRANGE _SNIOC(0x0003)
#define SNIOC_SCALIB _SNIOC(0x0004)
#define SNIOC_SFIFOTHRESH _SNIOC(0x0005)
#define SNIOC_UPDATEFW _SNIOC(0x0010)
#define SNIOC_SETDATASIZE _SNIOC(0x0080)
#define SNIOC_WREGSPI _SNIOC(0x0081)
#define SNIOC_RREGSPI _SNIOC(0x0082)
#define SNIOC_WREGS _SNIOC(0x0083)
#define SNIOC_RREGS _SNIOC(0x0084)
#define SNIOC_RREGS_WOADR _SNIOC(0x0085)
#define SNIOC_GETBNUM _SNIOC(0x0086)
/****************************************************************************
* Public Types
****************************************************************************/
/* Interrupt configuration data structure */
typedef struct cxd5602pwbimu_config_s
{
CODE int (*irq_attach)(FAR const struct cxd5602pwbimu_config_s *state,
xcpt_t isr, FAR void *arg);
CODE void (*irq_enable)(FAR const struct cxd5602pwbimu_config_s *state,
bool enable);
CODE void (*csx)(FAR const struct cxd5602pwbimu_config_s *state,
bool pol);
CODE void (*power)(FAR const struct cxd5602pwbimu_config_s *state,
bool pol);
CODE void (*reset)(FAR const struct cxd5602pwbimu_config_s *state,
bool assert);
} cxd5602pwbimu_config_t;
/****************************************************************************
* struct 6-axis data
****************************************************************************/
struct cxd5602pwbimu_data_s
{
uint32_t timestamp; /* timestamp */
float temp; /* temperature */
float gx; /* gyro x */
float gy; /* gyro y */
float gz; /* gyro z */
float ax; /* accel x */
float ay; /* accel y */
float az; /* accel z */
};
typedef struct cxd5602pwbimu_data_s cxd5602pwbimu_data_t;
struct cxd5602pwbimu_range_s
{
int accel; /* 2, 4, 8, 16 */
int gyro; /* 125, 250, 500, 1000, 2000, 4000 */
};
typedef struct cxd5602pwbimu_range_s cxd5602pwbimu_range_t;
begin_packed_struct struct cxd5602pwbimu_calib_s
{
uint8_t offset;
uint32_t coef;
} end_packed_struct;
typedef struct cxd5602pwbimu_calib_s cxd5602pwbimu_calib_t;
struct cxd5602pwbimu_regs_s
{
uint8_t addr; /* Register address */
FAR uint8_t *value; /* Write value or read value */
uint8_t len; /* Length of value */
int slaveid; /* Target 0=master, 1,2,3=slave{1,2,3} */
};
typedef struct cxd5602pwbimu_regs_s cxd5602pwbimu_regs_t;
struct cxd5602pwbimu_updatefw_s
{
FAR const char *path;
void (*progress)(off_t current, off_t total);
};
typedef struct cxd5602pwbimu_updatefw_s cxd5602pwbimu_updatefw_t;
struct spi_dev_s;
struct i2c_master_s;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: cxd5602pwbimu_register
*
* Description:
* Register the CXD5602PWBIMU character device as 'devpath'
*
* Input Parameters:
* devpath - The full path to the driver to register. E.g., "/dev/imu0"
* dev_spi - An instance of the SPI interface to use to communicate
* with CXD5602PWBIMU
* dev_i2c - An instance of the I2C interface to use to communicate
* with CXD5602PWBIMU
* config - An instance of the interrupt configuration data structure
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int cxd5602pwbimu_register(FAR const char *devpath,
FAR struct spi_dev_s *dev_spi,
FAR struct i2c_master_s *dev_i2c,
FAR cxd5602pwbimu_config_t *config);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_SENSORS_CXD5602PWBIMU */
#endif /* __INCLUDE_NUTTX_SENSORS_CXD5602PWBIMU_H */