Add QE support to STM32F4Discovery; add a test of the quadrature encoder driver

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4395 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo
2012-02-15 17:51:30 +00:00
parent a1590c1424
commit 3625222c6c
24 changed files with 1107 additions and 181 deletions

View File

@@ -188,3 +188,5 @@
dump the system log if CONFIG_SYSLOG is selected. dump the system log if CONFIG_SYSLOG is selected.
6.16 2012-xx-xx Gregory Nutt <gnutt@nuttx.org> 6.16 2012-xx-xx Gregory Nutt <gnutt@nuttx.org>
* apps/examples/qencoder: Add a quadrature driver test.

View File

@@ -39,9 +39,9 @@
SUBDIRS = adc buttons can composite dhcpd ftpc ftpd hello helloxx hidkbd \ SUBDIRS = adc buttons can composite dhcpd ftpc ftpd hello helloxx hidkbd \
igmp lcdrw mm mount nettest nsh null nx nxffs nxflat nxhello nximage \ igmp lcdrw mm mount nettest nsh null nx nxffs nxflat nxhello nximage \
nxlines nxtext ostest pashello pipe poll pwm rgmp romfs sendmail \ nxlines nxtext ostest pashello pipe poll pwm qencoder rgmp romfs \
serloop telnetd thttpd tiff touchscreen udp uip usbserial \ serloop telnetd thttpd tiff touchscreen udp uip usbserial \
usbstorage usbterm wget wlan sendmail usbstorage usbterm wget wlan
# Sub-directories that might need context setup. Directories may need # Sub-directories that might need context setup. Directories may need
# context setup for a variety of reasons, but the most common is because # context setup for a variety of reasons, but the most common is because
@@ -56,7 +56,7 @@ SUBDIRS = adc buttons can composite dhcpd ftpc ftpd hello helloxx hidkbd \
CNTXTDIRS = pwm CNTXTDIRS = pwm
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
CNTXTDIRS += adc can composite ftpd dhcpd nettest telnetd CNTXTDIRS += adc can composite ftpd dhcpd nettest qencoder telnetd
endif endif
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y) ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)

View File

@@ -906,6 +906,33 @@ examples/pwm
only available if CONFIG_PWM_PULSECOUNT is defined. Default: 0 (i.e., use only available if CONFIG_PWM_PULSECOUNT is defined. Default: 0 (i.e., use
the duration, not the count). the duration, not the count).
examples/qencoder
^^^^^^^^^^^^^^^^^
This example is a simple test of a Quadrature Encoder driver. It simply reads
positional data from the encoder and prints it.,
This test depends on these specific QE/NSH configurations settings (your
specific PWM settings might require additional settings).
CONFIG_QENCODER - Enables quadrature encoder support (upper-half driver).
CONFIG_NSH_BUILTIN_APPS - Build the QE test as an NSH built-in function.
Default: Built as a standalone progrem.
Additional configuration options will mostly likely be required for the board-
specific lower-half driver. See the README.txt file in your board configuration
directory.
Specific configuration options for this example include:
CONFIG_EXAMPLES_QENCODER_DEVPATH - The path to the QE device. Default:
/dev/qe0
CONFIG_EXAMPLES_QENCODER_NSAMPLES - If CONFIG_NSH_BUILTIN_APPS
is defined, then the number of samples is provided on the command line
and this value is ignored. Otherwise, this number of samples is
collected and the program terminates. Default: Samples are collected
indefinitely.
examples/rgmp examples/rgmp
^^^^^^^^^^^^^ ^^^^^^^^^^^^^

View File

@@ -0,0 +1,105 @@
############################################################################
# apps/examples/qe/Makefile
#
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
# NuttX NX Graphics Example.
ASRCS =
CSRCS = qe_main.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
OBJS = $(AOBJS) $(COBJS)
ifeq ($(WINTOOL),y)
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
else
BIN = "$(APPDIR)/libapps$(LIBEXT)"
endif
ROOTDEPPATH = --dep-path .
# Quadrature Encoder built-in application info
APPNAME = qe
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
# Common build
VPATH =
all: .built
.PHONY: context clean depend distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(COBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
.built: $(OBJS)
@( for obj in $(OBJS) ; do \
$(call ARCHIVE, $(BIN), $${obj}); \
done ; )
@touch .built
.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
@touch $@
depend: .depend
clean:
@rm -f *.o *~ .*.swp .built
$(call CLEAN)
distclean: clean
@rm -f Make.dep .depend
-include Make.dep

123
apps/examples/qencoder/qe.h Normal file
View File

@@ -0,0 +1,123 @@
/****************************************************************************
* examples/examples/qe/qe.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __APPS_EXAMPLES_QENCODER_QE_H
#define __APPS_EXAMPLES_QENCODER_QE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* CONFIG_NSH_BUILTIN_APPS - Build the QE test as an NSH built-in function.
* Default: Built as a standalone problem
* CONFIG_EXAMPLES_QENCODER_DEVPATH - The path to the QE device. Default:
* /dev/qe0
* CONFIG_EXAMPLES_QENCODER_NSAMPLES - If CONFIG_NSH_BUILTIN_APPS
* is defined, then the number of samples is provided on the command line
* and this value is ignored. Otherwise, this number of samples is
* collected and the program terminates. Default: Samples are collected
* indefinitely.
*/
#ifndef CONFIG_QENCODER
# error "QE device support is not enabled (CONFIG_QENCODER)"
#endif
#ifndef CONFIG_EXAMPLES_QENCODER_DEVPATH
# define CONFIG_EXAMPLES_QENCODER_DEVPATH "/dev/qe0"
#endif
/* Debug ********************************************************************/
#ifdef CONFIG_CPP_HAVE_VARARGS
# ifdef CONFIG_DEBUG
# define message(...) lib_rawprintf(__VA_ARGS__)
# define msgflush()
# else
# define message(...) printf(__VA_ARGS__)
# define msgflush() fflush(stdout)
# endif
#else
# ifdef CONFIG_DEBUG
# define message lib_rawprintf
# define msgflush()
# else
# define message printf
# define msgflush() fflush(stdout)
# endif
#endif
/****************************************************************************
* Public Types
****************************************************************************/
#ifdef CONFIG_NSH_BUILTIN_APPS
struct qe_example_s
{
bool reset;
int nloops;
};
#endif
/****************************************************************************
* Public Variables
****************************************************************************/
#ifdef CONFIG_NSH_BUILTIN_APPS
extern struct qe_example_s g_qeexample;
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: qe_devinit()
*
* Description:
* Perform architecuture-specific initialization of the QE hardware. This
* interface must be provided by all configurations using apps/examples/qe
*
****************************************************************************/
int qe_devinit(void);
#endif /* __APPS_EXAMPLES_QENCODER_QE_H */

View File

@@ -0,0 +1,310 @@
/****************************************************************************
* examples/qe/qe_main.c
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/sensors/qencoder.h>
#include "qe.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_NSH_BUILTIN_APPS
# define MAIN_NAME qe_main
# define MAIN_STRING "qe_main: "
#else
# define MAIN_NAME user_start
# define MAIN_STRING "user_start: "
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef CONFIG_NSH_BUILTIN_APPS
struct qe_example_s g_qeexample;
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: qe_help
****************************************************************************/
#ifdef CONFIG_NSH_BUILTIN_APPS
static void qe_help(void)
{
message("\nUsage: qe [OPTIONS]\n\n");
message("OPTIONS include:\n");
message(" [-n samples] number of samples\n");
message(" [-r] reset the count\n");
message(" [-h] shows this message and exits\n\n");
}
#endif
/****************************************************************************
* Name: arg_string
****************************************************************************/
#ifdef CONFIG_NSH_BUILTIN_APPS
int arg_string(FAR char **arg, FAR char **value)
{
FAR char *ptr = *arg;
if (ptr[2] == '\0')
{
*value = arg[1];
return 2;
}
else
{
*value = &ptr[2];
return 1;
}
}
#endif
/****************************************************************************
* Name: arg_decimal
****************************************************************************/
#ifdef CONFIG_NSH_BUILTIN_APPS
int arg_decimal(FAR char **arg, FAR long *value)
{
FAR char *string;
int ret;
ret = arg_string(arg, &string);
*value = strtol(string, NULL, 10);
return ret;
}
#endif
/****************************************************************************
* Name: parse_args
****************************************************************************/
#ifdef CONFIG_NSH_BUILTIN_APPS
void parse_args(int argc, FAR char **argv)
{
FAR char *ptr;
long value;
int index;
int nargs;
g_qeexample.reset = false;
g_qeexample.nloops = 1;
for (index = 1; index < argc; )
{
ptr = argv[index];
if (ptr[0] != '-')
{
message("Invalid options format: %s\n", ptr);
exit(0);
}
switch (ptr[1])
{
case 'n':
nargs = arg_decimal(&argv[index], &value);
if (value < 0 || value > INT_MAX)
{
message("Sample count out of range: %ld\n", value);
exit(1);
}
g_qeexample.nloops = (int)value;
index += nargs;
break;
case 'r':
g_qeexample.reset = true;
index++;
break;
case 'h':
qe_help();
exit(EXIT_SUCCESS);
default:
message("Unsupported option: %s\n", ptr);
qe_help();
exit(EXIT_FAILURE);
}
}
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: user_start/qe_main
****************************************************************************/
int MAIN_NAME(int argc, char *argv[])
{
int32_t position;
int fd;
int exitval = EXIT_SUCCESS;
int ret;
#if defined(CONFIG_NSH_BUILTIN_APPS) || defined(CONFIG_EXAMPLES_QENCODER_NSAMPLES)
int nloops;
#endif
/* Parse command line arguments */
#ifdef CONFIG_NSH_BUILTIN_APPS
parse_args(argc, argv);
#endif
/* Initialization of the encoder hardware is performed by logic external to
* this test.
*/
message(MAIN_STRING "Initializing external encoder\n");
ret = qe_devinit();
if (ret != OK)
{
message(MAIN_STRING "qe_devinit failed: %d\n", ret);
exitval = EXIT_FAILURE;
goto errout;
}
/* Open the encoder device for reading */
message(MAIN_STRING "Hardware initialized. Opening the encoder device\n");
fd = open(CONFIG_EXAMPLES_QENCODER_DEVPATH, O_RDONLY);
if (fd < 0)
{
message(MAIN_STRING "open %s failed: %d\n",
CONFIG_EXAMPLES_QENCODER_DEVPATH, errno);
exitval = EXIT_FAILURE;
goto errout_with_dev;
}
/* Reset the count if so requested */
if (g_qeexample.reset)
{
message(MAIN_STRING "Resetting the count...\n");
ret = ioctl(fd, QEIOC_RESET, 0);
if (ret < 0)
{
message(MAIN_STRING "ioctl(QEIOC_RESET) failed: %d\n", errno);
exitval = EXIT_FAILURE;
goto errout_with_dev;
}
}
/* Now loop the appropriate number of times, displaying the collected
* encoder samples.
*/
#if defined(CONFIG_NSH_BUILTIN_APPS)
message(MAIN_STRING "Number of samples: %d\n", g_qeexample.nloops);
for (nloops = 0; nloops < g_qeexample.nloops; nloops++)
#elif defined(CONFIG_EXAMPLES_QENCODER_NSAMPLES)
message(MAIN_STRING "Number of samples: %d\n", CONFIG_EXAMPLES_QENCODER_NSAMPLES);
for (nloops = 0; nloops < CONFIG_EXAMPLES_QENCODER_NSAMPLES; nloops++)
#else
for (;;)
#endif
{
/* Flush any output before the loop entered or from the previous pass
* through the loop.
*/
msgflush();
/* Get the positions data using the ioctl */
ret = ioctl(fd, QEIOC_POSITION, (unsigned long)((uintptr_t)&position));
if (ret < 0)
{
message(MAIN_STRING "ioctl(QEIOC_POSITION) failed: %d\n", errno);
exitval = EXIT_FAILURE;
goto errout_with_dev;
}
/* Print the sample data on successful return */
else
{
message(MAIN_STRING " %d\n", position);
}
}
errout_with_dev:
close(fd);
errout:
message("Terminating!\n");
msgflush();
return exitval;
}

View File

@@ -455,122 +455,122 @@
#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7) #define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7)
#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13) #define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13)
#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN8) #define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN8)
#define GPIO_TIM1_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN8) #define GPIO_TIM1_CH1IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN8)
#define GPIO_TIM1_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN9) #define GPIO_TIM1_CH1IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN9)
#define GPIO_TIM1_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) #define GPIO_TIM1_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8)
#define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9) #define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9)
#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN0) #define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN0)
#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN14) #define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN14)
#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN10) #define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN10)
#define GPIO_TIM1_CH2IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN9) #define GPIO_TIM1_CH2IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN9)
#define GPIO_TIM1_CH2IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN11) #define GPIO_TIM1_CH2IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN11)
#define GPIO_TIM1_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) #define GPIO_TIM1_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9)
#define GPIO_TIM1_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11) #define GPIO_TIM1_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11)
#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN1) #define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN1)
#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN15) #define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN15)
#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN12) #define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN12)
#define GPIO_TIM1_CH3IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN10) #define GPIO_TIM1_CH3IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN10)
#define GPIO_TIM1_CH3IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN13) #define GPIO_TIM1_CH3IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN13)
#define GPIO_TIM1_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) #define GPIO_TIM1_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10)
#define GPIO_TIM1_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13) #define GPIO_TIM1_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13)
#define GPIO_TIM1_CH4IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN11) #define GPIO_TIM1_CH4IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN11)
#define GPIO_TIM1_CH4IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN14) #define GPIO_TIM1_CH4IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN14)
#define GPIO_TIM1_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) #define GPIO_TIM1_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11)
#define GPIO_TIM1_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14) #define GPIO_TIM1_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14)
#define GPIO_TIM1_ETR_1 (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN12) #define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN12)
#define GPIO_TIM1_ETR_2 (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN7) #define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN7)
#define GPIO_TIM2_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN0) #define GPIO_TIM2_CH1IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN0)
#define GPIO_TIM2_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN15) #define GPIO_TIM2_CH1IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN15)
#define GPIO_TIM2_CH1IN_3 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN5) #define GPIO_TIM2_CH1IN_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN5)
#define GPIO_TIM2_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) #define GPIO_TIM2_CH1OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0)
#define GPIO_TIM2_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15) #define GPIO_TIM2_CH1OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15)
#define GPIO_TIM2_CH1OUT_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) #define GPIO_TIM2_CH1OUT_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5)
#define GPIO_TIM2_CH2IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN1) #define GPIO_TIM2_CH2IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN1)
#define GPIO_TIM2_CH2IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN3) #define GPIO_TIM2_CH2IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN3)
#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) #define GPIO_TIM2_CH2OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1)
#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) #define GPIO_TIM2_CH2OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3)
#define GPIO_TIM2_CH3IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM2_CH3IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2)
#define GPIO_TIM2_CH3IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN10) #define GPIO_TIM2_CH3IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN10)
#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM2_CH3OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)
#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) #define GPIO_TIM2_CH3OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10)
#define GPIO_TIM2_CH4IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM2_CH4IN_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3)
#define GPIO_TIM2_CH4IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN11) #define GPIO_TIM2_CH4IN_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN11)
#define GPIO_TIM2_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM2_CH4OUT_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)
#define GPIO_TIM2_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) #define GPIO_TIM2_CH4OUT_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11)
#define GPIO_TIM2_ETR_1 (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) #define GPIO_TIM2_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0)
#define GPIO_TIM2_ETR_2 (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) #define GPIO_TIM2_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15)
#define GPIO_TIM2_ETR_3 (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) #define GPIO_TIM2_ETR_3 (GPIO_ALT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5)
#define GPIO_TIM3_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN6) #define GPIO_TIM3_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN6)
#define GPIO_TIM3_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN4) #define GPIO_TIM3_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN4)
#define GPIO_TIM3_CH1IN_3 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN6) #define GPIO_TIM3_CH1IN_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN6)
#define GPIO_TIM3_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) #define GPIO_TIM3_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6)
#define GPIO_TIM3_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) #define GPIO_TIM3_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4)
#define GPIO_TIM3_CH1OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) #define GPIO_TIM3_CH1OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6)
#define GPIO_TIM3_CH2IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN7) #define GPIO_TIM3_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN7)
#define GPIO_TIM3_CH2IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN5) #define GPIO_TIM3_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN5)
#define GPIO_TIM3_CH2IN_3 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN7) #define GPIO_TIM3_CH2IN_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN7)
#define GPIO_TIM3_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) #define GPIO_TIM3_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7)
#define GPIO_TIM3_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) #define GPIO_TIM3_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5)
#define GPIO_TIM3_CH2OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) #define GPIO_TIM3_CH2OUT_3 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7)
#define GPIO_TIM3_CH3IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN0) #define GPIO_TIM3_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN0)
#define GPIO_TIM3_CH3IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN8) #define GPIO_TIM3_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN8)
#define GPIO_TIM3_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) #define GPIO_TIM3_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0)
#define GPIO_TIM3_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) #define GPIO_TIM3_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8)
#define GPIO_TIM3_CH4IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN1) #define GPIO_TIM3_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN1)
#define GPIO_TIM3_CH4IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN9) #define GPIO_TIM3_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN9)
#define GPIO_TIM3_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) #define GPIO_TIM3_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1)
#define GPIO_TIM3_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) #define GPIO_TIM3_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9)
#define GPIO_TIM3_ETR (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2) #define GPIO_TIM3_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2)
#define GPIO_TIM4_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN6) #define GPIO_TIM4_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN6)
#define GPIO_TIM4_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN12) #define GPIO_TIM4_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN12)
#define GPIO_TIM4_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) #define GPIO_TIM4_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6)
#define GPIO_TIM4_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) #define GPIO_TIM4_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12)
#define GPIO_TIM4_CH2IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN7) #define GPIO_TIM4_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN7)
#define GPIO_TIM4_CH2IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN13) #define GPIO_TIM4_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN13)
#define GPIO_TIM4_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) #define GPIO_TIM4_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7)
#define GPIO_TIM4_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) #define GPIO_TIM4_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13)
#define GPIO_TIM4_CH3IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN8) #define GPIO_TIM4_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN8)
#define GPIO_TIM4_CH3IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN14) #define GPIO_TIM4_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN14)
#define GPIO_TIM4_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) #define GPIO_TIM4_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8)
#define GPIO_TIM4_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14) #define GPIO_TIM4_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14)
#define GPIO_TIM4_CH4IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN9) #define GPIO_TIM4_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN9)
#define GPIO_TIM4_CH4IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN15) #define GPIO_TIM4_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN15)
#define GPIO_TIM4_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) #define GPIO_TIM4_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9)
#define GPIO_TIM4_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) #define GPIO_TIM4_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15)
#define GPIO_TIM4_ETR (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) #define GPIO_TIM4_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0)
#define GPIO_TIM5_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN0) #define GPIO_TIM5_CH1IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN0)
#define GPIO_TIM5_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN10) #define GPIO_TIM5_CH1IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN10)
#define GPIO_TIM5_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) #define GPIO_TIM5_CH1OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0)
#define GPIO_TIM5_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) #define GPIO_TIM5_CH1OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10)
#define GPIO_TIM5_CH2IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN1) #define GPIO_TIM5_CH2IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN1)
#define GPIO_TIM5_CH2IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN11) #define GPIO_TIM5_CH2IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN11)
#define GPIO_TIM5_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) #define GPIO_TIM5_CH2OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1)
#define GPIO_TIM5_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) #define GPIO_TIM5_CH2OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11)
#define GPIO_TIM5_CH3IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM5_CH3IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2)
#define GPIO_TIM5_CH3IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN12) #define GPIO_TIM5_CH3IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN12)
#define GPIO_TIM5_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM5_CH3OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)
#define GPIO_TIM5_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) #define GPIO_TIM5_CH3OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12)
#define GPIO_TIM5_CH4IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM5_CH4IN_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3)
#define GPIO_TIM5_CH4IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN0) #define GPIO_TIM5_CH4IN_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN0)
#define GPIO_TIM5_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM5_CH4OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)
#define GPIO_TIM5_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0) #define GPIO_TIM5_CH4OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0)
#define GPIO_TIM5_ETR (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10) #define GPIO_TIM5_ETR (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10)
#define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN6) #define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN6)
#define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN4) #define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN4)
#define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5) #define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5)
#define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7) #define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7)
#define GPIO_TIM8_CH1N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN13) #define GPIO_TIM8_CH1N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN13)
#define GPIO_TIM8_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN6) #define GPIO_TIM8_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN6)
#define GPIO_TIM8_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN5) #define GPIO_TIM8_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN5)
#define GPIO_TIM8_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) #define GPIO_TIM8_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6)
#define GPIO_TIM8_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5) #define GPIO_TIM8_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5)
#define GPIO_TIM8_CH2IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN7) #define GPIO_TIM8_CH2IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN7)
#define GPIO_TIM8_CH2IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN6) #define GPIO_TIM8_CH2IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN6)
#define GPIO_TIM8_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) #define GPIO_TIM8_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7)
#define GPIO_TIM8_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6) #define GPIO_TIM8_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6)
#define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0) #define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0)
@@ -579,52 +579,52 @@
#define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1) #define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1)
#define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN15) #define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN15)
#define GPIO_TIM8_CH3N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN15) #define GPIO_TIM8_CH3N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN15)
#define GPIO_TIM8_CH3IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN8) #define GPIO_TIM8_CH3IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN8)
#define GPIO_TIM8_CH3IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN7) #define GPIO_TIM8_CH3IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN7)
#define GPIO_TIM8_CH3OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) #define GPIO_TIM8_CH3OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8)
#define GPIO_TIM8_CH3OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7) #define GPIO_TIM8_CH3OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7)
#define GPIO_TIM8_CH4IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN9) #define GPIO_TIM8_CH4IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN9)
#define GPIO_TIM8_CH4IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN2) #define GPIO_TIM8_CH4IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN2)
#define GPIO_TIM8_CH4OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) #define GPIO_TIM8_CH4OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9)
#define GPIO_TIM8_CH4OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2) #define GPIO_TIM8_CH4OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2)
#define GPIO_TIM8_ETR_1 (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) #define GPIO_TIM8_ETR_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0)
#define GPIO_TIM8_ETR_2 (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN3) #define GPIO_TIM8_ETR_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN3)
#define GPIO_TIM9_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM9_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2)
#define GPIO_TIM9_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN5) #define GPIO_TIM9_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN5)
#define GPIO_TIM9_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) #define GPIO_TIM9_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)
#define GPIO_TIM9_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5) #define GPIO_TIM9_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5)
#define GPIO_TIM9_CH2IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM9_CH2IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3)
#define GPIO_TIM9_CH2IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN6) #define GPIO_TIM9_CH2IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN6)
#define GPIO_TIM9_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) #define GPIO_TIM9_CH2OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)
#define GPIO_TIM9_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6) #define GPIO_TIM9_CH2OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6)
#define GPIO_TIM10_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN8) #define GPIO_TIM10_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN8)
#define GPIO_TIM10_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN6) #define GPIO_TIM10_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN6)
#define GPIO_TIM10_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) #define GPIO_TIM10_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8)
#define GPIO_TIM10_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) #define GPIO_TIM10_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6)
#define GPIO_TIM11_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN9) #define GPIO_TIM11_CH1IN_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN9)
#define GPIO_TIM11_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN7) #define GPIO_TIM11_CH1IN_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN7)
#define GPIO_TIM11_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) #define GPIO_TIM11_CH1OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9)
#define GPIO_TIM11_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) #define GPIO_TIM11_CH1OUT_2 (GPIO_ALT|GPIO_AF3|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7)
#define GPIO_TIM12_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN6) #define GPIO_TIM12_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN6)
#define GPIO_TIM12_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN14) #define GPIO_TIM12_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN14)
#define GPIO_TIM12_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) #define GPIO_TIM12_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6)
#define GPIO_TIM12_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) #define GPIO_TIM12_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14)
#define GPIO_TIM12_CH2IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN15) #define GPIO_TIM12_CH2IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN15)
#define GPIO_TIM12_CH2IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN9) #define GPIO_TIM12_CH2IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN9)
#define GPIO_TIM12_CH2OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN15) #define GPIO_TIM12_CH2OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN15)
#define GPIO_TIM12_CH2OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) #define GPIO_TIM12_CH2OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9)
#define GPIO_TIM13_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN6) #define GPIO_TIM13_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN6)
#define GPIO_TIM13_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN8) #define GPIO_TIM13_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN8)
#define GPIO_TIM13_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) #define GPIO_TIM13_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6)
#define GPIO_TIM13_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) #define GPIO_TIM13_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8)
#define GPIO_TIM14_CH1IN_1 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN7) #define GPIO_TIM14_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN7)
#define GPIO_TIM14_CH1IN_2 (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN9) #define GPIO_TIM14_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN9)
#define GPIO_TIM14_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) #define GPIO_TIM14_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7)
#define GPIO_TIM14_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) #define GPIO_TIM14_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9)

View File

@@ -65,7 +65,7 @@
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ************************************************************************************/
/* Debug ****************************************************************************/ /* Debug ****************************************************************************/
/* Non-standard debug that may be enabled just for testing QENCODER */ /* Non-standard debug that may be enabled just for testing the quadrature encoder */
#ifndef CONFIG_DEBUG #ifndef CONFIG_DEBUG
# undef CONFIG_DEBUG_QENCODER # undef CONFIG_DEBUG_QENCODER
@@ -647,17 +647,13 @@ static int stm32_setup(FAR struct qe_lowerhalf_s *lower)
stm32_configgpio(priv->config->ti1cfg); stm32_configgpio(priv->config->ti1cfg);
stm32_configgpio(priv->config->ti2cfg); stm32_configgpio(priv->config->ti2cfg);
/* Set the encoder Mode 3*/ /* Set the encoder Mode 3 */
#warning REVISIT #warning REVISIT
smcr = stm32_getreg16(priv, STM32_GTIM_SMCR_OFFSET); smcr = stm32_getreg16(priv, STM32_GTIM_SMCR_OFFSET);
smcr &= ~GTIM_SMCR_SMS_MASK; smcr &= ~GTIM_SMCR_SMS_MASK;
smcr |= GTIM_SMCR_ENCMD3; smcr |= GTIM_SMCR_ENCMD3;
stm32_putreg16(priv, STM32_GTIM_SMCR_OFFSET, smcr); stm32_putreg16(priv, STM32_GTIM_SMCR_OFFSET, smcr);
/* Write to TIM CCER */
stm32_putreg16(priv, STM32_GTIM_CCER_OFFSET, ccer);
/* TI1 Channel Configuration */ /* TI1 Channel Configuration */
/* Disable the Channel 1: Reset the CC1E Bit */ /* Disable the Channel 1: Reset the CC1E Bit */
@@ -988,11 +984,11 @@ static int stm32_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, unsigned long
* *
* Description: * Description:
* Initialize a quadrature encoder interface. This function must be called from * Initialize a quadrature encoder interface. This function must be called from
* board-specific logic after input pins have been configured. * board-specific logic.
* *
* Input Parameters: * Input Parameters:
* devpath - The full path to the driver to register. E.g., "/dev/qe0" * devpath - The full path to the driver to register. E.g., "/dev/qe0"
* tim - The timer number to used. time must be an element of {1,2,3,4,5,8} * tim - The timer number to used. 'tim' must be an element of {1,2,3,4,5,8}
* *
* Returned Values: * Returned Values:
* Zero on success; A negated errno value is returned on failure. * Zero on success; A negated errno value is returned on failure.
@@ -1007,8 +1003,9 @@ int stm32_qeinitialize(FAR const char *devpath, int tim)
/* Find the pre-allocated timer state structure corresponding to this timer */ /* Find the pre-allocated timer state structure corresponding to this timer */
priv = stm32_tim2lower(tim); priv = stm32_tim2lower(tim);
if (priv) if (!priv)
{ {
qedbg("TIM%d support not configured\n", tim);
return -ENXIO; return -ENXIO;
} }
@@ -1016,6 +1013,7 @@ int stm32_qeinitialize(FAR const char *devpath, int tim)
if (priv->inuse) if (priv->inuse)
{ {
qedbg("TIM%d is in-used\n", tim);
return -EBUSY; return -EBUSY;
} }
@@ -1024,6 +1022,7 @@ int stm32_qeinitialize(FAR const char *devpath, int tim)
ret = qe_register(devpath, (FAR struct qe_lowerhalf_s *)priv); ret = qe_register(devpath, (FAR struct qe_lowerhalf_s *)priv);
if (ret < 0) if (ret < 0)
{ {
qedbg("qe_register failed: %d\n", ret);
return ret; return ret;
} }

View File

@@ -96,11 +96,11 @@
* *
* Description: * Description:
* Initialize a quadrature encoder interface. This function must be called from * Initialize a quadrature encoder interface. This function must be called from
* board-specific logic after input pins have been configured. * board-specific logic..
* *
* Input Parameters: * Input Parameters:
* devpath - The full path to the driver to register. E.g., "/dev/qe0" * devpath - The full path to the driver to register. E.g., "/dev/qe0"
* tim - The timer number to used. time must be an element of {1,2,3,4,5,8} * tim - The timer number to used. 'tim' must be an element of {1,2,3,4,5,8}
* *
* Returned Values: * Returned Values:
* Zero on success; A negated errno value is returned on failure. * Zero on success; A negated errno value is returned on failure.

View File

@@ -11,9 +11,11 @@ Contents
- GNU Toolchain Options - GNU Toolchain Options
- IDEs - IDEs
- NuttX buildroot Toolchain - NuttX buildroot Toolchain
- stm32f4discovery-specific Configuration Options
- LEDs - LEDs
- PWM - PWM
- UARTs
- Timer Inputs/Outputs
- STM32F4Discovery-specific Configuration Options
- Configurations - Configurations
Development Environment Development Environment
@@ -139,7 +141,7 @@ NuttX buildroot Toolchain
1. You must have already configured Nuttx in <some-dir>/nuttx. 1. You must have already configured Nuttx in <some-dir>/nuttx.
cd tools cd tools
./configure.sh stm32f4discovery/<sub-dir> ./configure.sh STM32F4Discovery/<sub-dir>
2. Download the latest buildroot package into <some-dir> 2. Download the latest buildroot package into <some-dir>
@@ -165,10 +167,10 @@ NuttX buildroot Toolchain
LEDs LEDs
==== ====
The stm32f4discovery board has four LEDs; green, organge, red and blue on the The STM32F4Discovery board has four LEDs; green, organge, red and blue on the
board.. These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is board.. These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is
defined. In that case, the usage by the board port is defined in defined. In that case, the usage by the board port is defined in
include/board.h and src/up_leds.c. The LEDs are used to encode OS-related\ include/board.h and src/up_leds.c. The LEDs are used to encode OS-related
events as follows: events as follows:
SYMBOL Meaning LED1* LED2 LED3 LED4 SYMBOL Meaning LED1* LED2 LED3 LED4
@@ -194,12 +196,120 @@ events as follows:
PWM PWM
=== ===
The stm32f4discovery has no real on-board PWM devices, but the board can be The STM32F4Discovery has no real on-board PWM devices, but the board can be
configured to output a pulse train using TIM4 CH2 on PD3. This pin is configured to output a pulse train using TIM4 CH2 on PD3. This pin is
available next to the audio jack. available next to the audio jack.
stm32f4discovery-specific Configuration Options UART
============================================ ====
UART/USART PINS
---------------
USART1
CK PA8
CTS PA11*
RTS PA12*
RX PA10*, PB7
TX PA9*, PB6*
USART2
CK PA4*, PD7
CTS PA0*, PD3
RTS PA1, PD4*
RX PA3, PD6
TX PA2, PD5*
USART3
CK PB12, PC12*, PD10
CTS PB13, PD11
RTS PB14, PD12*
RX PB11, PC11, PD9
TX PB10*, PC10*, PD8
UART4
RX PA1, PC11
TX PA0*, PC10*
UART5
RX PD2
TX PC12*
USART6
CK PC8, PG7**
CTS PG13**, PG15**
RTS PG12**, PG8**
RX PC7*, PG9**
TX PC6, PG14**
* Indicates pins that have other on-board functins and should be used only
with care (See table 5 in the STM32F4Discovery User Guide). The rest are
free I/O pins.
** Port G pins are not supported by the MCU
Default USART/UART Configuration
--------------------------------
USART2 is enabled in all configurations (see */defconfig). RX and TX are
configured on pins PA3 and PA2, respectively (see include/board.h).
Timer Inputs/Outputs
====================
TIM1
CH1 PA8, PE9
CH2 PA9*, PE11
CH3 PA10*, PE13
CH4 PA11*, PE14
TIM2
CH1 PA0*, PA15, PA5*
CH2 PA1, PB3*
CH3 PA2, PB10*
CH4 PA3, PB11
TIM3
CH1 PA6*, PB4, PC6
CH2 PA7*, PB5, PC7*
CH3 PB0, PC8
CH4 PB1, PC9
TIM4
CH1 PB6*, PD12*
CH2 PB7, PD13*
CH3 PB8, PD14*
CH4 PB9*, PD15*
TIM5
CH1 PA0*, PH10**
CH2 PA1, PH11**
CH3 PA2, PH12**
CH4 PA3, PI0
TIM8
CH1 PC6, PI5
CH2 PC7*, PI6
CH3 PC8, PI7
CH4 PC9, PI2
TIM9
CH1 PA2, PE5
CH2 PA3, PE6
TIM10
CH1 PB8, PF6
TIM11
CH1 PB9*, PF7
TIM12
CH1 PH6**, PB14
CH2 PC15, PH9**
TIM13
CH1 PA6*, PF8
TIM14
CH1 PA7*, PF9
* Indicates pins that have other on-board functins and should be used only
with care (See table 5 in the STM32F4Discovery User Guide). The rest are
free I/O pins.
** Port H pins are not supported by the MCU
Quadrature Encode Timer Inputs
------------------------------
If enabled (by setting CONFIG_QENCODER=y), then quadrature encoder will
user TIM2 (see nsh/defconfig) and input pins PA15, and PA1 for CH1 and
CH2, respectively (see include board.h).
STM32F4Discovery-specific Configuration Options
===============================================
CONFIG_ARCH - Identifies the arch/ subdirectory. This should CONFIG_ARCH - Identifies the arch/ subdirectory. This should
be set to: be set to:
@@ -231,7 +341,7 @@ stm32f4discovery-specific Configuration Options
CONFIG_ARCH_BOARD - Identifies the configs subdirectory and CONFIG_ARCH_BOARD - Identifies the configs subdirectory and
hence, the board that supports the particular chip or SoC. hence, the board that supports the particular chip or SoC.
CONFIG_ARCH_BOARD=stm32f4discovery (for the stm32f4discovery development board) CONFIG_ARCH_BOARD=STM32F4Discovery (for the STM32F4Discovery development board)
CONFIG_ARCH_BOARD_name - For use in C code CONFIG_ARCH_BOARD_name - For use in C code
@@ -438,11 +548,11 @@ stm32f4discovery-specific Configuration Options
Configurations Configurations
============== ==============
Each stm32f4discovery configuration is maintained in a sudirectory and Each STM32F4Discovery configuration is maintained in a sudirectory and
can be selected as follow: can be selected as follow:
cd tools cd tools
./configure.sh stm32f4discovery/<subdir> ./configure.sh STM32F4Discovery/<subdir>
cd - cd -
. ./setenv.sh . ./setenv.sh
@@ -468,6 +578,7 @@ Where <subdir> is one of the following:
be manually enabled by selecting: be manually enabled by selecting:
CONFIG_PWM=y : Enable the generic PWM infrastructure CONFIG_PWM=y : Enable the generic PWM infrastructure
CONFIG_STM32_TIM4=y : Enable TIM4
CONFIG_STM32_TIM4_PWM=y : Use TIM4 to generate PWM output CONFIG_STM32_TIM4_PWM=y : Use TIM4 to generate PWM output
See also apps/examples/README.txt See also apps/examples/README.txt
@@ -476,3 +587,15 @@ Where <subdir> is one of the following:
CONFIG_DEBUG_PWM CONFIG_DEBUG_PWM
1. This example supports the Quadrature Encode test (apps/examples/qencoder)
but this must be manually enabled by selecting:
CONFIG_QENCODER=y : Enable the generic Quadrature Encoder infrastructure
CONFIG_STM32_TIM2=y : Enable TIM2
CONFIG_STM32_TIM2_QE=y : Use TIM2 as the quadrature encoder
See also apps/examples/README.txt
Special PWM-only debug options:
CONFIG_DEBUG_QENCODER

View File

@@ -208,6 +208,7 @@
* *
* The STM32F4 Discovery has no on-board serial devices, but the console is * The STM32F4 Discovery has no on-board serial devices, but the console is
* brought out to PA2 (TX) and PA3 (RX) for connection to an external serial device. * brought out to PA2 (TX) and PA3 (RX) for connection to an external serial device.
* (See the README.txt file for other options)
*/ */
#define GPIO_USART2_RX GPIO_USART2_RX_1 #define GPIO_USART2_RX GPIO_USART2_RX_1
@@ -227,6 +228,11 @@
#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1 #define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1
#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1 #define GPIO_SPI1_SCK GPIO_SPI1_SCK_1
/* Timer Inputs/Outputs (see the README.txt file for options) */
#define GPIO_TIM2_CH1IN GPIO_TIM2_CH1IN_2
#define GPIO_TIM2_CH2IN GPIO_TIM2_CH2IN_1
/************************************************************************************ /************************************************************************************
* Public Data * Public Data
************************************************************************************/ ************************************************************************************/

View File

@@ -51,3 +51,7 @@ endif
ifeq ($(CONFIG_PWM),y) ifeq ($(CONFIG_PWM),y)
CONFIGURED_APPS += examples/pwm CONFIGURED_APPS += examples/pwm
endif endif
ifeq ($(CONFIG_QENCODER),y)
CONFIGURED_APPS += examples/qencoder
endif

View File

@@ -1,7 +1,7 @@
############################################################################ ############################################################################
# configs/stm32f4discovery/nsh/defconfig # configs/stm32f4discovery/nsh/defconfig
# #
# Copyright (C) 2011 Gregory Nutt. All rights reserved. # Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org> # Author: Gregory Nutt <gnutt@nuttx.org>
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@@ -313,18 +313,25 @@ CONFIG_STM32_PHYSR_FULLDUPLEX=0x0004
CONFIG_STM32_ETH_PTP=n CONFIG_STM32_ETH_PTP=n
CONFIG_STM32_ETHMAC_REGDEBUG=n CONFIG_STM32_ETHMAC_REGDEBUG=n
# #
# PWM configuration # PWM configuration
# #
# The stm32f4discovery has no real on-board PWM devices, but the board can be configured to output # The stm32f4discovery has no real on-board PWM devices, but the board can be configured to output
# a pulse train using TIM4 CH2. # a pulse train using TIM4 CH2. (Don't forget to set CONFIG_STM32_TIM4=y above)
# #
CONFIG_PWM=n CONFIG_PWM=n
CONFIG_STM32_TIM4=y
CONFIG_STM32_TIM4_PWM=y CONFIG_STM32_TIM4_PWM=y
CONFIG_STM32_TIM4_CHANNEL=2 CONFIG_STM32_TIM4_CHANNEL=2
#
# Quadrature Encoder configuration.
#
# Uses TIM2 (CONFIG_STM32_TIM2=y above)
#
#
CONFIG_QENCODER=n
CONFIG_STM32_TIM2_QE=y
# #
# General build options # General build options
# #
@@ -452,6 +459,7 @@ CONFIG_DEBUG_RTC=n
CONFIG_DEBUG_ANALOG=n CONFIG_DEBUG_ANALOG=n
CONFIG_DEBUG_PWM=n CONFIG_DEBUG_PWM=n
CONFIG_DEBUG_CAN=n CONFIG_DEBUG_CAN=n
CONFIG_DEBUG_QENCODER=n
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_MM_REGIONS=2 CONFIG_MM_REGIONS=2
CONFIG_ARCH_LOWPUTC=y CONFIG_ARCH_LOWPUTC=y

View File

@@ -56,6 +56,10 @@ ifeq ($(CONFIG_PWM),y)
CSRCS += up_pwm.c CSRCS += up_pwm.c
endif endif
ifeq ($(CONFIG_QENCODER),y)
CSRCS += up_qencoder.c
endif
COBJS = $(CSRCS:.c=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS) SRCS = $(ASRCS) $(CSRCS)

View File

@@ -2,7 +2,7 @@
* configs/stm3240g_eval/src/stm3240g_internal.h * configs/stm3240g_eval/src/stm3240g_internal.h
* arch/arm/src/board/stm3240g_internal.n * arch/arm/src/board/stm3240g_internal.n
* *
* Copyright (C) 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@@ -2,7 +2,7 @@
* configs/stm3240g_eval/src/up_autoleds.c * configs/stm3240g_eval/src/up_autoleds.c
* arch/arm/src/board/up_autoleds.c * arch/arm/src/board/up_autoleds.c
* *
* Copyright (C) 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* configs/stm32f4discovery/src/up_buttons.c * configs/stm32f4discovery/src/up_buttons.c
* *
* Copyright (C) 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@@ -0,0 +1,144 @@
/************************************************************************************
* configs/stm32f4discovery/src/up_qencoder.c
* arch/arm/src/board/up_qencoder.c
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/sensors/qencoder.h>
#include <arch/board/board.h>
#include "chip.h"
#include "up_arch.h"
#include "stm32_qencoder.h"
#include "stm32f4discovery-internal.h"
/************************************************************************************
* Definitions
************************************************************************************/
/* Configuration *******************************************************************/
/* The following checks assum that the quadrature encoder is on TIM2. Make the
* appropriate changes if your configuration differes.
*/
#define HAVE_QENCODER 1
#ifndef CONFIG_QENCODER
# undef HAVE_QENCODER
#endif
#ifndef CONFIG_STM32_TIM2
# undef HAVE_QENCODER
#endif
#ifndef CONFIG_STM32_TIM2_QE
# undef HAVE_QENCODER
#endif
#ifdef HAVE_QENCODER
/* Debug ***************************************************************************/
/* Non-standard debug that may be enabled just for testing the quadrature encoder */
#ifndef CONFIG_DEBUG
# undef CONFIG_DEBUG_QENCODER
#endif
#ifdef CONFIG_DEBUG_QENCODER
# define qedbg dbg
# define qelldbg lldbg
# ifdef CONFIG_DEBUG_VERBOSE
# define qevdbg vdbg
# define qellvdbg llvdbg
# else
# define qelldbg(x...)
# define qellvdbg(x...)
# endif
#else
# define qedbg(x...)
# define qelldbg(x...)
# define qevdbg(x...)
# define qellvdbg(x...)
#endif
/************************************************************************************
* Private Functions
************************************************************************************/
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: qe_devinit
*
* Description:
* All STM32 architectures must provide the following interface to work with
* examples/qencoder.
*
************************************************************************************/
int qe_devinit(void)
{
static initialized = false;
int ret;
/* Check if we are already initialized */
if (!initialized)
{
/* Initialize a quadrature encoder interface. */
qevdbg("Initializing the quadrature encoder\n");
ret = stm32_qeinitialize("/dev/qe0", 2);
if (ret < 0)
{
qedbg("stm32_qeinitialize failed: %d\n", ret);
return ret;
}
initialized = true;
}
return OK;
}
#endif /* HAVE_QENCODER */

View File

@@ -365,7 +365,13 @@ static int qe_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
* lower - An instance of the lower half interface * lower - An instance of the lower half interface
* *
* Returned Value: * Returned Value:
* Zero (OK) on success; a negated errno value on failure. * Zero (OK) on success; a negated errno value on failure. The following
* possible error values may be returned (most are returned by
* register_driver()):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
* *
****************************************************************************/ ****************************************************************************/

View File

@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* fs/fs_registerreserve.c * fs/fs_registerreserve.c
* *
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -39,6 +39,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <assert.h>
#include <errno.h> #include <errno.h>
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
@@ -66,7 +67,7 @@
* Name: inode_namelen * Name: inode_namelen
****************************************************************************/ ****************************************************************************/
static int inode_namelen(const char *name) static int inode_namelen(FAR const char *name)
{ {
const char *tmp = name; const char *tmp = name;
while(*tmp && *tmp != '/') tmp++; while(*tmp && *tmp != '/') tmp++;
@@ -87,7 +88,7 @@ static void inode_namecpy(char *dest, const char *src)
* Name: inode_alloc * Name: inode_alloc
****************************************************************************/ ****************************************************************************/
static FAR struct inode *inode_alloc(const char *name) static FAR struct inode *inode_alloc(FAR const char *name)
{ {
int namelen = inode_namelen(name); int namelen = inode_namelen(name);
FAR struct inode *node = (FAR struct inode*)kzalloc(FSNODE_SIZE(namelen)); FAR struct inode *node = (FAR struct inode*)kzalloc(FSNODE_SIZE(namelen));
@@ -142,27 +143,50 @@ static void inode_insert(FAR struct inode *node,
/**************************************************************************** /****************************************************************************
* Name: inode_reserve * Name: inode_reserve
* *
* Description:
* Reserve an (initialized) inode the pseudo file system.
*
* NOTE: Caller must hold the inode semaphore * NOTE: Caller must hold the inode semaphore
*
* Input parameters:
* path - The path to the inode to create
* inode - The location to return the inode pointer
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* value is returned on failure:
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
****************************************************************************/ ****************************************************************************/
FAR struct inode *inode_reserve(const char *path) int inode_reserve(FAR const char *path, FAR struct inode **inode)
{ {
const char *name = path; const char *name = path;
FAR struct inode *left; FAR struct inode *left;
FAR struct inode *parent; FAR struct inode *parent;
/* Assume failure */
DEBUGASSERT(path && inode);
*inode = NULL;
/* Handle paths that are interpreted as the root directory */
if (!*path || path[0] != '/') if (!*path || path[0] != '/')
{ {
return NULL; return -EINVAL;
} }
/* Find the location to insert the new subtree */ /* Find the location to insert the new subtree */
if (inode_search(&name, &left, &parent, (const char **)NULL) != NULL) if (inode_search(&name, &left, &parent, (FAR const char **)NULL) != NULL)
{ {
/* Is is an error if the node already exists in the tree */ /* It is an error if the node already exists in the tree */
return NULL; return -EEXIST;
} }
/* Now we now where to insert the subtree */ /* Now we now where to insert the subtree */
@@ -176,7 +200,7 @@ FAR struct inode *inode_reserve(const char *path)
* by looking at the next name. * by looking at the next name.
*/ */
const char *next_name = inode_nextname(name); FAR const char *next_name = inode_nextname(name);
if (*next_name) if (*next_name)
{ {
/* Insert an operationless node */ /* Insert an operationless node */
@@ -200,11 +224,13 @@ FAR struct inode *inode_reserve(const char *path)
if (node) if (node)
{ {
inode_insert(node, left, parent); inode_insert(node, left, parent);
return node; *inode = node;
return OK;
} }
} }
/* We get here on failures to allocate node memory */ /* We get here on failures to allocate node memory */
return NULL;
return -ENOMEM;
} }
} }

View File

@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* fs/fs_internal.h * fs/fs_internal.h
* *
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -111,19 +111,19 @@ EXTERN FAR struct inode *inode_search(FAR const char **path,
FAR struct inode **parent, FAR struct inode **parent,
FAR const char **relpath); FAR const char **relpath);
EXTERN void inode_free(FAR struct inode *node); EXTERN void inode_free(FAR struct inode *node);
EXTERN const char *inode_nextname(const char *name); EXTERN const char *inode_nextname(FAR const char *name);
/* fs_inodereserver.c ********************************************************/ /* fs_inodereserver.c ********************************************************/
EXTERN FAR struct inode *inode_reserve(const char *path); EXTERN int inode_reserve(FAR const char *path, FAR struct inode **inode);
/* fs_inoderemove.c **********************************************************/ /* fs_inoderemove.c **********************************************************/
EXTERN int inode_remove(const char *path); EXTERN int inode_remove(FAR const char *path);
/* fs_inodefind.c ************************************************************/ /* fs_inodefind.c ************************************************************/
EXTERN FAR struct inode *inode_find(const char *path, const char **relpath); EXTERN FAR struct inode *inode_find(FAR const char *path, const char **relpath);
/* fs_inodeaddref.c **********************************************************/ /* fs_inodeaddref.c **********************************************************/

View File

@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* fs/fs_mount.c * fs/fs_mount.c
* *
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -193,9 +193,9 @@ mount_findfs(FAR const struct fsmap_t *fstab, FAR const char *filesystemtype)
* *
****************************************************************************/ ****************************************************************************/
int mount(const char *source, const char *target, int mount(FAR const char *source, FAR const char *target,
const char *filesystemtype, unsigned long mountflags, FAR const char *filesystemtype, unsigned long mountflags,
const void *data) FAR const void *data)
{ {
#if defined(BDFS_SUPPORT) || defined(NONBDFS_SUPPORT) #if defined(BDFS_SUPPORT) || defined(NONBDFS_SUPPORT)
#ifdef BDFS_SUPPORT #ifdef BDFS_SUPPORT
@@ -205,7 +205,7 @@ int mount(const char *source, const char *target,
FAR const struct mountpt_operations *mops; FAR const struct mountpt_operations *mops;
void *fshandle; void *fshandle;
int errcode; int errcode;
int status; int ret;
/* Verify required pointer arguments */ /* Verify required pointer arguments */
@@ -222,11 +222,11 @@ int mount(const char *source, const char *target,
/* Find the block driver */ /* Find the block driver */
status = find_blockdriver(source, mountflags, &blkdrvr_inode); ret = find_blockdriver(source, mountflags, &blkdrvr_inode);
if (status < 0) if (ret < 0)
{ {
fdbg("Failed to find block driver %s\n", source); fdbg("Failed to find block driver %s\n", source);
errcode = -status; errcode = -ret;
goto errout; goto errout;
} }
} }
@@ -249,15 +249,19 @@ int mount(const char *source, const char *target,
*/ */
inode_semtake(); inode_semtake();
mountpt_inode = inode_reserve(target); ret = inode_reserve(target, &mountpt_inode);
if (!mountpt_inode) if (ret < 0)
{ {
/* inode_reserve can fail for a couple of reasons, but the most likely /* inode_reserve can fail for a couple of reasons, but the most likely
* one is that the inode already exists. * one is that the inode already exists. inode_reserve may return:
*
* -EINVAL - 'path' is invalid for this operation
* -EEXIST - An inode already exists at 'path'
* -ENOMEM - Failed to allocate in-memory resources for the operation
*/ */
fdbg("Failed to reserve inode\n"); fdbg("Failed to reserve inode\n");
errcode = EBUSY; errcode = -ret;
goto errout_with_semaphore; goto errout_with_semaphore;
} }
@@ -289,18 +293,18 @@ int mount(const char *source, const char *target,
/* On failure, the bind method returns -errorcode */ /* On failure, the bind method returns -errorcode */
#ifdef BDFS_SUPPORT #ifdef BDFS_SUPPORT
status = mops->bind(blkdrvr_inode, data, &fshandle); ret = mops->bind(blkdrvr_inode, data, &fshandle);
#else #else
status = mops->bind(NULL, data, &fshandle); ret = mops->bind(NULL, data, &fshandle);
#endif #endif
if (status != 0) if (ret != 0)
{ {
/* The inode is unhappy with the blkdrvr for some reason. Back out /* The inode is unhappy with the blkdrvr for some reason. Back out
* the count for the reference we failed to pass and exit with an * the count for the reference we failed to pass and exit with an
* error. * error.
*/ */
fdbg("Bind method failed: %d\n", status); fdbg("Bind method failed: %d\n", ret);
#ifdef BDFS_SUPPORT #ifdef BDFS_SUPPORT
#ifdef NONBDFS_SUPPORT #ifdef NONBDFS_SUPPORT
if (blkdrvr_inode) if (blkdrvr_inode)
@@ -309,7 +313,7 @@ int mount(const char *source, const char *target,
blkdrvr_inode->i_crefs--; blkdrvr_inode->i_crefs--;
} }
#endif #endif
errcode = -status; errcode = -ret;
goto errout_with_mountpt; goto errout_with_mountpt;
} }

View File

@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* fs/fs_registerblockdriver.c * fs/fs_registerblockdriver.c
* *
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -65,27 +65,45 @@
/**************************************************************************** /****************************************************************************
* Name: register_driver * Name: register_driver
*
* Description:
* Register a block driver inode the pseudo file system.
*
* Input parameters:
* path - The path to the inode to create
* bops - The block driver operations structure
* mode - inmode priviledges (not used)
* priv - Private, user data that will be associated with the inode.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
****************************************************************************/ ****************************************************************************/
int register_blockdriver(const char *path, int register_blockdriver(FAR const char *path,
const struct block_operations *bops, FAR const struct block_operations *bops,
mode_t mode, void *priv) mode_t mode, FAR void *priv)
{ {
struct inode *node; FAR struct inode *node;
int ret = -ENOMEM; int ret;
/* Insert an inode for the device driver -- we need to hold the inode semaphore /* Insert an inode for the device driver -- we need to hold the inode
* to prevent access to the tree while we this. This is because we will have a * semaphore to prevent access to the tree while we this. This is because
* momentarily bad true until we populate the inode with valid data. * we will have a momentarily bad true until we populate the inode with
* valid data.
*/ */
inode_semtake(); inode_semtake();
node = inode_reserve(path); ret = inode_reserve(path, &node);
if (node != NULL) if (ret >= 0)
{ {
/* We have it, now populate it with block driver specific /* We have it, now populate it with block driver specific information. */
* information.
*/
INODE_SET_BLOCK(node); INODE_SET_BLOCK(node);

View File

@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* fs/fs_registerdriver.c * fs/fs_registerdriver.c
* *
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -65,25 +65,42 @@
/**************************************************************************** /****************************************************************************
* Name: register_driver * Name: register_driver
*
* Description:
* Register a character driver inode the pseudo file system.
*
* Input parameters:
* path - The path to the inode to create
* fops - The file operations structure
* mode - inmode priviledges (not used)
* priv - Private, user data that will be associated with the inode.
*
* Returned Value:
* Zero on success (with the inode point in 'inode'); A negated errno
* value is returned on a failure (all error values returned by
* inode_reserve):
*
* EINVAL - 'path' is invalid for this operation
* EEXIST - An inode already exists at 'path'
* ENOMEM - Failed to allocate in-memory resources for the operation
*
****************************************************************************/ ****************************************************************************/
int register_driver(const char *path, const struct file_operations *fops, int register_driver(FAR const char *path, FAR const struct file_operations *fops,
mode_t mode, void *priv) mode_t mode, FAR void *priv)
{ {
struct inode *node; FAR struct inode *node;
int ret = ERROR; int ret;
/* Insert a dummy node -- we need to hold the inode semaphore /* Insert a dummy node -- we need to hold the inode semaphore because we
* to do this because we will have a momentarily bad structure. * will have a momentarily bad structure.
*/ */
inode_semtake(); inode_semtake();
node = inode_reserve(path); ret = inode_reserve(path, &node);
if (node != NULL) if (ret >= 0)
{ {
/* We have it, now populate it with driver specific /* We have it, now populate it with driver specific information. */
* information.
*/
INODE_SET_DRIVER(node); INODE_SET_DRIVER(node);