You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/04/15 11:38:50 UTC

[incubator-nuttx] 02/03: boards/stm32/common: add support for IHM16M1

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 25240d9114e7edb247a2d32bf3d934a482c599c8
Author: raiden00pl <ra...@railab.me>
AuthorDate: Wed Apr 14 15:01:43 2021 +0200

    boards/stm32/common: add support for IHM16M1
---
 boards/arm/stm32/common/Kconfig                 |  18 +
 boards/arm/stm32/common/include/stm32_ihm16m1.h |  59 ++++
 boards/arm/stm32/common/src/Make.defs           |   4 +
 boards/arm/stm32/common/src/stm32_ihm16m1.c     | 445 ++++++++++++++++++++++++
 4 files changed, 526 insertions(+)

diff --git a/boards/arm/stm32/common/Kconfig b/boards/arm/stm32/common/Kconfig
index fa52591..4eef44c 100644
--- a/boards/arm/stm32/common/Kconfig
+++ b/boards/arm/stm32/common/Kconfig
@@ -50,6 +50,24 @@ config BOARD_STM32_IHM08M1_POT
 
 endif # BOARD_STM32_IHM08M1
 
+menuconfig BOARD_STM32_IHM16M1
+       bool "X-NUCLEO-IHM16M1 board support"
+       default n
+       ---help---
+         Board based on the STSPIN830 three-phase brushless motor driver.
+
+if BOARD_STM32_IHM16M1
+
+config BOARD_STM32_IHM16M1_VBUS
+       bool "X-NUCLEO-IHM16M1 board VBUS sense"
+       default n
+
+config BOARD_STM32_IHM16M1_POT
+       bool "X-NUCLEO-IHM16M1 board POT support"
+       default n
+
+endif # BOARD_STM32_IHM16M1
+
 endif # STM32_FOC
 
 endif # BOARD_STM32_COMMON
diff --git a/boards/arm/stm32/common/include/stm32_ihm16m1.h b/boards/arm/stm32/common/include/stm32_ihm16m1.h
new file mode 100644
index 0000000..f96520c
--- /dev/null
+++ b/boards/arm/stm32/common/include/stm32_ihm16m1.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+ * boards/arm/stm32/common/include/stm32_ihm16m1.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 __STM32_IHM16M1_H
+#define __STM32_IHM16M1_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "stm32_foc.h"
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_ihm16m1_initialize
+ ****************************************************************************/
+
+int board_ihm16m1_initialize(FAR struct stm32_foc_adc_s *adc_cfg);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __STM32_IHM16M1_H
diff --git a/boards/arm/stm32/common/src/Make.defs b/boards/arm/stm32/common/src/Make.defs
index 736279d..45e91b6 100644
--- a/boards/arm/stm32/common/src/Make.defs
+++ b/boards/arm/stm32/common/src/Make.defs
@@ -122,6 +122,10 @@ ifeq ($(CONFIG_BOARD_STM32_IHM08M1),y)
   CSRCS += stm32_ihm08m1.c
 endif
 
+ifeq ($(CONFIG_BOARD_STM32_IHM16M1),y)
+  CSRCS += stm32_ihm16m1.c
+endif
+
 DEPPATH += --dep-path src
 VPATH += :src
 CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src)
diff --git a/boards/arm/stm32/common/src/stm32_ihm16m1.c b/boards/arm/stm32/common/src/stm32_ihm16m1.c
new file mode 100644
index 0000000..606f9bb
--- /dev/null
+++ b/boards/arm/stm32/common/src/stm32_ihm16m1.c
@@ -0,0 +1,445 @@
+/****************************************************************************
+ * boards/arm/stm32/common/src/stm32_ihm16m1.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 <nuttx/config.h>
+
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include <nuttx/analog/adc.h>
+
+#include "stm32_foc.h"
+#include "stm32_gpio.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_MOTOR_FOC_SHUNTS != 3
+#  error For now ony 3-shunts configuration is supported
+#endif
+
+/* Configuration specific for STSPIN830:
+ * 1. PWM enable on high
+ * 2. PWM channels must have positive polarity
+ * 3. EN_FAULT enable on high, configured as open drain output
+ */
+
+#if CONFIG_STM32_TIM1_CH1POL != 0
+#  error
+#endif
+#if CONFIG_STM32_TIM1_CH2POL != 0
+#  error
+#endif
+#if CONFIG_STM32_TIM1_CH3POL != 0
+#  error
+#endif
+
+/* Aux ADC needs DMA enabled */
+
+#ifdef CONFIG_ADC
+#  ifndef CONFIG_STM32_ADC1_DMA
+#    error
+#  endif
+#endif
+
+/* REVISIT: dead-time STSPIN830 */
+
+#define PWM_DEADTIME    (20)
+#define PWM_DEADTIME_NS (500)
+
+/* Devpath for FOC driver */
+
+#define FOC_DEVPATH "/dev/foc0"
+
+/* Board parameters:
+ *   Current shunt resistance                    = 0.33
+ *   Current sense gain                          = -1.53 (inverted current)
+ *   Vbus sense gain                             = 0.0522
+ *   Vbus min                                    = 7V
+ *   Vbus max                                    = 45V
+ *   Iout max                                    = 1.5A RMS
+ *   IPHASE_RATIO = 1/(R_shunt*gain)             = -1.98
+ *   ADC_REF_VOLTAGE                             = 3.3
+ *   ADC_VAL_MAX                                 = 4095
+ *   ADC_TO_VOLT = ADC_REF_VOLTAGE / ADC_VAL_MAX
+ *   IPHASE_ADC = IPHASE_RATIO * ADC_TO_VOLT     = -0.00160
+ *   VBUS_RATIO = 1/VBUS_gain                    = 16
+ */
+
+/* Center-aligned PWM duty cycle limits */
+
+#define MAX_DUTY_B16 ftob16(0.95f)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Protototypes
+ ****************************************************************************/
+
+static int board_foc_setup(FAR struct foc_dev_s *dev);
+static int board_foc_shutdown(FAR struct foc_dev_s *dev);
+static int board_foc_calibration(FAR struct foc_dev_s *dev, bool state);
+static int board_foc_fault_clear(FAR struct foc_dev_s *dev);
+static int board_foc_pwm_start(FAR struct foc_dev_s *dev, bool state);
+static int board_foc_current_get(FAR struct foc_dev_s *dev,
+                                 FAR int16_t *curr_raw,
+                                 FAR foc_current_t *curr);
+#ifdef CONFIG_MOTOR_FOC_TRACE
+static int board_foc_trace_init(FAR struct foc_dev_s *dev);
+static void board_foc_trace(FAR struct foc_dev_s *dev, int type, bool state);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Board specific ops */
+
+static struct stm32_foc_board_ops_s g_stm32_foc_board_ops =
+{
+  .setup       = board_foc_setup,
+  .shutdown    = board_foc_shutdown,
+  .calibration = board_foc_calibration,
+  .fault_clear = board_foc_fault_clear,
+  .pwm_start   = board_foc_pwm_start,
+  .current_get = board_foc_current_get,
+#ifdef CONFIG_MOTOR_FOC_TRACE
+  .trace_init  = board_foc_trace_init,
+  .trace       = board_foc_trace
+#endif
+};
+
+/* Board specific data */
+
+static struct stm32_foc_board_data_s g_stm32_foc_board_data =
+{
+  .adc_cfg   = NULL,     /* board-specific */
+  .duty_max  = (MAX_DUTY_B16),
+  .pwm_dt    = (PWM_DEADTIME),
+  .pwm_dt_ns = (PWM_DEADTIME_NS)
+};
+
+/* Board specific configuration */
+
+static struct stm32_foc_board_s g_stm32_foc_board =
+{
+  .data = &g_stm32_foc_board_data,
+  .ops  = &g_stm32_foc_board_ops,
+};
+
+/* Global pointer to the upper FOC driver */
+
+static FAR struct foc_dev_s *g_foc_dev = NULL;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_foc_setup
+ ****************************************************************************/
+
+static int board_foc_setup(FAR struct foc_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  UNUSED(dev);
+
+  /* Configure EN_U, EN_V, EN_W, EN_FAULT GPIOs */
+
+  stm32_configgpio(GPIO_FOC_EN_U);
+  stm32_configgpio(GPIO_FOC_EN_V);
+  stm32_configgpio(GPIO_FOC_EN_W);
+
+  stm32_configgpio(GPIO_FOC_ENFAULT);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: board_foc_shutdown
+ ****************************************************************************/
+
+static int board_foc_shutdown(FAR struct foc_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  UNUSED(dev);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: board_foc_calibration
+ ****************************************************************************/
+
+static int board_foc_calibration(FAR struct foc_dev_s *dev, bool state)
+{
+  DEBUGASSERT(dev);
+
+  UNUSED(dev);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: board_foc_fault_clear
+ ****************************************************************************/
+
+static int board_foc_fault_clear(FAR struct foc_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  UNUSED(dev);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: board_foc_pwm_start
+ ****************************************************************************/
+
+static int board_foc_pwm_start(FAR struct foc_dev_s *dev, bool state)
+{
+  DEBUGASSERT(dev);
+
+  UNUSED(dev);
+
+  /* Set/reset ENABLE input */
+
+  stm32_gpiowrite(GPIO_FOC_ENFAULT, state);
+
+  /* Enable/disable UVW output */
+
+  stm32_gpiowrite(GPIO_FOC_EN_U, state);
+  stm32_gpiowrite(GPIO_FOC_EN_V, state);
+  stm32_gpiowrite(GPIO_FOC_EN_W, state);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: board_foc_current_get
+ ****************************************************************************/
+
+static int board_foc_current_get(FAR struct foc_dev_s *dev,
+                                 FAR int16_t *curr_raw,
+                                 FAR foc_current_t *curr)
+{
+  DEBUGASSERT(dev);
+  DEBUGASSERT(curr_raw);
+  DEBUGASSERT(curr);
+
+  /* Get currents */
+
+  curr[0] = curr_raw[0];
+  curr[1] = curr_raw[1];
+  curr[2] = curr_raw[2];
+
+  return OK;
+}
+
+#ifdef CONFIG_MOTOR_FOC_TRACE
+/****************************************************************************
+ * Name: board_foc_trace_init
+ ****************************************************************************/
+
+static int board_foc_trace_init(FAR struct foc_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  UNUSED(dev);
+
+  /* Configure debug GPIO */
+
+  stm32_configgpio(GPIO_FOC_DEBUG0);
+  stm32_configgpio(GPIO_FOC_DEBUG1);
+  stm32_configgpio(GPIO_FOC_DEBUG2);
+  stm32_configgpio(GPIO_FOC_DEBUG3);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: board_foc_trace
+ ****************************************************************************/
+
+static void board_foc_trace(FAR struct foc_dev_s *dev, int type, bool state)
+{
+  DEBUGASSERT(dev);
+
+  UNUSED(dev);
+
+  switch (type)
+    {
+      case FOC_TRACE_NONE:
+        {
+          break;
+        }
+
+      case FOC_TRACE_PARAMS:
+        {
+          stm32_gpiowrite(GPIO_FOC_DEBUG0, state);
+
+          break;
+        }
+
+      case FOC_TRACE_STATE:
+        {
+          stm32_gpiowrite(GPIO_FOC_DEBUG1, state);
+
+          break;
+        }
+
+      case FOC_TRACE_NOTIFIER:
+        {
+          stm32_gpiowrite(GPIO_FOC_DEBUG2, state);
+
+          break;
+        }
+
+      case FOC_TRACE_LOWER:
+        {
+          stm32_gpiowrite(GPIO_FOC_DEBUG3, state);
+
+          break;
+        }
+
+      default:
+        {
+          mtrerr("board_foc_trace type=%d not supported!\n", type);
+          DEBUGASSERT(0);
+        }
+    }
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_ihm16m1_initialize
+ ****************************************************************************/
+
+int board_ihm16m1_initialize(FAR struct stm32_foc_adc_s *adc_cfg)
+{
+  FAR struct foc_dev_s *foc = NULL;
+  int                   ret = OK;
+
+  DEBUGASSERT(adc_cfg);
+
+  /* Initialize only once */
+
+  if (g_foc_dev == NULL)
+    {
+      /* Connect ADC configuration */
+
+      g_stm32_foc_board_data.adc_cfg = adc_cfg;
+
+      /* Initialize arch specific FOC lower-half */
+
+      foc = stm32_foc_initialize(0, &g_stm32_foc_board);
+      if (foc == NULL)
+        {
+          ret = -errno;
+          mtrerr("Failed to initialize STM32 FOC: %d\n", ret);
+          goto errout;
+        }
+
+      DEBUGASSERT(foc->lower);
+
+      /* Register FOC device */
+
+      ret = foc_register(FOC_DEVPATH, foc);
+      if (ret < 0)
+        {
+          mtrerr("Failed to register FOC device: %d\n", ret);
+          goto errout;
+        }
+
+      /* Store pointer to driver */
+
+      g_foc_dev = foc;
+    }
+
+errout:
+  return ret;
+}
+
+#ifdef CONFIG_ADC
+/****************************************************************************
+ * Name: stm32_adc_setup
+ *
+ * Description:
+ *   Initialize ADC and register the ADC driver.
+ *
+ ****************************************************************************/
+
+int stm32_adc_setup(void)
+{
+  FAR struct adc_dev_s *adc         = NULL;
+  int                   ret         = OK;
+  static bool           initialized = false;
+
+  /* Initialize only once */
+
+  if (initialized == false)
+    {
+      if (g_foc_dev == NULL)
+        {
+          mtrerr("Failed to get g_foc_dev device\n");
+          ret = -EACCES;
+          goto errout;
+        }
+
+      /* Register regular channel ADC */
+
+      adc = stm32_foc_adcget(g_foc_dev);
+      if (adc == NULL)
+        {
+          mtrerr("Failed to get ADC device: %d\n", ret);
+          goto errout;
+        }
+
+      ret = adc_register("/dev/adc0", adc);
+      if (ret < 0)
+        {
+          mtrerr("adc_register failed: %d\n", ret);
+          goto errout;
+        }
+
+      initialized = true;
+    }
+
+errout:
+  return ret;
+}
+#endif