arch/risc-v: add support for motor control on ESP32|C6|H2

This commit is contained in:
Filipe Cavalcanti
2024-07-03 09:49:11 -03:00
committed by Alan Carvalho de Assis
parent fddebc267d
commit 65e989e063
13 changed files with 1803 additions and 65 deletions
@@ -105,15 +105,15 @@ capture
The capture configuration enables the capture driver and the capture example, allowing
the user to measure duty cycle and frequency of a signal. Default pin is GPIO 18 with
an internal pull-up resistor enabled. When connecting a 50 Hz pulse with 50% duty cycle,
the following output is expected:
the following output is expected::
nsh> cap
cap_main: Hardware initialized. Opening the capture device: /dev/capture0
cap_main: Number of samples: 0
pwm duty cycle: 50 %
pwm frequence: 50 Hz
pwm duty cycle: 50 %
pwm frequence: 50 Hz
nsh> cap
cap_main: Hardware initialized. Opening the capture device: /dev/capture0
cap_main: Number of samples: 0
pwm duty cycle: 50 %
pwm frequence: 50 Hz
pwm duty cycle: 50 %
pwm frequence: 50 Hz
coremark
--------
@@ -154,6 +154,18 @@ You can scan for all I2C devices using the following command::
nsh> i2c dev 0x00 0x7f
motor
-------
The motor configuration enables the MCPWM peripheral with support to brushed DC motor
control.
It creates a ``/dev/motor0`` device with speed and direction control capabilities
by using two GPIOs (GPIO21 and GPIO22) for PWM output. PWM frequency is configurable
from 25 Hz to 3 kHz, however it defaults to 1 kHz.
There is also support for an optional fault GPIO (defaults to GPIO9), which can be used
for quick motor braking. All GPIOs are configurable in ``menuconfig``.
mcuboot_nsh
--------------------
@@ -170,7 +170,7 @@ I2S No
Int. Temp. No
LED No
LED_PWM Yes
MCPWM Yes (Capture)
MCPWM Yes
Pulse Counter No
RMT No
RNG No
+105
View File
@@ -1309,9 +1309,105 @@ config ESPRESSIF_I2CTIMEOMS
default 500
endmenu # I2C configuration
menu "MCPWM Configuration"
depends on ESP_MCPWM
config ESP_MCPWM_MOTOR
bool "MCPWM Motor Support"
default n
menu "MCPWM Motor Configuration"
depends on ESP_MCPWM_MOTOR
config ESP_MCPWM_MOTOR_BDC
bool "Brushed DC Motor Control"
depends on ESP_MCPWM
depends on ESP_MCPWM_MOTOR
select MOTOR
select MOTOR_UPPER
select MOTOR_UPPER_HAVE_SPEED
default n
---help---
Enables the use of the MCPWM submodule for control of brushed DC
motor.
if ESP_MCPWM_MOTOR_BDC
config ESP_MCPWM_MOTOR_CH0
bool "Motor Control Channel 0"
default n
---help---
Enables motor control on channel 0.
if ESP_MCPWM_MOTOR_CH0
config ESP_MCPWM_MOTOR_CH0_PWMA_GPIO
int "Output Pin PWM_A"
default 20 if ESPRESSIF_ESP32C6
default 10 if ESPRESSIF_ESP32H2
---help---
Output pin assigned to channel 0 PWM output PWM_A.
config ESP_MCPWM_MOTOR_CH0_PWMB_GPIO
int "Output Pin PWM_B"
default 21 if ESPRESSIF_ESP32C6
default 11 if ESPRESSIF_ESP32H2
---help---
Output pin assigned to channel 0 PWM output PWM_B.
config ESP_MCPWM_MOTOR_CH0_PWM_FREQ
int "PWM output frequency for channel 0 [Hz]"
default 1000
---help---
Select PWM frequency for channel 0.
Minimum is 25 Hz and maximum is 3000 Hz.
config ESP_MCPMW_MOTOR_CH0_FAULT
bool "Enable fault for channel 0"
default n
---help---
Enables the use of a fault pin to quickly stop the motor when
a GPIO pin pulled high.
if ESP_MCPMW_MOTOR_CH0_FAULT
config ESP_MCPMW_MOTOR_CH0_FAULT_GPIO
int "GPIO Pin for fault detection"
default 9
---help---
Input pin assigned to channel 0 fault indicator.
endif # ESP_MCPMW_MOTOR_CH0_FAULT
endif # ESP_MCPWM_MOTOR_CH0
config ESP_MCPWM_MOTOR_CH1
bool "Motor Control Channel 1"
default n
---help---
Enables motor control on channel 1.
if ESP_MCPWM_MOTOR_CH1
config ESP_MCPWM_MOTOR_CH1_PWMA_GPIO
int "Output Pin CH1 PWM_A"
default 15
---help---
Output pin assigned to channel 1 PWM output PWM_A.
config ESP_MCPWM_MOTOR_CH1_PWMB_GPIO
int "Output Pin CH1 PWM_B"
default 16
---help---
Output pin assigned to channel 1 PWM output PWM_B.
endif # ESP_MCPWM_MOTOR_CH1
endif # ESP_MCPWM_MOTOR_BDC
endmenu # MCPWM Motor Settings
config ESP_MCPWM_CAPTURE
bool "MCPWM Capture Submodule"
depends on ESP_MCPWM
@@ -1372,6 +1468,15 @@ endif # ESP_MCPWM_CAPTURE_CH2
endif # ESP_MCPWM_CAPTURE
config ESP_MCPWM_TEST_LOOPBACK
bool "MCPWM loopback test mode"
depends on EXPERIMENTAL
default n
---help---
This enables a lower-half driver-specific loopback test
mode that attaches a capture device to the PWM output on
motor tests.
endmenu # MCPWM Configuration
menu "High Resolution Timer"
File diff suppressed because it is too large Load Diff
@@ -56,6 +56,31 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp_motor_bdc_initialize
*
* Description:
* This function initializes the MCPWM peripheral and configures the
* motor control driver.
*
* Input Parameters:
* channel - Channel to be initialized (only 0 available for now).
* frequency - PWM output frequency in Hertz.
* pwm_a_pin - GPIO pin number for PWM0_A output.
* pwm_b_pin - GPIO pin number for PWM0_B output.
* fault_pin - GPIO pin number for fault signal input.
*
* Returned Value:
* On success, this function returns a valid pointer to the Capture device
* structure. If the initialization fails, it returns NULL.
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_MOTOR_BDC
struct motor_lowerhalf_s *esp_motor_bdc_initialize(int channel,
uint32_t frequency, int pwm_a_pin, int pwm_b_pin, int fault_pin);
#endif
/****************************************************************************
* Name: esp_mcpwm_capture_initialize
*
@@ -43,7 +43,24 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_CAPTURE
/****************************************************************************
* Name: board_motor_initialize
*
* Description:
* Initialize MCPWM peripheral for motor control and register the motor
* driver.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_MOTOR
int board_motor_initialize(void);
#endif
/****************************************************************************
* Name: board_capture_initialize
@@ -59,9 +76,10 @@ extern "C"
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_CAPTURE
int board_capture_initialize(void);
#endif
#endif /* CONFIG_ESP_MCPWM_CAPTURE */
#undef EXTERN
#ifdef __cplusplus
}
@@ -29,7 +29,12 @@
#include <debug.h>
#include <nuttx/board.h>
#ifdef CONFIG_MOTOR
#include <nuttx/motor/motor.h>
#endif
#ifdef CONFIG_CAPTURE
#include <nuttx/timers/capture.h>
#endif
#include <arch/board/board.h>
@@ -39,10 +44,61 @@
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_ESP_MCPMW_MOTOR_CH0_FAULT
# define MCPWM_FAULT_GPIO CONFIG_ESP_MCPMW_MOTOR_CH0_FAULT_GPIO
#else
# define MCPWM_FAULT_GPIO 0
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_motor_initialize
*
* Description:
* Initialize MCPWM peripheral for motor control and register the motor
* driver.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_MOTOR
int board_motor_initialize(void)
{
int ret;
struct motor_lowerhalf_s *motor;
#ifdef CONFIG_ESP_MCPWM_MOTOR_CH0
motor = esp_motor_bdc_initialize(0,
CONFIG_ESP_MCPWM_MOTOR_CH0_PWM_FREQ,
CONFIG_ESP_MCPWM_MOTOR_CH0_PWMA_GPIO,
CONFIG_ESP_MCPWM_MOTOR_CH0_PWMB_GPIO,
MCPWM_FAULT_GPIO);
if (motor == NULL)
{
syslog(LOG_ERR, "ERROR: Failed to start MCPWM BDC Motor: CH0\n");
return -ENODEV;
}
ret = motor_register("/dev/motor0", motor);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: motor_register failed: %d\n", ret);
return ret;
}
#endif
return OK;
}
#endif
/****************************************************************************
* Name: board_capture_initialize
*
@@ -57,6 +113,7 @@
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_CAPTURE
int board_capture_initialize(void)
{
int ret;
@@ -112,3 +169,4 @@ int board_capture_initialize(void)
return OK;
}
#endif
@@ -0,0 +1,52 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32c6-devkitc"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32C6_DEVKITC=y
CONFIG_ARCH_CHIP="esp32c6"
CONFIG_ARCH_CHIP_ESP32C6=y
CONFIG_ARCH_CHIP_ESP32C6WROOM1=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_ESP32C6=y
CONFIG_ESP_MCPWM=y
CONFIG_ESP_MCPWM_MOTOR=y
CONFIG_ESP_MCPWM_MOTOR_BDC=y
CONFIG_ESP_MCPWM_MOTOR_CH0=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y
@@ -348,6 +348,14 @@ int esp_bringup(void)
}
#endif
#ifdef CONFIG_ESP_MCPWM_MOTOR
ret = board_motor_initialize();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: board_motor_initialize failed: %d\n", ret);
}
#endif
/* If we got here then perhaps not all initialization was successful, but
* at least enough succeeded to bring-up NSH with perhaps reduced
* capabilities.
@@ -43,7 +43,24 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_CAPTURE
/****************************************************************************
* Name: board_motor_initialize
*
* Description:
* Initialize MCPWM peripheral for motor control and register the motor
* driver.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_MOTOR
int board_motor_initialize(void);
#endif
/****************************************************************************
* Name: board_capture_initialize
@@ -59,9 +76,10 @@ extern "C"
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_CAPTURE
int board_capture_initialize(void);
#endif
#endif /* CONFIG_ESP_MCPWM_CAPTURE */
#undef EXTERN
#ifdef __cplusplus
}
@@ -29,7 +29,12 @@
#include <debug.h>
#include <nuttx/board.h>
#ifdef CONFIG_MOTOR
#include <nuttx/motor/motor.h>
#endif
#ifdef CONFIG_CAPTURE
#include <nuttx/timers/capture.h>
#endif
#include <arch/board/board.h>
@@ -39,10 +44,61 @@
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_ESP_MCPMW_MOTOR_CH0_FAULT
# define MCPWM_FAULT_GPIO CONFIG_ESP_MCPMW_MOTOR_CH0_FAULT_GPIO
#else
# define MCPWM_FAULT_GPIO 0
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_motor_initialize
*
* Description:
* Initialize MCPWM peripheral for motor control and register the motor
* driver.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_MOTOR
int board_motor_initialize(void)
{
int ret;
struct motor_lowerhalf_s *motor;
#ifdef CONFIG_ESP_MCPWM_MOTOR_CH0
motor = esp_motor_bdc_initialize(0,
CONFIG_ESP_MCPWM_MOTOR_CH0_PWM_FREQ,
CONFIG_ESP_MCPWM_MOTOR_CH0_PWMA_GPIO,
CONFIG_ESP_MCPWM_MOTOR_CH0_PWMB_GPIO,
MCPWM_FAULT_GPIO);
if (motor == NULL)
{
syslog(LOG_ERR, "ERROR: Failed to start MCPWM BDC Motor: CH0\n");
return -ENODEV;
}
ret = motor_register("/dev/motor0", motor);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: motor_register failed: %d\n", ret);
return ret;
}
#endif
return OK;
}
#endif
/****************************************************************************
* Name: board_capture_initialize
*
@@ -57,6 +113,7 @@
*
****************************************************************************/
#ifdef CONFIG_ESP_MCPWM_CAPTURE
int board_capture_initialize(void)
{
int ret;
@@ -112,3 +169,4 @@ int board_capture_initialize(void)
return OK;
}
#endif
@@ -0,0 +1,51 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32h2-devkit"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32H2_DEVKIT=y
CONFIG_ARCH_CHIP="esp32h2"
CONFIG_ARCH_CHIP_ESP32H2=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_ESP32H2=y
CONFIG_ESP_MCPWM=y
CONFIG_ESP_MCPWM_MOTOR=y
CONFIG_ESP_MCPWM_MOTOR_BDC=y
CONFIG_ESP_MCPWM_MOTOR_CH0=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y
@@ -315,6 +315,14 @@ int esp_bringup(void)
}
#endif
#ifdef CONFIG_ESP_MCPWM_MOTOR
ret = board_motor_initialize();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: board_motor_initialize failed: %d\n", ret);
}
#endif
/* If we got here then perhaps not all initialization was successful, but
* at least enough succeeded to bring-up NSH with perhaps reduced
* capabilities.