From 2c91805d8ffbd40a1423075ab196610f2820b893 Mon Sep 17 00:00:00 2001 From: Brennan Ashton Date: Sun, 2 May 2021 22:17:35 -0700 Subject: [PATCH] boards/stm32f7: Add i2c and mpu60x0 support to nucleo-144 --- boards/arm/stm32f7/nucleo-144/README.txt | 2 + .../nucleo-144/configs/f767-evalos/defconfig | 5 ++ .../nucleo-144/src/stm32_appinitialize.c | 47 +++++++++++++++++++ drivers/sensors/mpu60x0.c | 25 ++++++++-- 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/boards/arm/stm32f7/nucleo-144/README.txt b/boards/arm/stm32f7/nucleo-144/README.txt index 9447b2eb3e..4ee4da3e5f 100644 --- a/boards/arm/stm32f7/nucleo-144/README.txt +++ b/boards/arm/stm32f7/nucleo-144/README.txt @@ -573,6 +573,8 @@ f7xx-evalos: - Configures nsh with advanced features such as autocompletion. - Configures the on-board LEDs to work with the 'leds' example app. - Configures the 'helloxx' example app. + - Adds character device for i2c1 + - Tries to register mpu60x0 IMU to i2c1 NOTES: diff --git a/boards/arm/stm32f7/nucleo-144/configs/f767-evalos/defconfig b/boards/arm/stm32f7/nucleo-144/configs/f767-evalos/defconfig index 34575a9ca7..d6af52c988 100644 --- a/boards/arm/stm32f7/nucleo-144/configs/f767-evalos/defconfig +++ b/boards/arm/stm32f7/nucleo-144/configs/f767-evalos/defconfig @@ -31,6 +31,7 @@ CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_MAX_TASKS=16 CONFIG_MM_REGIONS=3 +CONFIG_MPU60X0_I2C=y CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=512 @@ -49,14 +50,18 @@ CONFIG_SCHED_HPWORK=y CONFIG_SCHED_LPWORK=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y +CONFIG_SENSORS=y +CONFIG_SENSORS_MPU60X0=y CONFIG_SPI=y CONFIG_STACK_COLORATION=y CONFIG_START_DAY=30 CONFIG_START_MONTH=11 CONFIG_START_YEAR=2015 +CONFIG_STM32F7_I2C1=y CONFIG_STM32F7_SERIALBRK_BSDCOMPAT=y CONFIG_STM32F7_SERIAL_DISABLE_REORDERING=y CONFIG_STM32F7_USART_BREAKS=y +CONFIG_SYSTEM_I2CTOOL=y CONFIG_SYSTEM_NSH=y CONFIG_TASK_NAME_SIZE=0 CONFIG_USART3_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32f7/nucleo-144/src/stm32_appinitialize.c b/boards/arm/stm32f7/nucleo-144/src/stm32_appinitialize.c index b851b3dade..8177e5b548 100644 --- a/boards/arm/stm32f7/nucleo-144/src/stm32_appinitialize.c +++ b/boards/arm/stm32f7/nucleo-144/src/stm32_appinitialize.c @@ -48,7 +48,13 @@ #include "nucleo-144.h" #include +#include +#include #include +#include + +#include "stm32_i2c.h" + #ifdef CONFIG_STM32_ROMFS #include "stm32_romfs.h" #endif @@ -97,6 +103,13 @@ int stm32f7_can_setup(void); int board_app_initialize(uintptr_t arg) { int ret; +#ifdef CONFIG_I2C + int i2c_bus; + FAR struct i2c_master_s *i2c; +#ifdef CONFIG_MPU60X0_I2C + FAR struct mpu_config_s *mpu_config; +#endif +#endif #ifdef CONFIG_FS_PROCFS /* Mount the procfs file system */ @@ -220,6 +233,40 @@ int board_app_initialize(uintptr_t arg) } #endif +#if defined(CONFIG_I2C) && defined(CONFIG_STM32F7_I2C1) + i2c_bus = 1; + i2c = stm32_i2cbus_initialize(i2c_bus); + if (i2c == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to get I2C%d interface\n", i2c_bus); + } + else + { +#if defined(CONFIG_SYSTEM_I2CTOOL) + ret = i2c_register(i2c, i2c_bus); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register I2C%d driver: %d\n", + i2c_bus, ret); + } +#endif + +#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 = i2c; + mpu_config->addr = 0x68; + mpu60x0_register("/dev/imu0", mpu_config); + } +#endif + } +#endif + UNUSED(ret); return OK; } diff --git a/drivers/sensors/mpu60x0.c b/drivers/sensors/mpu60x0.c index 84edf65f32..fb7f13aab6 100644 --- a/drivers/sensors/mpu60x0.c +++ b/drivers/sensors/mpu60x0.c @@ -693,6 +693,7 @@ static void inline mpu_unlock(FAR struct mpu_dev_s *dev) static int mpu_reset(FAR struct mpu_dev_s *dev) { + int ret; #ifdef CONFIG_MPU60X0_SPI if (dev->config.spi == NULL) { @@ -709,7 +710,12 @@ static int mpu_reset(FAR struct mpu_dev_s *dev) /* Awaken chip, issue hardware reset */ - __mpu_write_pwr_mgmt_1(dev, PWR_MGMT_1__DEVICE_RESET); + ret = __mpu_write_pwr_mgmt_1(dev, PWR_MGMT_1__DEVICE_RESET); + if (ret != OK) + { + snerr("Could not find mpu60x0!\n"); + return ret; + } /* Wait for reset cycle to finish (note: per the datasheet, we don't need * to hold NSS for this) @@ -994,6 +1000,19 @@ int mpu60x0_register(FAR const char *path, FAR struct mpu_config_s *config) priv->config = *config; + /* Reset the chip, to give it an initial configuration. */ + + ret = mpu_reset(priv); + if (ret < 0) + { + snerr("ERROR: Failed to configure mpu60x0: %d\n", ret); + + nxmutex_destroy(&priv->lock); + + kmm_free(priv); + return ret; + } + /* Register the device node. */ ret = register_driver(path, &g_mpu_fops, 0666, priv); @@ -1007,7 +1026,5 @@ int mpu60x0_register(FAR const char *path, FAR struct mpu_config_s *config) return ret; } - /* Reset the chip, to give it an initial configuration. */ - - return mpu_reset(priv); + return OK; }