mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
sim: Initial Linux i2c bus support
This adds the inital wiring for i2c bus support in the sim target and for Linux host adds the lower half that uses the i2c chardev. Signed-off-by: Brennan Ashton <bashton@brennanashton.com>
This commit is contained in:
parent
2dfd7a4e8f
commit
54832f37f2
10 changed files with 534 additions and 6 deletions
|
@ -534,6 +534,36 @@ config SIM_HCISOCKET
|
|||
control of the device, but is abstracted from the
|
||||
physical interface which is still handled by Linux.
|
||||
|
||||
config SIM_I2CBUS
|
||||
bool "Simulated I2C Bus"
|
||||
default n
|
||||
select I2C
|
||||
---help---
|
||||
Build in support for simulated i2c bus
|
||||
|
||||
if SIM_I2CBUS
|
||||
|
||||
choice
|
||||
prompt "Simulated I2C Bus Type"
|
||||
default SIM_I2CBUS_LINUX
|
||||
|
||||
config SIM_I2CBUS_LINUX
|
||||
bool "Linux I2C Bus Character Dev"
|
||||
depends on HOST_LINUX
|
||||
---help---
|
||||
Attach a Linux I2C bus via the character device
|
||||
interface. This should be used with caution as it
|
||||
could interfere with devices internal to the system.
|
||||
It is recommended to use this with a USB<>I2C device
|
||||
like the MCP2221 and set udev rules so that only
|
||||
the bus provided by this device can be controlled
|
||||
by the user running the simulator.
|
||||
https://www.kernel.org/doc/html/latest/i2c/dev-interface.html
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
||||
config SIM_UART_NUMBER
|
||||
int "The number of tty ports on sim platform, range is 0~4"
|
||||
default 0
|
||||
|
|
|
@ -201,6 +201,14 @@ ifeq ($(CONFIG_SIM_HCISOCKET),y)
|
|||
CSRCS += up_hcisocket.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_I2C_RESET),y)
|
||||
HOSTCFLAGS += -DCONFIG_I2C_RESET=1
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIM_I2CBUS_LINUX),y)
|
||||
HOSTSRCS += up_i2cbuslinux.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RPTUN),y)
|
||||
CSRCS += up_rptun.c
|
||||
endif
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
NXSYMBOLS(__cxa_atexit)
|
||||
NXSYMBOLS(bind)
|
||||
NXSYMBOLS(calloc)
|
||||
NXSYMBOLS(clock_gettime)
|
||||
NXSYMBOLS(close)
|
||||
NXSYMBOLS(closedir)
|
||||
|
@ -46,6 +47,7 @@ NXSYMBOLS(if_nametoindex)
|
|||
NXSYMBOLS(ioctl)
|
||||
NXSYMBOLS(lseek)
|
||||
NXSYMBOLS(malloc)
|
||||
NXSYMBOLS(memcpy)
|
||||
NXSYMBOLS(mkdir)
|
||||
NXSYMBOLS(mmap)
|
||||
NXSYMBOLS(munmap)
|
||||
|
|
76
arch/sim/src/sim/up_i2cbus.h
Normal file
76
arch/sim/src/sim/up_i2cbus.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/****************************************************************************
|
||||
* arch/sim/src/sim/up_i2cbus.h
|
||||
*
|
||||
* 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 _ARCH_SIM_SRC_SIM_I2CBUS_H_
|
||||
#define _ARCH_SIM_SRC_SIM_I2CBUS_H_
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* NuttX msg flags (see i2c_master.h) */
|
||||
|
||||
#define NUTTX_I2C_M_READ 0x0001 /* Read data, from slave to master */
|
||||
#define NUTTX_I2C_M_TEN 0x0002 /* Ten bit address */
|
||||
#define NUTTX_I2C_M_NOSTOP 0x0040 /* Message should not end with a STOP */
|
||||
#define NUTTX_I2C_M_NOSTART 0x0080 /* Message should not begin with a START */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* NuttX i2c msg struct (see i2c_master.h) */
|
||||
|
||||
struct i2c_msg_s
|
||||
{
|
||||
uint32_t frequency; /* I2C frequency */
|
||||
uint16_t addr; /* Slave address (7- or 10-bit) */
|
||||
uint16_t flags; /* See I2C_M_* definitions */
|
||||
uint8_t *buffer; /* Buffer to be transferred */
|
||||
ssize_t length; /* Length of the buffer in bytes */
|
||||
};
|
||||
|
||||
/* Structs needed for interacting with the NuttX i2c_master */
|
||||
|
||||
struct i2c_master_s
|
||||
{
|
||||
const struct i2c_ops_s *ops;
|
||||
};
|
||||
|
||||
struct i2c_ops_s
|
||||
{
|
||||
int (*transfer)(struct i2c_master_s *dev,
|
||||
struct i2c_msg_s *msgs, int count);
|
||||
#ifdef CONFIG_I2C_RESET
|
||||
int (*reset)(struct i2c_master_s *dev);
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* _ARCH_SIM_SRC_SIM_I2CBUS_H_ */
|
310
arch/sim/src/sim/up_i2cbuslinux.c
Normal file
310
arch/sim/src/sim/up_i2cbuslinux.c
Normal file
|
@ -0,0 +1,310 @@
|
|||
/****************************************************************************
|
||||
* arch/sim/src/sim/up_i2cbuslinux.c
|
||||
*
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include "up_i2cbus.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ERROR(fmt, ...) \
|
||||
syslog(LOG_ERR, "up_i2cbuslinux: " fmt "\n", ##__VA_ARGS__)
|
||||
#define INFO(fmt, ...) \
|
||||
syslog(LOG_ERR, "up_i2cbuslinux: " fmt "\n", ##__VA_ARGS__)
|
||||
#define DEBUG(fmt, ...)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct linux_i2cbus_master_s
|
||||
{
|
||||
const struct i2c_ops_s *ops; /* I2C vtable */
|
||||
int file;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int linux_i2cbus_transfer(struct i2c_master_s *dev,
|
||||
struct i2c_msg_s *msgs, int count);
|
||||
#ifdef CONFIG_I2C_RESET
|
||||
static int linux_i2cbus_reset(struct i2c_master_s *dev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct i2c_ops_s i2c_linux_ops =
|
||||
{
|
||||
.transfer = linux_i2cbus_transfer,
|
||||
#ifdef CONFIG_I2C_RESET
|
||||
.reset = linux_i2cbus_reset,
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: linux_i2cbus_reset
|
||||
*
|
||||
* Description:
|
||||
* Provide i2c reset
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_I2C_RESET
|
||||
static int linux_i2cbus_reset(struct i2c_master_s *dev)
|
||||
{
|
||||
return -1; /* Not implemented */
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: linux_i2cbus_transfer
|
||||
*
|
||||
* Description:
|
||||
* Provide i2c transfer
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int linux_i2cbus_transfer(struct i2c_master_s *dev,
|
||||
struct i2c_msg_s *msgs, int count)
|
||||
{
|
||||
int ret = 0;
|
||||
struct linux_i2cbus_master_s *priv = (struct linux_i2cbus_master_s *)dev;
|
||||
int file = priv->file;
|
||||
uint8_t *pack_buf = NULL;
|
||||
struct i2c_rdwr_ioctl_data ioctl_data;
|
||||
struct i2c_msg l_msgs[2]; /* We only support up to 2 messages */
|
||||
ioctl_data.msgs = l_msgs;
|
||||
|
||||
/* Many i2c bus do not play well with combined messages via the Linux
|
||||
* interface, this makes stitching things together a little harder
|
||||
* because NuttX provides the ability to hold the bus without ending
|
||||
* with a STOP which is not ideal in general, and not possible with
|
||||
* Linux.
|
||||
*/
|
||||
|
||||
if ((msgs[0].flags & NUTTX_I2C_M_TEN) || (msgs[1].flags & NUTTX_I2C_M_TEN))
|
||||
{
|
||||
/* Linux also has somewhat poor support for 10bit addresses and they
|
||||
* are quite rare so we just don't support them for now here
|
||||
*/
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ioctl_data.msgs = l_msgs;
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
if (msgs[0].flags & NUTTX_I2C_M_NOSTOP || \
|
||||
msgs[0].flags & NUTTX_I2C_M_NOSTART)
|
||||
{
|
||||
/* Do not support leaving the bus hanging or try to send
|
||||
* without first starting.
|
||||
*/
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
l_msgs[0].addr = msgs[0].addr;
|
||||
l_msgs[0].buf = msgs[0].buffer;
|
||||
l_msgs[0].len = msgs[0].length;
|
||||
l_msgs[0].flags = 0;
|
||||
if (msgs[0].flags & NUTTX_I2C_M_READ)
|
||||
{
|
||||
l_msgs[0].flags |= I2C_M_RD;
|
||||
}
|
||||
|
||||
ioctl_data.nmsgs = 1;
|
||||
}
|
||||
else if(count == 2)
|
||||
{
|
||||
/* Addresses should be the same */
|
||||
|
||||
if (msgs[0].addr != msgs[1].addr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if we are about to do a read of a register
|
||||
* NuttX interface represents this as WRITE(NOSTOP) + READ
|
||||
* Linux interface represents this as WRITE + READ
|
||||
*/
|
||||
|
||||
if (msgs[0].flags & NUTTX_I2C_M_NOSTOP && \
|
||||
msgs[1].flags & NUTTX_I2C_M_READ)
|
||||
{
|
||||
l_msgs[0].addr = msgs[0].addr;
|
||||
l_msgs[0].flags = 0;
|
||||
l_msgs[0].buf = msgs[0].buffer;
|
||||
l_msgs[0].len = msgs[0].length;
|
||||
|
||||
l_msgs[1].addr = msgs[1].addr;
|
||||
l_msgs[1].flags = I2C_M_RD;
|
||||
l_msgs[1].buf = msgs[1].buffer;
|
||||
l_msgs[1].len = msgs[1].length;
|
||||
ioctl_data.nmsgs = 2;
|
||||
}
|
||||
else if (!(msgs[0].flags & NUTTX_I2C_M_READ) && \
|
||||
!(msgs[1].flags & NUTTX_I2C_M_READ) && \
|
||||
(msgs[0].flags & NUTTX_I2C_M_NOSTOP) && \
|
||||
(msgs[1].flags & NUTTX_I2C_M_NOSTART))
|
||||
{
|
||||
/* These writes are actually just a single write in Linux
|
||||
* so we pack the data in a single buffer and the unpack
|
||||
* it at the end. This could support for for more than just 2
|
||||
* messages, but in most cases it is just two because it is
|
||||
* connivent to write the register address and the data into two
|
||||
* different buffers.
|
||||
*/
|
||||
|
||||
pack_buf = malloc(msgs[0].length + msgs[1].length);
|
||||
if (pack_buf == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(pack_buf, msgs[0].buffer, msgs[0].length);
|
||||
memcpy(pack_buf + msgs[0].length, msgs[1].buffer, msgs[1].length);
|
||||
l_msgs[0].len = msgs[0].length + msgs[1].length;
|
||||
l_msgs[0].flags = 0;
|
||||
l_msgs[0].addr = msgs[0].addr;
|
||||
ioctl_data.msgs[0].buf = pack_buf;
|
||||
ioctl_data.nmsgs = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Many busses cannot handle more than 2 messages */
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(file, I2C_RDWR, &ioctl_data) < 1)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* Unpack from buffer back to msg buffers if needed */
|
||||
|
||||
if (pack_buf != NULL)
|
||||
{
|
||||
if (ret == 0)
|
||||
{
|
||||
int idx;
|
||||
uint8_t *msg_p = pack_buf;
|
||||
for (idx = 0; idx < count; idx++)
|
||||
{
|
||||
memcpy(msgs[idx].buffer, msg_p, msgs[idx].length);
|
||||
msg_p += msgs[idx].length;
|
||||
}
|
||||
}
|
||||
|
||||
free(pack_buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_i2cbus_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize one I2C bus
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct i2c_master_s *sim_i2cbus_initialize(int bus)
|
||||
{
|
||||
struct linux_i2cbus_master_s *priv;
|
||||
char filename[20];
|
||||
|
||||
priv = (struct linux_i2cbus_master_s *)malloc(sizeof(priv));
|
||||
if (priv == NULL)
|
||||
{
|
||||
ERROR("Failed to allocate private i2c master driver");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(filename, 19, "/dev/i2c-%d", bus);
|
||||
priv->file = open(filename, O_RDWR);
|
||||
if (priv->file < 0)
|
||||
{
|
||||
ERROR("Failed to open %s: %d", filename, priv->file);
|
||||
free(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
priv->ops = &i2c_linux_ops;
|
||||
return (struct i2c_master_s *)priv;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sim_i2cbus_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* Uninitialize an I2C bus
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sim_i2cbus_uninitialize(struct i2c_master_s *dev)
|
||||
{
|
||||
struct linux_i2cbus_master_s *priv = (struct linux_i2cbus_master_s *)dev;
|
||||
if (priv->file >= 0)
|
||||
{
|
||||
close(priv->file);
|
||||
}
|
||||
|
||||
free(priv);
|
||||
return 0;
|
||||
}
|
|
@ -160,6 +160,7 @@ struct tcb_s;
|
|||
struct spi_dev_s;
|
||||
struct qspi_dev_s;
|
||||
struct ioexpander_dev_s;
|
||||
struct i2c_master_s;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
|
@ -404,6 +405,13 @@ struct audio_lowerhalf_s *sim_audio_initialize(bool playback);
|
|||
void sim_audio_loop(void);
|
||||
#endif
|
||||
|
||||
/* up_i2cbus*.c *************************************************************/
|
||||
|
||||
#ifdef CONFIG_SIM_I2CBUS
|
||||
struct i2c_master_s *sim_i2cbus_initialize(int bus);
|
||||
int sim_i2cbus_uninitialize(struct i2c_master_s *dev);
|
||||
#endif
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
#ifdef CONFIG_STACK_COLORATION
|
||||
|
|
|
@ -54,3 +54,11 @@ config SIM_WTGAHRS2_UARTN
|
|||
We can select the number accoding to which SIM_UARTX_NAME is uesd to sensor.
|
||||
This range is 0-4.
|
||||
endif
|
||||
|
||||
config SIM_I2CBUS_ID
|
||||
int "I2C host bus ID to attach to simulator"
|
||||
default 0
|
||||
depends on SIM_I2CBUS
|
||||
---help---
|
||||
This is the bus identifier that should be used by the host implementation to
|
||||
attach to the simulator driver.
|
||||
|
|
43
boards/sim/sim/sim/configs/linuxi2c/defconfig
Normal file
43
boards/sim/sim/sim/configs/linuxi2c/defconfig
Normal file
|
@ -0,0 +1,43 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
|
||||
CONFIG_ARCH="sim"
|
||||
CONFIG_ARCH_BOARD="sim"
|
||||
CONFIG_ARCH_BOARD_SIM=y
|
||||
CONFIG_ARCH_CHIP="sim"
|
||||
CONFIG_ARCH_SIM=y
|
||||
CONFIG_BOARDCTL_APP_SYMTAB=y
|
||||
CONFIG_BOARDCTL_POWEROFF=y
|
||||
CONFIG_BOARDCTL_ROMDISK=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=0
|
||||
CONFIG_BOOT_RUNFROMEXTSRAM=y
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=4096
|
||||
CONFIG_LIBC_EXECFUNCS=y
|
||||
CONFIG_MAX_TASKS=64
|
||||
CONFIG_NFILE_DESCRIPTORS=32
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=2048
|
||||
CONFIG_READLINE_TABCOMPLETION=y
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_ONEXIT=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SDCLONE_DISABLE=y
|
||||
CONFIG_SIM_I2CBUS=y
|
||||
CONFIG_START_MONTH=6
|
||||
CONFIG_START_YEAR=2008
|
||||
CONFIG_SYSTEM_I2CTOOL=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_USERMAIN_STACKSIZE=4096
|
||||
CONFIG_USER_ENTRYPOINT="nsh_main"
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* boards/sim/sim/sim/src/sam_bringup.c
|
||||
* boards/sim/sim/sim/src/sim_bringup.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
@ -40,6 +40,8 @@
|
|||
#include <nuttx/wireless/bluetooth/bt_driver.h>
|
||||
#include <nuttx/wireless/bluetooth/bt_null.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_loopback.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/mpu60x0.h>
|
||||
|
||||
#ifdef CONFIG_LCD_DEV
|
||||
#include <nuttx/lcd/lcd_dev.h>
|
||||
|
@ -68,6 +70,13 @@ int sim_bringup(void)
|
|||
#ifdef CONFIG_RAMMTD
|
||||
FAR uint8_t *ramstart;
|
||||
#endif
|
||||
#ifdef CONFIG_SIM_I2CBUS
|
||||
FAR struct i2c_master_s *i2cbus;
|
||||
#endif
|
||||
#ifdef CONFIG_MPU60X0_I2C
|
||||
FAR struct mpu_config_s *mpu_config;
|
||||
#endif
|
||||
|
||||
int ret = OK;
|
||||
|
||||
#ifdef CONFIG_FS_BINFS
|
||||
|
@ -335,5 +344,41 @@ int sim_bringup(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIM_I2CBUS
|
||||
/* Initialize the i2c master bus device */
|
||||
|
||||
i2cbus = sim_i2cbus_initialize(CONFIG_SIM_I2CBUS_ID);
|
||||
if (i2cbus == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: sim_i2cbus_initialize failed.\n");
|
||||
}
|
||||
#if defined(CONFIG_SYSTEM_I2CTOOL) || defined(CONFIG_MPU60X0_I2C)
|
||||
else
|
||||
{
|
||||
ret = i2c_register(i2cbus, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: Failed to register I2C%d driver: %d\n",
|
||||
0, ret);
|
||||
sim_i2cbus_uninitialize(i2cbus);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MPU60X0_I2C
|
||||
mpu_config = kmm_zalloc(sizeof(struct mpu_config_s));
|
||||
if (mpu_config == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: Failed to allocate mpu60x0 driver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
mpu_config->i2c = i2cbus;
|
||||
mpu_config->addr = 0x68;
|
||||
mpu60x0_register("/dev/imu0", mpu_config);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -453,13 +453,11 @@ static int __mpu_write_reg_i2c(FAR struct mpu_dev_s *dev,
|
|||
msg[0].flags = I2C_M_NOSTOP;
|
||||
msg[0].buffer = ®_addr;
|
||||
msg[0].length = 1;
|
||||
|
||||
msg[1].frequency = CONFIG_MPU60X0_I2C_FREQ;
|
||||
msg[1].addr = dev->config.addr;
|
||||
msg[1].flags = I2C_M_NOSTART;
|
||||
msg[1].buffer = (FAR uint8_t *)buf;
|
||||
msg[1].length = len;
|
||||
|
||||
ret = I2C_TRANSFER(dev->config.i2c, msg, 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
@ -718,19 +716,19 @@ static int mpu_reset(FAR struct mpu_dev_s *dev)
|
|||
|
||||
do
|
||||
{
|
||||
up_mdelay(50); /* msecs (arbitrary) */
|
||||
nxsig_usleep(50000); /* usecs (arbitrary) */
|
||||
}
|
||||
while (__mpu_read_pwr_mgmt_1(dev) & PWR_MGMT_1__DEVICE_RESET);
|
||||
|
||||
/* Reset signal paths */
|
||||
|
||||
__mpu_write_signal_path_reset(dev, SIGNAL_PATH_RESET__ALL_RESET);
|
||||
up_mdelay(2);
|
||||
nxsig_usleep(2000);
|
||||
|
||||
/* Disable SLEEP, use PLL with z-axis clock source */
|
||||
|
||||
__mpu_write_pwr_mgmt_1(dev, 3);
|
||||
up_mdelay(2);
|
||||
nxsig_usleep(2000);
|
||||
|
||||
/* Disable i2c if we're on spi. */
|
||||
|
||||
|
|
Loading…
Reference in a new issue