boards: add support for ODrive V3.6 board

This commit is contained in:
raiden00pl 2023-11-18 10:37:10 +01:00 committed by Xiang Xiao
parent 9a51197523
commit 014029c649
19 changed files with 2468 additions and 2 deletions

View File

@ -57,7 +57,6 @@ f_PWM f_notifier ccb Kp Ki
20kHz 10kHz 1000 0.0087 0.0025
====== =========== ===== ======== ======
* Linix 45ZWN24-40 (PMSM motor dedicated for NXP FRDM-MC-LVMTR kit)
====== =========== ===== ======== ======
@ -74,7 +73,6 @@ f_PWM f_notifier ccb Kp Ki
20kHz 10kHz 200 0.036 0.022
====== =========== ===== ======== ======
* iPower GBM2804H-100T (gimbal motor provided with the ST P-NUCLEO-IHM03 kit)
====== =========== ===== ======== ======

View File

@ -0,0 +1,97 @@
===========
ODrive V3.6
===========
ODrive V3.6 is an open-source dual-motor FOC controller based on
the STMicro STM32F405RG and TI DRV8301 gate drivers.
See https://odriverobotics.com/shop/odrive-v36 for further information.
For now we support only ODrive V3.6 56V.
Pin configuration
=================
========= ============== ========= =======================
Board Pin Chip Function Chip Pin Notes
========= ============== ========= =======================
GPIO_1 PA0
GPIO_2 PA1
GPIO_3 USART2_TX PA2 Serial TX
GPIO_4 USART2_RX PA3 Serial RX
M1_TEMP ADC1_IN4 PA4
AUX_TEMP ADC1_IN5 PA5
VBUS_S ADC1_IN6 PA6
M1_AL TIM8 CH1N PA7
M0_AH TIM1 CH1 PA8
M0_BH TIM1 CH2 PA9
M0_CH TIM1 CH3 PA10
USB_DM USB DM PA11
USB_DP USB DP PA12
SWDIO PA13
SWCLK PA14
GPIO_7 PA15
M0_SO1 ADC2_IN10 PC0 M0 current 1
M0_SO2 ADC2_IN11 PC1 M0 current 2
M1_SO2 ADC3_IN12 PC2 M1 current 2
M1_SO1 ADC3_IN13 PC3 M1 current 1
GPIO_5 PC4
M0_TEMP ADC1_IN15 PC5
M1_AH TIM8 CH1 PC6
M1_BH TIM8 CH2 PC7
M1_CH TIM8 CH3 PC8
M0_ENC_Z PC9
SPI_SCK SPI3_SCK PC10 DRV8301 M0/M1
SPI_MISO SPI3_MISO PC11 DRV8301 M0/M1
SPI_MOSI SPI3_MOSI PC12 DRV8301 M0/M1
M0_NCS SPI CS PC13 DRV8301 M0 CS
M1_NCS SPI CS PC14 DRV8301 M1 CS
M1_ENC_Z PC15
M1_BL TIM8 CH2N PB0
M1_CL TIM8 CH3N PB1
GPIO_6 PB2
GPIO_8 PB3
M0_ENC_A TIM3_CH1IN_2 PB4
M0_ENC_B TIM3_CH2IN_2 PB5
M1_ENC_A TIM4_CH1IN_1 PB6
M1_ENC_B TIM4_CH2IN_1 PB7
CAN_R CAN_R PB8
CAN_D CAN_D PB9
AUX_L PB10
AUX_H PB11
EN_GATE OUT PB12 M0/M1 DRV8301
M0_AL TIM1 CH1N PB13
M0_BL TIM1 CH2N PB14
M0_CL TIM1 CH3N PB15
N_FAULT PD2 M0/M1 DRV8301 N_FAULT
========= ============== ========= =======================
Board hardware configuration
============================
=========================== ==================
Current shunt resistance 0.0005
Current sense gain 10/20/40/80
Vbus min 12V
Vbus max 24V or 56V
Iout max 40A (no cooling for MOSFETs)
IPHASE_RATIO 1/(R_shunt*gain)
VBUS_RATIO = 1/VBUS_gain 11 or 19
=========================== ==================
Configurations
==============
nsh
---
Configures the NuttShell (nsh) located at apps/examples/nsh. The
Configuration enables the serial interfaces on USART2. Support for
builtin applications is enabled, but in the base configuration no
builtin applications are selected.
usbnsh
------
This is another NSH example. If differs from other 'nsh' configurations
in that this configurations uses a USB serial device for console I/O.

View File

@ -1270,6 +1270,14 @@ config ARCH_BOARD_OLIMEX_STRP711
further information. STATUS: Configurations for the basic OS test and NSH
are complete and verified.
config ARCH_BOARD_ODRIVE36
bool "Odrive V3.6 board"
depends on ARCH_CHIP_STM32F405RG
---help---
This port uses the ODrive3.6 board. This is an open-source dual-motor
FOC controller based on the STMicro STM32F405RG and TI DRV8301 gate drivers.
See https://odriverobotics.com/shop/odrive-v36 for further information.
config ARCH_BOARD_OLIMEX_STM32H405
bool "Olimex STM32 H405 board"
depends on ARCH_CHIP_STM32F405RG
@ -3198,6 +3206,7 @@ config ARCH_BOARD
default "olimex-stm32-p207" if ARCH_BOARD_OLIMEX_STM32P207
default "olimex-stm32-p407" if ARCH_BOARD_OLIMEX_STM32P407
default "olimex-strp711" if ARCH_BOARD_OLIMEX_STRP711
default "odrive36" if ARCH_BOARD_ODRIVE36
default "olimexino-stm32" if ARCH_BOARD_OLIMEXINO_STM32
default "omnibusf4" if ARCH_BOARD_OMNIBUSF4
default "open1788" if ARCH_BOARD_OPEN1788
@ -3892,6 +3901,9 @@ endif
if ARCH_BOARD_NUCLEO_L152RE
source "boards/arm/stm32/nucleo-l152re/Kconfig"
endif
if ARCH_BOARD_ODRIVE36
source "boards/arm/stm32/odrive36/Kconfig"
endif
if ARCH_BOARD_OLIMEX_STM32E407
source "boards/arm/stm32/olimex-stm32-e407/Kconfig"
endif

View File

@ -0,0 +1,21 @@
# ##############################################################################
# boards/arm/stm32/odrive36/CMakeLists.txt
#
# 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.
#
# ##############################################################################
add_subdirectory(src)

View File

@ -0,0 +1,48 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
if ARCH_BOARD_ODRIVE36
choice
prompt "ODrive voltage version"
default ODRIVE_HW_VOLTAGE_56
config ODRIVE_HW_VOLTAGE_56
bool "ODrive 56V version"
config ODRIVE_HW_VOLTAGE_24
bool "ODrive 24V version"
endchoice # ODrive voltage version
if MOTOR_FOC
config ODRIVE_FOC_FOC0
bool "ODrive enable support for FOC device 0"
default y
if ODRIVE_FOC_FOC0
endif # ODRIVE_FOC_FOC0
config ODRIVE_FOC_FOC1
bool "ODrive enable support for FOC device 1"
default y
if ODRIVE_FOC_FOC1
endif # ODRIVE_FOC_FOC1
config ODRIVE_FOC_VBUS
bool "ODrive VBUS ADC support"
default n
config ODRIVE_FOC_TEMP
bool "ODrive Temperature ADC support"
default n
endif # MOTOR_FOC
endif # ARCH_BOARD_ODRIVE

View File

@ -0,0 +1,44 @@
#
# 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_ARCH_FPU is not set
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
# CONFIG_STM32_USE_LEGACY_PINMAP is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="odrive36"
CONFIG_ARCH_BOARD_ODRIVE36=y
CONFIG_ARCH_CHIP="stm32"
CONFIG_ARCH_CHIP_STM32=y
CONFIG_ARCH_CHIP_STM32F405RG=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=15272
CONFIG_BUILTIN=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_MM_REGIONS=2
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=6
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011
CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_USART2=y
CONFIG_SYSTEM_NSH=y
CONFIG_USART2_SERIAL_CONSOLE=y

View File

@ -0,0 +1,56 @@
#
# 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_ARCH_FPU is not set
# CONFIG_DEV_CONSOLE is not set
# CONFIG_STM32_USE_LEGACY_PINMAP is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="odrive36"
CONFIG_ARCH_BOARD_ODRIVE36=y
CONFIG_ARCH_CHIP="stm32"
CONFIG_ARCH_CHIP_STM32=y
CONFIG_ARCH_CHIP_STM32F405RG=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_USBDEVCTRL=y
CONFIG_BOARD_LOOPSPERMSEC=15272
CONFIG_BUILTIN=y
CONFIG_CDCACM=y
CONFIG_CDCACM_CONSOLE=y
CONFIG_CDCACM_RXBUFSIZE=256
CONFIG_CDCACM_TXBUFSIZE=256
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_MM_REGIONS=2
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAMLOG=y
CONFIG_RAMLOG_BUFSIZE=4096
CONFIG_RAMLOG_SYSLOG=y
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=27
CONFIG_START_YEAR=2013
CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_OTGFS=y
CONFIG_STM32_PWR=y
CONFIG_STM32_USART2=y
CONFIG_SYSTEM_NSH=y
CONFIG_USBDEV=y

View File

@ -0,0 +1,210 @@
/****************************************************************************
* boards/arm/stm32/odrive36/include/board.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 __BOARDS_ARM_STM32_ODRIVE36_INCLUDE_BOARD_H
#define __BOARDS_ARM_STM32_ODRIVE36_INCLUDE_BOARD_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
#include "stm32_rcc.h"
#include "stm32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Clocking *****************************************************************/
/* HSI - 16 MHz RC factory-trimmed
* LSI - 32 KHz RC (30-60KHz, uncalibrated)
* HSE - On-board crystal frequency is 8MHz
* LSE - 32.768 kHz
*/
#define STM32_BOARD_XTAL 8000000ul
#define STM32_HSI_FREQUENCY 16000000ul
#define STM32_LSI_FREQUENCY 32000
#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL
#define STM32_LSE_FREQUENCY 32768
/* Main PLL Configuration.
*
* PLL source is HSE
* PLL_VCO = (STM32_HSE_FREQUENCY / PLLM) * PLLN
* = (8,000,000 / 8) * 336
* = 336,000,000
* SYSCLK = PLL_VCO / PLLP
* = 336,000,000 / 2 = 168,000,000
* USB OTG FS, SDIO and RNG Clock
* = PLL_VCO / PLLQ
* = 48,000,000
*/
#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(8)
#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(336)
#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_2
#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(7)
#define STM32_SYSCLK_FREQUENCY 168000000ul
/* AHB clock (HCLK) is SYSCLK (168MHz) */
#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */
#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY
/* APB1 clock (PCLK1) is HCLK/4 (42MHz) */
#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd4 /* PCLK1 = HCLK / 4 */
#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/4)
/* Timers driven from APB1 will be twice PCLK1 */
#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY)
/* APB2 clock (PCLK2) is HCLK/2 (84MHz) */
#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */
#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2)
/* Timers driven from APB2 will be twice PCLK2 */
#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY)
#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY)
#define STM32_APB2_TIM9_CLKIN (2*STM32_PCLK2_FREQUENCY)
#define STM32_APB2_TIM10_CLKIN (2*STM32_PCLK2_FREQUENCY)
#define STM32_APB2_TIM11_CLKIN (2*STM32_PCLK2_FREQUENCY)
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
* otherwise frequency is 2xAPBx.
* Note: TIM1,8 are on APB2, others on APB1
*/
#define BOARD_TIM1_FREQUENCY STM32_HCLK_FREQUENCY
#define BOARD_TIM2_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
#define BOARD_TIM3_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
#define BOARD_TIM4_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
#define BOARD_TIM5_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
#define BOARD_TIM6_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
#define BOARD_TIM7_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
#define BOARD_TIM8_FREQUENCY STM32_HCLK_FREQUENCY
/* DMA Channel/Stream Selections ********************************************/
/* ADC 1 */
#define ADC1_DMA_CHAN DMAMAP_ADC1_1
/* Alternate function pin selections ****************************************/
/* ADC */
#define GPIO_ADC1_IN4 GPIO_ADC1_IN4_0
#define GPIO_ADC1_IN5 GPIO_ADC1_IN5_0
#define GPIO_ADC1_IN6 GPIO_ADC1_IN6_0
#define GPIO_ADC1_IN15 GPIO_ADC1_IN15_0
#define GPIO_ADC2_IN10 GPIO_ADC2_IN10_0
#define GPIO_ADC2_IN11 GPIO_ADC2_IN11_0
#define GPIO_ADC2_IN12 GPIO_ADC2_IN13_0
#define GPIO_ADC3_IN12 GPIO_ADC3_IN12_0
#define GPIO_ADC3_IN13 GPIO_ADC3_IN13_0
/* USART2:
* USART2_TX - PA2 - GPIO_3
* USART2_RX - PA3 - GPIO_4
*/
#define GPIO_USART2_RX (GPIO_USART2_RX_1|GPIO_SPEED_100MHz)
#define GPIO_USART2_TX (GPIO_USART2_TX_1|GPIO_SPEED_100MHz)
/* CAN:
* CAN_R - PB8
* CAN_T - PB9
*/
#define GPIO_CAN1_RX (GPIO_CAN1_RX_2|GPIO_SPEED_50MHz)
#define GPIO_CAN1_TX (GPIO_CAN1_TX_2|GPIO_SPEED_50MHz)
/* SPI3 - connected to DRV8301
* SPI3_SCK - PC10
* SPI3_MISO - PC11
* SPI3_MOSI - PC12
*/
#define GPIO_SPI3_SCK (GPIO_SPI3_SCK_2|GPIO_SPEED_50MHz)
#define GPIO_SPI3_MISO (GPIO_SPI3_MISO_2|GPIO_SPEED_50MHz)
#define GPIO_SPI3_MOSI (GPIO_SPI3_MOSI_2|GPIO_SPEED_50MHz)
/* USBDEV */
#define GPIO_OTGFS_DM (GPIO_OTGFS_DM_0|GPIO_SPEED_100MHz)
#define GPIO_OTGFS_DP (GPIO_OTGFS_DP_0|GPIO_SPEED_100MHz)
#define GPIO_OTGFS_ID (GPIO_OTGFS_ID_0|GPIO_SPEED_100MHz)
/* Dual FOC configuration */
/* TIM1 configuration *******************************************************/
#define GPIO_TIM1_CH1OUT (GPIO_TIM1_CH1OUT_1|GPIO_SPEED_100MHz) /* TIM1 CH1 - PA8 - U high */
#define GPIO_TIM1_CH1NOUT (GPIO_TIM1_CH1N_2|GPIO_SPEED_100MHz) /* TIM1 CH1N - PB13 - U low */
#define GPIO_TIM1_CH2OUT (GPIO_TIM1_CH2OUT_1|GPIO_SPEED_100MHz) /* TIM1 CH2 - PA9 - V high */
#define GPIO_TIM1_CH2NOUT (GPIO_TIM1_CH2N_2|GPIO_SPEED_100MHz) /* TIM1 CH2N - PB14 - V low */
#define GPIO_TIM1_CH3OUT (GPIO_TIM1_CH3OUT_1|GPIO_SPEED_100MHz) /* TIM1 CH3 - PA10 - W high */
#define GPIO_TIM1_CH3NOUT (GPIO_TIM1_CH3N_2|GPIO_SPEED_100MHz) /* TIM1 CH3N - PB15 - W low */
#define GPIO_TIM1_CH4OUT 0 /* not used as output */
/* TIM8 configuration *******************************************************/
#define GPIO_TIM8_CH1OUT (GPIO_TIM8_CH1OUT_1|GPIO_SPEED_100MHz) /* TIM8 CH1 - PC6 - U high */
#define GPIO_TIM8_CH1NOUT (GPIO_TIM8_CH1N_2|GPIO_SPEED_100MHz) /* TIM8 CH1N - PA7 - U low */
#define GPIO_TIM8_CH2OUT (GPIO_TIM8_CH2OUT_1|GPIO_SPEED_100MHz) /* TIM8 CH2 - PC7 - V high */
#define GPIO_TIM8_CH2NOUT (GPIO_TIM8_CH2N_1|GPIO_SPEED_100MHz) /* TIM8 CH2N - PB0 - V low */
#define GPIO_TIM8_CH3OUT (GPIO_TIM8_CH3OUT_1|GPIO_SPEED_100MHz) /* TIM8 CH3 - PC8 - W high */
#define GPIO_TIM8_CH3NOUT (GPIO_TIM8_CH3N_1|GPIO_SPEED_100MHz) /* TIM8 CH3N - PB1 - W low */
#define GPIO_TIM8_CH4OUT 0 /* not used as output */
/* QEN3 configuration *******************************************************/
#define GPIO_TIM3_CH1IN (GPIO_TIM3_CH1IN_2|GPIO_SPEED_50MHz) /* TIM3 CH1IN - PB4 */
#define GPIO_TIM3_CH2IN (GPIO_TIM3_CH2IN_2|GPIO_SPEED_50MHz) /* TIM3 CH2IN - PB5 */
/* QEN4 configuration *******************************************************/
#define GPIO_TIM4_CH1IN (GPIO_TIM4_CH1IN_1|GPIO_SPEED_50MHz) /* TIM4 CH1IN - PB6 */
#define GPIO_TIM4_CH2IN (GPIO_TIM4_CH2IN_1|GPIO_SPEED_50MHz) /* TIM4 CH2IN - PB7 */
#endif /* __BOARDS_ARM_STM32_ODRIVE36_INCLUDE_BOARD_H */

View File

@ -0,0 +1,40 @@
############################################################################
# boards/arm/stm32/odrive36/scripts/Make.defs
#
# 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.
#
############################################################################
include $(TOPDIR)/.config
include $(TOPDIR)/tools/Config.mk
include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs
LDSCRIPT = ld.script
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
AFLAGS := $(CFLAGS) -D__ASSEMBLY__
NXFLATLDFLAGS1 = -r -d -warn-common
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
LDNXFLATFLAGS = -e main -s 2048

View File

@ -0,0 +1,123 @@
/****************************************************************************
* boards/arm/stm32/odrive36/scripts/ld.script
*
* 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.
*
****************************************************************************/
/* The STM32F405RGT6 has 1024Kb of FLASH beginning at address 0x0800:0000 and
* 192Kb of SRAM. SRAM is split up into two blocks:
*
* 1) 112Kb of SRAM beginning at address 0x2000:0000
* 2) 16Kb of SRAM beginning at address 0x2001:c000
* 3) 64Kb of SRAM beginning at address 0x2002:0000
*
* When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
* where the code expects to begin execution by jumping to the entry point in
* the 0x0800:0000 address
* range.
*/
MEMORY
{
flash (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
sram (rwx) : ORIGIN = 0x20000000, LENGTH = 112K
}
OUTPUT_ARCH(arm)
EXTERN(_vectors)
ENTRY(_stext)
SECTIONS
{
.text : {
_stext = ABSOLUTE(.);
*(.vectors)
*(.text .text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata .rodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.got)
*(.gcc_except_table)
*(.gnu.linkonce.r.*)
_etext = ABSOLUTE(.);
} > flash
.init_section : ALIGN(4) {
_sinit = ABSOLUTE(.);
KEEP(*(.init_array .init_array.*))
_einit = ABSOLUTE(.);
} > flash
.ARM.extab : ALIGN(4) {
*(.ARM.extab*)
} > flash
.ARM.exidx : ALIGN(4) {
__exidx_start = ABSOLUTE(.);
*(.ARM.exidx*)
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {
_sdata = ABSOLUTE(.);
*(.data .data.*)
*(.gnu.linkonce.d.*)
CONSTRUCTORS
. = ALIGN(4);
_edata = ABSOLUTE(.);
} > sram AT > flash
.bss : ALIGN(4) {
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = ABSOLUTE(.);
} > sram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}

View File

@ -0,0 +1,41 @@
# ##############################################################################
# boards/arm/stm32/odrive36/src/CMakeLists.txt
#
# 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.
#
# ##############################################################################
set(SRCS stm32_boot.c stm32_bringup.c)
if(CONFIG_STM32_SPI)
list(APPEND SRCS stm32_spi.c)
endif()
if(CONFIG_BOARDCTL)
list(APPEND SRCS stm32_appinit.c)
endif()
if(CONFIG_STM32_FOC)
list(APPEND SRCS stm32_foc.c)
endif()
if(CONFIG_STM32_OTGFS)
list(APPEND SRCS stm32_usb.c)
endif()
target_sources(board PRIVATE ${SRCS})
set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/ld.script")

View File

@ -0,0 +1,43 @@
############################################################################
# boards/arm/stm32/odrive36/src/Make.defs
#
# 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.
#
############################################################################
include $(TOPDIR)/Make.defs
CSRCS = stm32_boot.c stm32_bringup.c
ifeq ($(CONFIG_STM32_SPI),y)
CSRCS += stm32_spi.c
endif
ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += stm32_appinit.c
endif
ifeq ($(CONFIG_STM32_FOC),y)
CSRCS += stm32_foc.c
endif
ifeq ($(CONFIG_STM32_OTGFS),y)
CSRCS += stm32_usb.c
endif
DEPPATH += --dep-path board
VPATH += :board
CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)

View File

@ -0,0 +1,155 @@
/****************************************************************************
* boards/arm/stm32/odrive36/src/odrive.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 __BOARDS_ARM_STM32_ODRIVE36_SRC_ODRIVE_H
#define __BOARDS_ARM_STM32_ODRIVE36_SRC_ODRIVE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* procfs File System */
#ifdef CONFIG_FS_PROCFS
# ifdef CONFIG_NSH_PROC_MOUNTPOINT
# define STM32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT
# else
# define STM32_PROCFS_MOUNTPOINT "/proc"
# endif
#endif
/* DRV8301 pins */
#define GPIO_DRV8301_ENGATE (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz| \
GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN12)
#define GPIO_DRV8301_NFAULT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTD| \
GPIO_PIN2)
/* SPI chip selects */
#define GPIO_GATEDRV0_CS (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz| \
GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN13)
#define GPIO_GATEDRV1_CS (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz| \
GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN14)
/* QE index pins */
#define GPIO_QE3_INDEX (GPIO_INPUT | GPIO_FLOAT | \
GPIO_EXTI | GPIO_PORTC | GPIO_PIN9)
#define GPIO_QE4_INDEX (GPIO_INPUT | GPIO_FLOAT | \
GPIO_EXTI | GPIO_PORTC | GPIO_PIN15)
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: stm32_bringup
*
* Description:
* Perform architecture specific initialization
*
* CONFIG_LIB_BOARDCTL=y:
* If CONFIG_NSH_ARCHINITIALIZE=y:
* Called from the NSH library (or other application)
* Otherwise, assumed to be called from some other application.
*
* Otherwise CONFIG_BOARD_LATE_INITIALIZE=y:
* Called from board_late_initialize().
*
* Otherwise, bad news: Never called
*
****************************************************************************/
int stm32_bringup(void);
/****************************************************************************
* Name: stm32_spidev_initialize
*
* Description:
* Called to configure SPI chip select GPIO pins.
*
****************************************************************************/
void stm32_spidev_initialize(void);
/****************************************************************************
* Name: stm32_adc_setup
*
* Description:
* Initialize ADC and register the ADC driver.
*
****************************************************************************/
#ifdef CONFIG_ADC
int stm32_adc_setup(void);
#endif
/****************************************************************************
* Name: stm32_dac_setup
*
* Description:
* Initialize DAC and register the DAC driver.
*
****************************************************************************/
#ifdef CONFIG_DAC
int stm32_dac_setup(void);
#endif
/****************************************************************************
* Name: stm32_foc_setup
*
* Description:
* Initialize FOC peripherals for the board.
*
****************************************************************************/
#ifdef CONFIG_STM32_FOC
int stm32_foc_setup(void);
#endif
/****************************************************************************
* Name: stm32_usbinitialize
*
* Description:
* Called from stm32_usbinitialize very early in initialization to setup
* USB-related GPIO pins for the STM32F4Discovery board.
*
****************************************************************************/
#ifdef CONFIG_STM32_OTGFS
void weak_function stm32_usbinitialize(void);
#endif
#endif /* __BOARDS_ARM_STM32_ODRIVE36_SRC_ODRIVE_H */

View File

@ -0,0 +1,71 @@
/****************************************************************************
* boards/arm/stm32/odrive36/src/stm32_appinit.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 <sys/types.h>
#include "odrive.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_app_initialize
*
* Description:
* Perform application specific initialization. This function is never
* called directly from application code, but only indirectly via the
* (non-standard) boardctl() interface using the command BOARDIOC_INIT.
*
* Input Parameters:
* arg - The boardctl() argument is passed to the board_app_initialize()
* implementation without modification. The argument has no
* meaning to NuttX; the meaning of the argument is a contract
* between the board-specific initialization logic and the
* matching application logic. The value could be such things as a
* mode enumeration value, a set of DIP switch switch settings, a
* pointer to configuration data read from a file or serial FLASH,
* or whatever you would like to do with it. Every implementation
* should accept zero/NULL as a default configuration.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure to indicate the nature of the failure.
*
****************************************************************************/
int board_app_initialize(uintptr_t arg)
{
#ifdef CONFIG_BOARD_LATE_INITIALIZE
/* Board initialization already performed by board_late_initialize() */
return OK;
#else
/* Perform board-specific initialization */
return stm32_bringup();
#endif
}

View File

@ -0,0 +1,105 @@
/****************************************************************************
* boards/arm/stm32/odrive36/src/stm32_boot.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 <debug.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <nuttx/spi/spi.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "odrive.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_boardinitialize
*
* Description:
* All STM32 architectures must provide the following entry point. This
* entry point is called early in the initialization -- after all memory
* has been configured and mapped but before any devices have been
* initialized.
*
****************************************************************************/
void stm32_boardinitialize(void)
{
#ifdef CONFIG_SEGGER_SYSVIEW
up_perf_init((void *)STM32_SYSCLK_FREQUENCY);
#endif
#ifdef CONFIG_ARCH_LEDS
/* Configure on-board LEDs if LED support has been selected. */
board_autoled_initialize();
#endif
#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) || \
defined(CONFIG_STM32_SPI3)
/* Configure SPI chip selects if 1) SP2 is not disabled, and 2) the weak
* function stm32_spidev_initialize() has been brought into the link.
*/
stm32_spidev_initialize();
#endif
#ifdef CONFIG_STM32_OTGFS
/* Initialize USB is 1) USBDEV is selected, 2) the USB controller is not
* disabled, and 3) the weak function stm32_usbinitialize() has been
* brought into the build.
*/
stm32_usbinitialize();
#endif
}
/****************************************************************************
* Name: board_late_initialize
*
* Description:
* If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
* initialization call will be performed in the boot-up sequence to a
* function called board_late_initialize(). board_late_initialize() will
* be called immediately after up_initialize() is called and just before
* the initial application is started. This additional initialization
* phase may be used, for example, to initialize board-specific device
* drivers.
*
****************************************************************************/
#ifdef CONFIG_BOARD_LATE_INITIALIZE
void board_late_initialize(void)
{
/* Perform board-specific initialization */
stm32_bringup();
}
#endif

View File

@ -0,0 +1,141 @@
/****************************************************************************
* boards/arm/stm32/odrive36/src/stm32_bringup.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 <debug.h>
#include <arch/board/board.h>
#include <nuttx/usb/cdcacm.h>
#include <nuttx/fs/fs.h>
#ifdef CONFIG_SENSORS_QENCODER
# include "board_qencoder.h"
# include "stm32_qencoder.h"
#endif
#include "odrive.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_bringup
*
* Description:
* Perform architecture-specific initialization
*
* CONFIG_BOARD_LATE_INITIALIZE=y :
* Called from board_late_initialize().
*
* CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_LIB_BOARDCTL=y :
* Called from the NSH library
*
****************************************************************************/
int stm32_bringup(void)
{
int ret = OK;
#ifdef CONFIG_FS_PROCFS
/* Mount the procfs file system */
ret = nx_mount(NULL, STM32_PROCFS_MOUNTPOINT, "procfs", 0, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to mount the PROC filesystem: %d\n",
ret);
}
#endif /* CONFIG_FS_PROCFS */
#if defined(CONFIG_CDCACM) && !defined(CONFIG_CDCACM_CONSOLE)
/* Initialize CDCACM */
ret = cdcacm_initialize(0, NULL);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: cdcacm_initialize failed: %d\n", ret);
}
#endif /* CONFIG_CDCACM & !CONFIG_CDCACM_CONSOLE */
#if defined(CONFIG_STM32_TIM3_QE) && defined(CONFIG_SENSORS_QENCODER)
/* Initialize and register the qencoder driver - TIM3 */
ret = board_qencoder_initialize(0, 3);
if (ret != OK)
{
syslog(LOG_ERR, "ERROR: Failed to register the qencoder: %d\n", ret);
}
/* Connect QE index pin */
ret = stm32_qe_index_init(3, GPIO_QE3_INDEX);
if (ret != OK)
{
syslog(LOG_ERR, "ERROR: Failed to register qe index pin: %d\n", ret);
}
#endif
#if defined(CONFIG_STM32_TIM4_QE) && defined(CONFIG_SENSORS_QENCODER)
/* Initialize and register the qencoder driver - TIM4 */
ret = board_qencoder_initialize(1, 4);
if (ret != OK)
{
syslog(LOG_ERR, "ERROR: Failed to register the qencoder: %d\n", ret);
}
/* Connect QE index pin */
ret = stm32_qe_index_init(4, GPIO_QE4_INDEX);
if (ret != OK)
{
syslog(LOG_ERR, "ERROR: Failed to register qe index pin: %d\n", ret);
}
#endif
#ifdef CONFIG_ADC
/* Initialize ADC and register the ADC driver. */
ret = stm32_adc_setup();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: stm32_adc_setup failed: %d\n", ret);
}
#endif
#ifdef CONFIG_STM32_FOC
/* Initialize and register FOC devices */
ret = stm32_foc_setup();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: stm32_foc_setup failed: %d\n", ret);
}
#endif
return ret;
}

View File

@ -0,0 +1,962 @@
/****************************************************************************
* boards/arm/stm32/odrive36/src/stm32_foc.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/mutex.h>
#include <nuttx/signal.h>
#include <nuttx/analog/adc.h>
#include <nuttx/motor/foc/drv8301.h>
#include <nuttx/motor/motor_ioctl.h>
#include "stm32_foc.h"
#include "stm32_gpio.h"
#ifdef CONFIG_ADC
# include "stm32_adc.h"
#endif
#include "odrive.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_ODRIVE_HW_VOLTAGE_56
# error Tested only for ODrive 56V version
#endif
/* Supported FOC instances */
#ifdef CONFIG_ODRIVE_FOC_FOC0
# define ODRIVE_FOC_FOC0 1
#else
# define ODRIVE_FOC_FOC0 0
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC1
# define ODRIVE_FOC_FOC1 1
#else
# define ODRIVE_FOC_FOC1 0
#endif
#define ODRIVE_FOC_INST (ODRIVE_FOC_FOC0 + ODRIVE_FOC_FOC1)
#ifdef CONFIG_ODRIVE_FOC_FOC0
# define ODRIVE32_FOC0_DEVPATH "/dev/foc0"
# define ODRIVE32_FOC0_INST (0)
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC1
# define ODRIVE32_FOC1_DEVPATH "/dev/foc1"
# define ODRIVE32_FOC1_INST (1)
#endif
/* Must match upper-half configuration */
#if ODRIVE_FOC_INST != CONFIG_MOTOR_FOC_INST
# error Invalid configuration
#endif
/* Only 2-shunt configuration supported by board */
#if CONFIG_MOTOR_FOC_SHUNTS != 2
# error For now ony 2-shunts configuration is supported
#endif
/* Configuration specific for DRV8301:
* 1. PWM channels must have positive polarity
* 2. PWM complementary channels must have positive polarity
*/
#ifndef CONFIG_STM32_FOC_HAS_PWM_COMPLEMENTARY
# error
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC0
# if CONFIG_STM32_TIM1_CH1POL != 0
# error
# endif
# if CONFIG_STM32_TIM1_CH2POL != 0
# error
# endif
# if CONFIG_STM32_TIM1_CH3POL != 0
# error
# endif
# if CONFIG_STM32_TIM1_CH1NPOL != 0
# error
# endif
# if CONFIG_STM32_TIM1_CH2NPOL != 0
# error
# endif
# if CONFIG_STM32_TIM1_CH3NPOL != 0
# error
# endif
/* FOC0 uses ADC2 */
# ifndef CONFIG_STM32_FOC_FOC0_ADC2
# error
# endif
# if CONFIG_STM32_ADC2_RESOLUTION != 0
# error
# endif
#endif /* CONFIG_ODRIVE_FOC_FOC0 */
#ifdef CONFIG_ODRIVE_FOC_FOC1
# if CONFIG_STM32_TIM8_CH1POL != 0
# error
# endif
# if CONFIG_STM32_TIM8_CH2POL != 0
# error
# endif
# if CONFIG_STM32_TIM8_CH3POL != 0
# error
# endif
# if CONFIG_STM32_TIM8_CH1NPOL != 0
# error
# endif
# if CONFIG_STM32_TIM8_CH2NPOL != 0
# error
# endif
# if CONFIG_STM32_TIM8_CH3NPOL != 0
# error
# endif
/* FOC1 uses ADC3 */
# ifndef CONFIG_STM32_FOC_FOC1_ADC3
# error
# endif
# if CONFIG_STM32_ADC3_RESOLUTION != 0
# error
# endif
#endif /* CONFIG_ODRIVE_FOC_FOC1 */
/* Aux ADC needs DMA enabled */
#ifdef CONFIG_ADC
# ifndef CONFIG_STM32_ADC1_DMA
# error
# endif
# ifndef CONFIG_STM32_ADC1_SCAN
# error
# endif
#endif
/* TODO: */
#define PWM_DEADTIME (50)
#define PWM_DEADTIME_NS (320)
/* Board parameters:
* Current shunt resistance = 0.0005
* Current sense gain = (10/20/40/80)
* Vbus min = 12V
* Vbus max = 24V or 56V
* Iout max = 40A (no cooling for
* MOSFETs)
* IPHASE_RATIO = 1/(R_shunt*gain)
* 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.02014 (gain=80)
* VBUS_RATIO = 1/VBUS_gain = 11 or 19
*/
#define ADC_VOLT_REF 3300000 /* micro volt */
#define ADC_VAL_MAX 4095
#define R_SHUNT 500 /* micro ohm */
/* Center-aligned PWM duty cycle limits */
#define MAX_DUTY_B16 ftob16(0.95f)
/* ADC configuration */
#define CURRENT_SAMPLE_TIME ADC_SMPR_3
#define VBUS_SAMPLE_TIME ADC_SMPR_15
#define TEMP_SAMPLE_TIME ADC_SMPR_15
#define ODRIVE_ADC_AUX (1)
#define ODRIVE_ADC_FOC0 (2)
#define ODRIVE_ADC_FOC1 (3)
#ifdef CONFIG_ODRIVE_FOC_VBUS
# define ODRIVE_FOC_VBUS 1
#else
# define ODRIVE_FOC_VBUS 0
#endif
#ifdef CONFIG_ODRIVE_FOC_TEMP
# define ODRIVE_FOC_TEMP 3
#else
# define ODRIVE_FOC_TEMP 0
#endif
#ifdef CONFIG_ADC
# define ODRIVE_ADC_AUX_DEVPATH "/dev/adc0"
# define ODRIVE_ADC_AUX_NCHAN (ODRIVE_FOC_VBUS + ODRIVE_FOC_TEMP)
#endif
#define ADC1_INJECTED (0)
#define ADC1_REGULAR (0)
#define ADC1_NCHANNELS (ADC1_INJECTED + ADC1_REGULAR)
#define ADC2_INJECTED (CONFIG_MOTOR_FOC_SHUNTS)
#define ADC2_REGULAR (0)
#define ADC2_NCHANNELS (ADC2_INJECTED + ADC2_REGULAR)
#define ADC3_INJECTED (CONFIG_MOTOR_FOC_SHUNTS)
#define ADC3_REGULAR (0)
#define ADC3_NCHANNELS (ADC3_INJECTED + ADC3_REGULAR)
#if ADC1_INJECTED != CONFIG_STM32_ADC1_INJECTED_CHAN
# error
#endif
#if ADC2_INJECTED != CONFIG_STM32_ADC2_INJECTED_CHAN
# error
#endif
#if ADC3_INJECTED != CONFIG_STM32_ADC3_INJECTED_CHAN
# error
#endif
/* DRV8301 configuration */
#ifndef CONFIG_STM32_SPI3
# error
#endif
#define DRV8301_0_SPI (3)
#define DRV8301_1_SPI (3)
#define DRV8301_FREQUENCY (500000)
/* Qenco configuration */
#ifdef CONFIG_SENSORS_QENCODER
# ifndef CONFIG_STM32_QENCODER_DISABLE_EXTEND16BTIMERS
# error Invalid configuration
# endif
# ifndef CONFIG_STM32_QENCODER_INDEX_PIN
# error Invalid configuration
# endif
# ifdef CONFIG_STM32_TIM3_QE
# if CONFIG_STM32_TIM3_QEPSC != 0
# error Invalid TIM3 QEPSC value
# endif
# endif
# ifdef CONFIG_STM32_TIM4_QE
# if CONFIG_STM32_TIM4_QEPSC != 0
# error Invalid TIM4 QEPSC value
# endif
# endif
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Protototypes
****************************************************************************/
static int board_foc_setup(struct foc_dev_s *dev);
static int board_foc_shutdown(struct foc_dev_s *dev);
static int board_foc_calibration(struct foc_dev_s *dev, bool state);
static int board_foc_fault_clear(struct foc_dev_s *dev);
static int board_foc_pwm_start(struct foc_dev_s *dev, bool state);
static int board_foc_current_get(struct foc_dev_s *dev, int16_t *curr_raw,
foc_current_t *curr);
static int board_foc_info_get(struct foc_dev_s *dev,
struct foc_info_s *info);
static int board_foc_ioctl(struct foc_dev_s *dev, int cmd,
unsigned long arg);
#ifdef CONFIG_MOTOR_FOC_TRACE
static int board_foc_trace_init(struct foc_dev_s *dev);
static void board_foc_trace(struct foc_dev_s *dev, int type, bool state);
#endif
static int stm32_foc_drv8301_fault_attach(struct focpwr_dev_s *dev,
xcpt_t isr, void *arg);
static int stm32_foc_drv8301_gate_enable(struct focpwr_dev_s *dev,
bool enable);
static void stm32_foc_drv8301_fault_handle(struct focpwr_dev_s *dev);
static int stm32_focdev_setup(int devno, int spino,
struct stm32_foc_board_s *board);
/****************************************************************************
* 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,
.info_get = board_foc_info_get,
.ioctl = board_foc_ioctl,
#ifdef CONFIG_MOTOR_FOC_TRACE
.trace_init = board_foc_trace_init,
.trace = board_foc_trace
#endif
};
/* Board specific ADC configuration
*
* AUX (only VBUS used):
* VBUS - ADC1 - ADC1_IN6 (PA6)
* M0_TEMP - ADC1 - ADC1_IN15 (PC5)
* M1_TEMP - ADC1 - ADC1_IN4 (PA4)
* AUX_TEMP - ADC1 - ADC1_IN5 (PA5)
*
* FOC device 0:
* Phase 1 - ADC2 - ADC2_IN10 (PC0)
* Phase 2 - ADC2 - ADC2_IN11 (PC1)
*
* FOC device 1:
* Phase 1 - ADC3 - ADC3_IN13 (PC3)
* Phase 2 - ADC3 - ADC3_IN12 (PC2)
*
*/
#ifdef CONFIG_ADC
/* AUX ADC configuration */
static uint8_t g_adc_aux_chan[] =
{
#ifdef CONFIG_ODRIVE_FOC_VBUS
6,
#endif
#ifdef ODRIVE_ADC_TEMP
15,
4,
5
#endif
};
static uint32_t g_adc_aux_pins[] =
{
#ifdef CONFIG_ODRIVE_FOC_VBUS
GPIO_ADC1_IN6,
#endif
#ifdef ODRIVE_ADC_TEMP
GPIO_ADC1_IN15,
GPIO_ADC1_IN4,
GPIO_ADC1_IN5
#endif
};
static adc_channel_t g_adc_aux_stime[] =
{
#ifdef CONFIG_ODRIVE_FOC_VBUS
{
.channel = 6,
.sample_time = VBUS_SAMPLE_TIME
},
#endif
#ifdef ODRIVE_ADC_TEMP
{
.channel = 15,
.sample_time = TEMP_SAMPLE_TIME
},
{
.channel = 4,
.sample_time = TEMP_SAMPLE_TIME
},
{
.channel = 5,
.sample_time = TEMP_SAMPLE_TIME
}
#endif
};
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC0
/* Board specific ADC configuration for FOC device 0 */
static uint8_t g_adc_foc0_chan[] =
{
10,
11
};
static uint32_t g_adc_foc0_pins[] =
{
GPIO_ADC2_IN10,
GPIO_ADC2_IN11,
};
static adc_channel_t g_adc_foc0_stime[] =
{
{
.channel = 10,
.sample_time = CURRENT_SAMPLE_TIME
},
{
.channel = 11,
.sample_time = CURRENT_SAMPLE_TIME
}
};
static struct stm32_foc_adc_s g_adc_foc0_cfg =
{
.chan = g_adc_foc0_chan,
.pins = g_adc_foc0_pins,
.stime = g_adc_foc0_stime,
.nchan = ADC2_NCHANNELS,
.regch = ADC2_REGULAR,
.intf = ODRIVE_ADC_FOC0
};
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC1
/* Board specific ADC configuration for FOC device 1 */
static uint8_t g_adc_foc1_chan[] =
{
13,
12
};
static uint32_t g_adc_foc1_pins[] =
{
GPIO_ADC3_IN13,
GPIO_ADC3_IN12,
};
static adc_channel_t g_adc_foc1_stime[] =
{
{
.channel = 13,
.sample_time = CURRENT_SAMPLE_TIME
},
{
.channel = 12,
.sample_time = CURRENT_SAMPLE_TIME
}
};
static struct stm32_foc_adc_s g_adc_foc1_cfg =
{
.chan = g_adc_foc1_chan,
.pins = g_adc_foc1_pins,
.stime = g_adc_foc1_stime,
.nchan = ADC3_NCHANNELS,
.regch = ADC3_REGULAR,
.intf = ODRIVE_ADC_FOC1
};
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC0
/* Board specific data - FOC 0 */
static struct stm32_foc_board_data_s g_stm32_foc0_board_data =
{
.adc_cfg = &g_adc_foc0_cfg,
.pwm_dt = (PWM_DEADTIME),
};
/* Board specific configuration */
static struct stm32_foc_board_s g_stm32_foc0_board =
{
.data = &g_stm32_foc0_board_data,
.ops = &g_stm32_foc_board_ops,
};
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC1
/* Board specific data - FOC 1 */
static struct stm32_foc_board_data_s g_stm32_foc1_board_data =
{
.adc_cfg = &g_adc_foc1_cfg,
.pwm_dt = (PWM_DEADTIME),
};
/* Board specific configuration */
static struct stm32_foc_board_s g_stm32_foc1_board =
{
.data = &g_stm32_foc1_board_data,
.ops = &g_stm32_foc_board_ops,
};
#endif
/* DRV8301 board ops */
static struct drv8301_ops_s g_drv8301_board_ops =
{
.fault_attach = stm32_foc_drv8301_fault_attach,
.gate_enable = stm32_foc_drv8301_gate_enable,
.fault_handle = stm32_foc_drv8301_fault_handle
};
/* Global data */
static mutex_t g_common_lock = NXMUTEX_INITIALIZER;
static bool g_fault_attached = false;
static bool g_gate_enabled = false;
static struct foc_dev_s *g_foc_dev[2] =
{
NULL,
NULL
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: board_foc_setup
****************************************************************************/
static int board_foc_setup(struct foc_dev_s *dev)
{
DEBUGASSERT(dev);
DEBUGASSERT(dev->pwr);
return dev->pwr->ops->setup(dev->pwr);
}
/****************************************************************************
* Name: board_foc_shutdown
****************************************************************************/
static int board_foc_shutdown(struct foc_dev_s *dev)
{
DEBUGASSERT(dev);
DEBUGASSERT(dev->pwr);
return dev->pwr->ops->shutdown(dev->pwr);
}
/****************************************************************************
* Name: board_foc_calibration
****************************************************************************/
static int board_foc_calibration(struct foc_dev_s *dev, bool state)
{
DEBUGASSERT(dev);
DEBUGASSERT(dev->pwr);
return dev->pwr->ops->calibration(dev->pwr, state);
}
/****************************************************************************
* Name: board_foc_fault_clear
****************************************************************************/
static int board_foc_fault_clear(struct foc_dev_s *dev)
{
DEBUGASSERT(dev);
UNUSED(dev);
/* TODO: clear DRV8301 faults */
return OK;
}
/****************************************************************************
* Name: board_foc_pwm_start
****************************************************************************/
static int board_foc_pwm_start(struct foc_dev_s *dev, bool state)
{
DEBUGASSERT(dev);
return OK;
}
/****************************************************************************
* Name: board_foc_current_get
****************************************************************************/
static int board_foc_current_get(struct foc_dev_s *dev, int16_t *curr_raw,
foc_current_t *curr)
{
DEBUGASSERT(dev);
DEBUGASSERT(curr_raw);
DEBUGASSERT(curr);
/* Get currents */
curr[1] = curr_raw[0];
curr[2] = curr_raw[1];
/* From Kirchhoff's current law: ia = -(ib + ic) */
curr[0] = -(curr[1] + curr[2]);
return OK;
}
/****************************************************************************
* Name: board_foc_info_get
****************************************************************************/
static int board_foc_info_get(struct foc_dev_s *dev,
struct foc_info_s *info)
{
struct foc_get_boardcfg_s cfg;
DEBUGASSERT(dev);
DEBUGASSERT(info);
UNUSED(dev);
/* PWM */
info->hw_cfg.pwm_dt_ns = PWM_DEADTIME_NS;
info->hw_cfg.pwm_max = MAX_DUTY_B16;
/* Get power stage configuration */
board_foc_ioctl(dev, MTRIOC_GET_BOARDCFG, (unsigned long)&cfg);
/* ADC Current */
info->hw_cfg.iphase_max = 40000;
info->hw_cfg.iphase_scale = ((100000ul * (ADC_VOLT_REF / ADC_VAL_MAX)) /
(cfg.gain * R_SHUNT));
return OK;
}
/****************************************************************************
* Name: board_foc_ioctl
****************************************************************************/
static int board_foc_ioctl(struct foc_dev_s *dev, int cmd, unsigned long arg)
{
DEBUGASSERT(dev);
DEBUGASSERT(dev->pwr);
return dev->pwr->ops->ioctl(dev->pwr, cmd, arg);
}
#ifdef CONFIG_MOTOR_FOC_TRACE
/****************************************************************************
* Name: board_foc_trace_init
****************************************************************************/
static int board_foc_trace_init(struct foc_dev_s *dev)
{
DEBUGASSERT(dev);
UNUSED(dev);
/* Not supported */
return -1;
}
/****************************************************************************
* Name: board_foc_trace
****************************************************************************/
static void board_foc_trace(struct foc_dev_s *dev, int type, bool state)
{
DEBUGASSERT(dev);
UNUSED(dev);
}
#endif
/****************************************************************************
* Name: stm32_foc_drv8301_fault_attach
****************************************************************************/
static int stm32_foc_drv8301_fault_attach(struct focpwr_dev_s *dev,
xcpt_t isr, void *arg)
{
int ret = OK;
nxmutex_lock(&g_common_lock);
/* nFAULT is common for both FOC instances */
if (g_fault_attached != (bool) isr)
{
ret = stm32_gpiosetevent(GPIO_DRV8301_NFAULT, false, true, false,
isr, arg);
g_fault_attached = (bool) isr;
}
nxmutex_unlock(&g_common_lock);
return ret;
}
/****************************************************************************
* Name: stm32_foc_drv8301_gate_enable
****************************************************************************/
static int stm32_foc_drv8301_gate_enable(struct focpwr_dev_s *dev,
bool enable)
{
/* ENGATE is common for both FOC instances */
nxmutex_lock(&g_common_lock);
if (enable != g_gate_enabled)
{
stm32_gpiowrite(GPIO_DRV8301_ENGATE, enable);
g_gate_enabled = enable;
}
nxmutex_unlock(&g_common_lock);
return OK;
}
/****************************************************************************
* Name: stm32_foc_drv8301_fault_handle
****************************************************************************/
static void stm32_foc_drv8301_fault_handle(struct focpwr_dev_s *dev)
{
UNUSED(dev);
/* Set fault state for both instances */
#ifdef CONFIG_ODRIVE_FOC_FOC0
g_foc_dev[0]->state.fault |= FOC_FAULT_BOARD;
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC1
g_foc_dev[1]->state.fault |= FOC_FAULT_BOARD;
#endif
/* Disable gates for both instances */
stm32_gpiowrite(GPIO_DRV8301_ENGATE, false);
}
/****************************************************************************
* Name: stm32_focdev_setup
****************************************************************************/
static int stm32_focdev_setup(int devno, int spino,
struct stm32_foc_board_s *board)
{
struct drv8301_cfg_s drv8301_cfg;
struct drv8301_board_s drv8301_board;
struct spi_dev_s *spi = NULL;
struct foc_dev_s *foc = NULL;
int ret = OK;
char devpath[20];
/* Initialize arch specific FOC 0 lower-half */
foc = stm32_foc_initialize(devno, board);
if (foc == NULL)
{
ret = -errno;
mtrerr("Failed to initialize STM32 FOC: %d\n", ret);
goto errout;
}
DEBUGASSERT(foc->lower);
/* Get devpath */
snprintf(devpath, sizeof(devpath), "/dev/foc%d", devno);
/* Get SPI device */
spi = stm32_spibus_initialize(spino);
if (spi == NULL)
{
ret = -errno;
goto errout;
}
/* DRV8301 configuration */
drv8301_cfg.freq = DRV8301_FREQUENCY;
drv8301_cfg.gate_curr = DRV8301_GATECURR_1p7;
drv8301_cfg.gain = DRV8301_GAIN_80;
drv8301_cfg.pwm_mode = DRV8301_PWM_6IN;
drv8301_cfg.oc_adj = DRV8301_OCADJ_DEFAULT;
/* DRV8301 board data */
drv8301_board.spi = spi;
drv8301_board.ops = &g_drv8301_board_ops;
drv8301_board.cfg = &drv8301_cfg;
drv8301_board.devno = devno;
/* Register DRV8301 device */
ret = drv8301_register(devpath, foc, &drv8301_board);
if (ret < 0)
{
mtrerr("Failed to register drv8301 device: %d\n", ret);
goto errout;
}
errout:
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_foc_setup
*
* Description:
* Setup FOC devices
*
* This function should be call by board_app_initialize().
*
* Returned Value:
* 0 on success, a negated errno value on failure
*
****************************************************************************/
int stm32_foc_setup(void)
{
int ret = OK;
/* Configure common EN_GATE */
stm32_configgpio(GPIO_DRV8301_ENGATE);
#ifdef CONFIG_ODRIVE_FOC_FOC0
ret = stm32_focdev_setup(0, DRV8301_0_SPI, &g_stm32_foc0_board);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: stm32_focdev_setup 0 failed: %d\n", ret);
goto errout;
}
#endif
#ifdef CONFIG_ODRIVE_FOC_FOC1
ret = stm32_focdev_setup(1, DRV8301_1_SPI, &g_stm32_foc1_board);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: stm32_focdev_setup 1 failed: %d\n", ret);
goto errout;
}
#endif
errout:
return ret;
}
#ifdef CONFIG_ADC
/****************************************************************************
* Name: stm32_adc_setup
*
* Description:
* Initialize ADC and register the ADC driver.
*
****************************************************************************/
int stm32_adc_setup(void)
{
struct adc_dev_s *adc = NULL;
struct stm32_adc_dev_s *stm32_adc = NULL;
struct adc_sample_time_s stime;
int i = 0;
int ret = OK;
/* Configure pins */
for (i = 0; i < ODRIVE_ADC_AUX_NCHAN; i += 1)
{
stm32_configgpio(g_adc_aux_pins[i]);
}
/* Initialize ADC */
adc = stm32_adcinitialize(ODRIVE_ADC_AUX, g_adc_aux_chan,
ODRIVE_ADC_AUX_NCHAN);
if (adc == NULL)
{
aerr("ERROR: Failed to get ADC interface %d\n", ODRIVE_ADC_AUX);
ret = -ENODEV;
goto errout;
}
/* Regsiter ADC */
ret = adc_register(ODRIVE_ADC_AUX_DEVPATH, adc);
if (ret < 0)
{
aerr("ERROR: adc_register %s failed: %d\n",
ODRIVE_ADC_AUX_DEVPATH, ret);
goto errout;
}
/* Get lower-half ADC */
stm32_adc = (struct stm32_adc_dev_s *)adc->ad_priv;
DEBUGASSERT(stm32_adc);
/* Configure ADC sample time */
memset(&stime, 0, sizeof(struct adc_sample_time_s));
stime.channels_nbr = ODRIVE_ADC_AUX_NCHAN;
stime.channel = g_adc_aux_stime;
STM32_ADC_SAMPLETIME_SET(stm32_adc, &stime);
STM32_ADC_SAMPLETIME_WRITE(stm32_adc);
ret = OK;
errout:
return ret;
}
#endif

View File

@ -0,0 +1,196 @@
/****************************************************************************
* boards/arm/stm32/odrive36/src/stm32_spi.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 <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/spi/spi.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "chip.h"
#include "stm32.h"
#include "odrive.h"
#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) || defined(CONFIG_STM32_SPI3)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_spidev_initialize
*
* Description:
* Called to configure SPI chip select GPIO pins for the stm32f4discovery
* board.
*
****************************************************************************/
void weak_function stm32_spidev_initialize(void)
{
#ifdef CONFIG_MOTOR_FOC
# ifdef CONFIG_ODRIVE_FOC_FOC0
stm32_configgpio(GPIO_GATEDRV0_CS);
# endif
# ifdef CONFIG_ODRIVE_FOC_FOC1
stm32_configgpio(GPIO_GATEDRV1_CS);
# endif
#endif /* CONFIG_MOTOR_FOC */
}
/****************************************************************************
* Name: stm32_spi1/2/3select and stm32_spi1/2/3status
*
* Description:
* The external functions, stm32_spi1/2/3select and stm32_spi1/2/3status
* must be provided by board-specific logic. They are implementations of
* the select and status methods of the SPI interface defined by struct
* spi_ops_s (see include/nuttx/spi/spi.h). All other methods (including
* stm32_spibus_initialize()) are provided by common STM32 logic. To use
* this common SPI logic on your board:
*
* 1. Provide logic in stm32_boardinitialize() to configure SPI chip select
* pins.
* 2. Provide stm32_spi1/2/3select() and stm32_spi1/2/3status() functions
* in your board-specific logic. These functions will perform chip
* selection and status operations using GPIOs in the way your board
* is configured.
* 3. Add a calls to stm32_spibus_initialize() in your low level
* application initialization logic
* 4. The handle returned by stm32_spibus_initialize() may then be used to
* bind the SPI driver to higher level logic (e.g., calling
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
* the SPI MMC/SD driver).
*
****************************************************************************/
#ifdef CONFIG_STM32_SPI1
void stm32_spi1select(struct spi_dev_s *dev, uint32_t devid, bool selected)
{
spiinfo("devid: %d CS: %s\n",
(int)devid, selected ? "assert" : "de-assert");
}
uint8_t stm32_spi1status(struct spi_dev_s *dev, uint32_t devid)
{
return 0;
}
#endif
#ifdef CONFIG_STM32_SPI2
void stm32_spi2select(struct spi_dev_s *dev, uint32_t devid,
bool selected)
{
spiinfo("devid: %d CS: %s\n",
(int)devid, selected ? "assert" : "de-assert");
}
uint8_t stm32_spi2status(struct spi_dev_s *dev, uint32_t devid)
{
return 0;
}
#endif
#ifdef CONFIG_STM32_SPI3
void stm32_spi3select(struct spi_dev_s *dev, uint32_t devid, bool selected)
{
spiinfo("devid: %d CS: %s\n",
(int)devid, selected ? "assert" : "de-assert");
#ifdef CONFIG_MOTOR_FOC
# ifdef CONFIG_ODRIVE_FOC_FOC0
if (devid == SPIDEV_MOTOR(0))
{
stm32_gpiowrite(GPIO_GATEDRV0_CS, !selected);
}
# endif
# ifdef CONFIG_ODRIVE_FOC_FOC1
if (devid == SPIDEV_MOTOR(1))
{
stm32_gpiowrite(GPIO_GATEDRV1_CS, !selected);
}
# endif
#endif /* CONFIG_MOTOR_FOC */
}
uint8_t stm32_spi3status(struct spi_dev_s *dev, uint32_t devid)
{
return 0;
}
#endif
/****************************************************************************
* Name: stm32_spi1cmddata
*
* Description:
* Set or clear the SH1101A A0 or SD1306 D/C n bit to select data (true)
* or command (false). This function must be provided by platform-specific
* logic. This is an implementation of the cmddata method of the SPI
* interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h).
*
* Input Parameters:
*
* spi - SPI device that controls the bus the device that requires the CMD/
* DATA selection.
* devid - If there are multiple devices on the bus, this selects which one
* to select cmd or data. NOTE: This design restricts, for example,
* one one SPI display per SPI bus.
* cmd - true: select command; false: select data
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_SPI_CMDDATA
#ifdef CONFIG_STM32_SPI1
int stm32_spi1cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
#ifdef CONFIG_STM32_SPI2
int stm32_spi2cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
#ifdef CONFIG_STM32_SPI3
int stm32_spi3cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
#endif /* CONFIG_SPI_CMDDATA */
#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 || CONFIG_STM32_SPI3 */

View File

@ -0,0 +1,103 @@
/****************************************************************************
* boards/arm/stm32/odrive36/src/stm32_usb.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 <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <sched.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/kthread.h>
#include <nuttx/usb/usbdev.h>
#include <nuttx/usb/usbdev_trace.h>
#include "arm_internal.h"
#include "stm32.h"
#include "stm32_otgfs.h"
#include "odrive.h"
#ifdef CONFIG_STM32_OTGFS
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if defined(CONFIG_USBDEV)
# define HAVE_USB 1
#else
# warning "CONFIG_STM32_OTGFS is enabled but neither CONFIG_USBDEV"
# undef HAVE_USB
#endif
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_usbinitialize
*
* Description:
* Called from stm32_usbinitialize very early in inialization to setup
* USB-related GPIO pins for the STM32F4Discovery board.
*
****************************************************************************/
void stm32_usbinitialize(void)
{
/* The OTG FS has an internal soft pull-up.
* No GPIO configuration is required
*/
}
/****************************************************************************
* Name: stm32_usbsuspend
*
* Description:
* Board logic must provide the stm32_usbsuspend logic if the USBDEV
* driver is used. This function is called whenever the USB enters or
* leaves suspend mode. This is an opportunity for the board logic to
* shutdown clocks, power, etc. while the USB is suspended.
*
****************************************************************************/
#ifdef CONFIG_USBDEV
void stm32_usbsuspend(struct usbdev_s *dev, bool resume)
{
uinfo("resume: %d\n", resume);
}
#endif
#endif /* CONFIG_STM32_OTGFS */