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