diff --git a/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst b/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst index 785e6cbf23..e255110fbc 100644 --- a/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst +++ b/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst @@ -442,3 +442,26 @@ NSH commands:: 1: channel: 4 value: 2682 Currently there is a bug that causes the application to always read the same value for channel 0 and 4. If you want to read the value from channel 2, you will need to enable the config "ADC1 Scan Mode". + +dac +--- + +Configures the NuttShell (nsh) over USB Serial (check usbserial configuration) and enables PWM 3 on channel 1. +Use pwm command on NSH to change dutty cycle, frequency and duration, use dac_out_2 to measure the output voltage. +NSH commands:: + + nsh> pwm -h + Usage: pwm [OPTIONS] + + Arguments are "sticky". For example, once the PWM frequency is + specified, that frequency will be re-used until it is changed. + + "sticky" OPTIONS include: + [-p devpath] selects the PWM device. Default: /dev/pwm0 Current: NONE + [-f frequency] selects the pulse frequency. Default: 100 Hz Current: 100 Hz + [-d duty] selects the pulse duty as a percentage. Default: 50 % Current: 50 % + [-t duration] is the duration of the pulse train in seconds. Default: 5 Current: 5 + [-h] shows this message and exits + nsh> pwm -d 50 -t 3 + pwm_main: starting output with frequency: 50 duty: 00007fff + pwm_main: stopping output diff --git a/boards/arm/stm32/stm32f401rc-rs485/configs/dac/defconfig b/boards/arm/stm32/stm32f401rc-rs485/configs/dac/defconfig new file mode 100644 index 0000000000..bff4a70526 --- /dev/null +++ b/boards/arm/stm32/stm32f401rc-rs485/configs/dac/defconfig @@ -0,0 +1,67 @@ +# +# 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_NSH_DISABLE_IFCONFIG is not set +# CONFIG_NSH_DISABLE_PS is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32f401rc-rs485" +CONFIG_ARCH_BOARD_STM32F401RC_RS485=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F401RC=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_IRQBUTTONS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_USBDEVCTRL=y +CONFIG_BOARD_LOOPSPERMSEC=8499 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_CONSOLE=y +CONFIG_EXAMPLES_BUTTONS=y +CONFIG_EXAMPLES_BUTTONS_NAME0="SW3" +CONFIG_EXAMPLES_BUTTONS_NAME1="SW4" +CONFIG_EXAMPLES_BUTTONS_NAME2="SW5" +CONFIG_EXAMPLES_BUTTONS_NAMES=y +CONFIG_EXAMPLES_BUTTONS_QTD=3 +CONFIG_EXAMPLES_PWM=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INPUT=y +CONFIG_INPUT_BUTTONS=y +CONFIG_INPUT_BUTTONS_LOWER=y +CONFIG_INTELHEX_BINARY=y +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_PWM=y +CONFIG_RAM_SIZE=98304 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SPI=y +CONFIG_START_DAY=5 +CONFIG_START_MONTH=5 +CONFIG_START_YEAR=2014 +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_OTGFS=y +CONFIG_STM32_PWR=y +CONFIG_STM32_TIM3=y +CONFIG_STM32_TIM3_CH1OUT=y +CONFIG_STM32_TIM3_PWM=y +CONFIG_STM32_USART6=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_USBDEV=y diff --git a/boards/arm/stm32/stm32f401rc-rs485/include/board.h b/boards/arm/stm32/stm32f401rc-rs485/include/board.h index 016ce5a840..17e9112e5a 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/include/board.h +++ b/boards/arm/stm32/stm32f401rc-rs485/include/board.h @@ -282,6 +282,14 @@ extern "C" #define GPIO_USART6_RX GPIO_USART6_RX_1 /* PC7 */ #define GPIO_USART6_TX GPIO_USART6_TX_1 /* PC6 */ +/* PWM + * + * The STM32F401RC-RS485 has no real on-board PWM devices, but the board + * can be configured to output a pulse train using TIM3 CH1 on PA6. + */ + +#define GPIO_TIM3_CH1OUT GPIO_TIM3_CH1OUT_1 + /* I2C * * The optional _GPIO configurations allow the I2C driver to manually diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt b/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt index 0c55188cb6..3baadaff60 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt +++ b/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt @@ -52,6 +52,10 @@ if(CONFIG_STM32_CONFIG_I2C_EE_24XXEEPROM) list(APPEND SRCS stm32_at24.c) endif() +if(CONFIG_STM32_PWM) + list(APPEND SRCS stm32_pwm.c) +endif() + target_sources(board PRIVATE ${SRCS}) if(CONFIG_ARCH_CHIP_STM32F401RC) diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs b/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs index 02b7c3f4f0..5eff56f7be 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs +++ b/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs @@ -55,6 +55,10 @@ ifeq ($(CONFIG_I2C_EE_24XX),y) CSRCS += stm32_at24.c endif +ifeq ($(CONFIG_STM32_PWM),y) +CSRCS += stm32_pwm.c +endif + DEPPATH += --dep-path board VPATH += :board CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c index 98c1be0e9e..e0a486a252 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c @@ -179,6 +179,16 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_PWM + /* Initialize PWM and register the PWM device */ + + ret = stm32_pwm_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_pwm_setup() failed: %d\n", ret); + } +#endif + #ifdef HAVE_SDIO /* Initialize the SDIO block driver */ diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_pwm.c b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_pwm.c new file mode 100644 index 0000000000..80eacc9964 --- /dev/null +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_pwm.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * boards/arm/stm32/stm32f401rc-rs485/src/stm32_pwm.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 + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" +#include "stm32_pwm.h" +#include "stm32f401rc-rs485.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* PWM + * + * The STM32F401RC-RS485 has no real on-board PWM devices, but the board can + * be configured to output a pulse train using TIM3 CH1. + * + */ + +#define HAVE_PWM 1 + +#ifndef CONFIG_PWM +# undef HAVE_PWM +#endif + +#ifndef CONFIG_STM32_TIM3 +# undef HAVE_PWM +#endif + +#ifndef CONFIG_STM32_TIM3_PWM +# undef HAVE_PWM +#endif + +#if !defined(CONFIG_STM32_TIM3_CHANNEL) || CONFIG_STM32_TIM3_CHANNEL != STM32F401RCRS485_PWMCHANNEL +# undef HAVE_PWM +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +int stm32_pwm_setup(void) +{ +#ifdef HAVE_PWM + static bool initialized = false; + struct pwm_lowerhalf_s *pwm; + int ret; + + /* Have we already initialized? */ + + if (!initialized) + { + /* Call stm32_pwminitialize() to get an instance of the PWM interface */ + + pwm = stm32_pwminitialize(STM32F401RCRS485_PWMTIMER); + if (!pwm) + { + aerr("ERROR: Failed to get the STM32 PWM lower half\n"); + return -ENODEV; + } + + /* Register the PWM driver at "/dev/pwm0" */ + + ret = pwm_register("/dev/pwm0", pwm); + if (ret < 0) + { + aerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +#else + return -ENODEV; +#endif +} diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h b/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h index 3cfd28a35c..691fb56cec 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h @@ -113,6 +113,15 @@ GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN5) #endif +/* PWM + * + * The STM32F401RC-RS485 has no real on-board PWM devices, but the board can + * be configured to output a pulse train using TIM3 CH1 on PA6. + */ + +#define STM32F401RCRS485_PWMTIMER 3 +#define STM32F401RCRS485_PWMCHANNEL 1 + /**************************************************************************** * Public Data ****************************************************************************/ @@ -185,6 +194,21 @@ void stm32_usbinitialize(void); int stm32_adc_setup(void); #endif +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + * Return Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_PWM +int stm32_pwm_setup(void); +#endif + /**************************************************************************** * Name: stm32_sdio_initialize *