diff --git a/.gitignore b/.gitignore
index 409232b7376b9c452400727cdac69f42ffdc2c69..3ec700458d0a455ed748bb4a6a498a844ae197b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,33 +1,30 @@
-.depend
-Make.dep
-*.o
-*.a
-*.d
-*.i
-*~
-.swp
-.*.swp
-core
-.gdbinit
-cscope.out
-/.config
-/.config.old
-/.version
-/Make.defs
-/setenv.sh
-/setenv.bat
-/nuttx
-/nuttx.*
-/nuttx-*
-/_SAVED_APPS_config
-/*.map
-/*.elf
-/*.srec
-/*.bin
-/*.ihx
-/*.hex
-/pcode
-/tags
-/.settings/
-/.cproject
-/.project
+.depend
+Make.dep
+*.o
+*.a
+*.d
+*.i
+*~
+.swp
+.*.swp
+core
+.gdbinit
+cscope.out
+/.config
+/.config.old
+/.version
+/Make.defs
+/setenv.sh
+/setenv.bat
+/nuttx
+/nuttx.*
+/nuttx-*
+/_SAVED_APPS_config
+/*.map
+/*.elf
+/*.srec
+/*.bin
+/*.ihx
+/*.hex
+/pcode
+/tags
diff --git a/COPYING b/COPYING
index a8113ab027c91b871a68a2632d5f69200e4ca81b..2fcc3edc6addae4a73847bb6371d8297dfa489d2 100644
--- a/COPYING
+++ b/COPYING
@@ -225,44 +225,3 @@ drivers/video/ov2640
content of those tables and still retain this BSD license. I am guessing
so, but I am not a copyright attorney so you should use this driver in
products at your own risk.
-
-apps/netutils/pppd
-^^^^^^^^^^^^^^^^^^
-
- This implementation of PPPD has a license that is mostly compatible the
- NuttX 3-clause BSD license, but includes a fourth clause that required
- acknowledgement of Mike Johnson/Mycal Labs if it is built into your
- product:
-
- Copyright (C) 2000, Mycal Labs www.mycal.com
- Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net
- All rights reserved.
-
- 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. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by Mike Johnson/Mycal Labs
- www.mycal.net.
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
diff --git a/ChangeLog b/ChangeLog
index 10c9ed34b6033696313bbecee90ff2cc886b1adb..06eba68671da0b6923ee8f6f92fdfc0bda9313ea 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -12117,3 +12117,181 @@
(2016-06-21).
* drivers/syslog: Extend SYSLOG logic so that we can send SYSLOG output
to a file. Not verified on initial commit (2016-06-21).
+ * arch/arm/src/stm32l4: Add some CAN mode IOCTL calls. These will be
+ useful for device autotest when the application boots. They are
+ redundant with the CONFIG_CAN_LOOPBACK option, which can now just be
+ interpreted as a default setting. From Sebastien Lorquet (2016-06-22).
+ * drivers/syslog: syslog_dev_flush() needs to check if the inode is a
+ mountpoint before calling the flush() method. Noted by David Sidrane
+ (2016-06-22).
+ * arch/arm/src/stm32f7: Adds SDMMC1 for stm32F7 74-75. From Lok Tep
+ (2016-06-22).
+ * drivers/syslog: SYSLOG character device channel will now expand LF to
+ CR-LF. Controllable with a configuration option (2016-06-22).
+ * arch/arm/src/stm32l4: Implementation of loopback IOCTLs. From
+ Sebastien Lorquet (2016-06-22).
+ * Documentation: Add SYSLOG documentation to the porting guide
+ (2016-06-22).
+ * configs/stm32f746g-disco: Removed knsh configuration it failed to
+ refresh (via tools/refresh.sh). I assume that it is a hand-edited
+ configuration and, hence, must be removed from the repository
+ (2016-06-23).
+ * arch/arm/arc/sam34: DAC bugfix: DACC_WPMR_WPKEY_MASK -> DACC_WPMR_WPKEY.
+ Timer bugfix: Fix ops check in TCIOC_STOP. From Wolfgang Reissnegge
+ (2016-06-23).
+ * configs/nucleo-144: Added SDMMC support to Nucleo-144. From David
+ Sidrane (2016-06-23).
+ * arch/arm/src/stm32: Port STM32L4 CAN IOCTLs to STM32. From Sebastien
+ Lorquet (2016-06-24).
+ * drivers/ioexpander: Add support for a very simple GPIO driver. It
+ supports only pre-conrigured input and output pins and only basic
+ input and output operations (2016-06-24).
+ * arch/arm/src/lpc43xx: Correct auto-negotiation mode in the LPC43xx
+ Ethernet. From Alexander Vasiljev (2016-06-24)
+ * arch/arm/src/samv7: TWIHS Driver improved and GPIO-Driver fixed for
+ Open-Drain Pins
+ - sam_gpioread: Now the actual line level from the pin is read back.
+ This is extremely important for Open-Drain Pins, which can be used
+ bidirectionally
+ - Re-Implemented twi_reset-function and enhanced it so it can be
+ called from inside the driver (see next point)
+ - Glitch-Filter: Added a configuration option to enable the twi-built-
+ in glitch filter
+ - Added a "Single Master Mode": In EMC Testing the TWI-Bus got stuck
+ because the TWI-Master detected a Multi-Master access (but there is
+ no second master). With the option "Single Master" we detect these
+ events and automatically trigger a twi_reset. We also do an
+ automatic recovery if a slave got stuck (SDA stays low).
+ With the above changes I²C-Bus reliability in harsh environments (eg.
+ EMC) is greatly improved. The small change in the GPIO-Driver was
+ necessary because otherwise you cannot read back the correct line
+ status of Open-Drain Outputs and this is needed by the twi_reset
+ function. From Michael Spahlinger (2016-06-24)
+ * arch/arm/src/stm32f7: BUGFIX:PLLs IS2 and SAI P Calculation. From
+ David Sidrane (2016-06-24).
+ * arch/arm/src/stm32f7: USB support. From Lok Tep (2016-06-27).
+ * configs/olimex-stm32-e407: Add support for Olimex STM32 E407
+ board. From Mateusz Szafoni (2016-06-27).
+ * drivers/ioexpander: Shadow-Mode: The output- and configuration
+ registers of the IO-Expander are held in the microcontrollers memory
+ and only written to the IO-Expander. This reduces bus traffic and
+ is more error-proof than the normal read-modify-write operation. Retry
+ Mode: If enabled and an error occurs while writing to the IO-Expander
+ the current transmission is automatically repeated once. From Michael
+ Spahlinger (2016-06-27).
+ * libc/hex2bin: Move the portable library portion of apps/system/hex2bin
+ to nuttx/libc/hex2bin where it can be shared with the OS internals
+ (2016-06-27).
+ * configs/nucleo-144: Added USB OTG device to Nucleo-144. From David
+ Sidrane (2016-06-27).
+ * arch/arm/src/stm32l4: STM32 CAN fixes need to be backported to
+ STM32L4 as well (2016-06-27).
+ * ARM stack check: Fix double fault on IDLE task with stack size = 0.
+ From David Sidrane (2016-06-27).
+ * configs/nucleo-144: Added bbsram test to Nucleo-144. From David
+ Sidrane (2016-06-27).
+ * arch/arm/src/stm32f7: Added PWR, RTC, and BBSRAM support for stm32f7.
+ From David Sidrane (2016-06-27).
+ * Build system: Fixed build of SAMV71-XULT/nsh. With the changes from
+ 26f7b8c the build process of the default configuration did not succeed
+ anymore. From Michael Spahlinger (2016-06-28).
+ * sched/semaphore: Need to set errno to EINVAL on errors in sem_post()
+ and sem_wait(). From Paul Alexander Patience (2016-06-28).
+ * Build system: This change fixes a build problem that only occurs when
+ reconfiguring from Linux to Windows or vice-versa. It is a problem
+ that was present but not usually experienced until two things happened:
+ (1) The pre_config target was added to run before the menconfig
+ operation and (2) the context target was added before the pre_config
+ target in order to set up the correct symbolic links (in the apps/platform
+ directory) needed by the pre_config target.
+ But then now if you start with a Linux system and run 'make menuconfig'
+ to switch to Linux, the context target will execute first and set up
+ POSIX style symbolic links before doing the menuconfig. Then after the
+ menuconfig, the make will fail on Windows if you are using a Windows
+ native toolchain because that native toolchain cannot follow the Cygwin-
+ style symbolic links.
+ The fix here is to also execute the clean_context AFTER executing
+ menuconfig. A lot more happens now: It used to be that doing 'make
+ menuconfig' only did the menuconfig operation. No it does context,
+ pre_config, menuconfig, clean_context. Not nearly as snappy as it used
+ to be (2016-06-28).
+ * arch/arm/src/efm32, lcp43, stm32, stm32l4: disable interrupts with
+ NVIC_IRQ_CLEAR. From Paul Alexander Patience (2016-06-28).
+ * arch/arm/src/stm32f7: STMF7xxx RTC: (1) Remove proxy #defines, (2)
+ Ensure the LSE(ON) etal are set and remembered in a) A cold start
+ (RTC_MAGIC invalid) of the RTC, and b) A warm start (RTC_MAGIC valid)
+ of the RTC but a clock change. The change was needed because in bench
+ testing a merge of the latest's STM32 53ec3ca (and friends) it became
+ apparent that the sequence of operation is wrong in the reset of the
+ Backup Domain in the RCC code. PWR is required before the Backup
+ Domain can be futzed with. !!!This Code should be tested on STM32 and
+ if needed rippled to the STM32 families. From David Sidrane
+ (2016-06-28).
+ * arch/arm/src/stm32f7: Added STMF7xxx RTC. From David Sidrane
+ (2016-06-28).
+ * arch/arm/src/stm32: STM32 BBSRAM fixed (and formatted) flags. From
+ David Sidrane (2016-06-28).
+ * arch/arm/src/stm32f7: STM32F7 BBSRAM fixed (and formatted) flags.
+ From David Sidrane (2016-06-28).
+ * arch/arm/src/stm32f7: Added STM32F7 DBGMCU. From David Sidrane
+ (2016-06-28).
+ * arch/arm/src/samv7: SAMV7: CAN Message Filtering fixed: (1) stdfilters
+ didn't work because the filter was never enabled (wrong number of bits
+ to shift), and (2) Filters were never used because the configuration
+ register cannot be written without using the initialization mode.
+ Both bugs are fixed by this change. Filtering has been tested with
+ both standard and extended identifiers and is now working properly.
+ From Michael Spahlinger (2016-06-29).
+ * configs/Kconfig and dummy/: Add logic to support custom board
+ directories that include a Kconfig file. During the context phase
+ of the build, any Kconfig file in the custom board directory is copied
+ into configs/dummy, replacing the existing Kconfig file with the
+ target Kconfig file (2016-06-29).
+ * arch/arm/src/stm32l4: Port support for both RX FIFOs from STM32 CAN.
+ From Paul Alexander Patience (2016-06-29).
+ * Remove all inclusion of header files from the apps/include directory.
+ This caused a lot of reshuffling of logic: binfmt pcode support,
+ usbmonitor is now a kernel thread, TZ/Olson database moved to
+ libc/zoneinfo (2016-06-29).
+ * drivers/mtd: Several MTD FLASH drivers nullify the freed 'priv'
+ structure and failed to return NULL as stated in the comments.
+ Result, will operate on a NULL pointer later. Noted by David Sidrane
+ (2016-06-30).
+ * arch/arm/src/kinetis: Add basic support for the K64 family. I
+ leveraged the changes from https://github.com/jmacintyre/nuttx-k64f
+ and merged into the existing kinetis code with a lot of changes and
+ additions (like pin multiplexing definitions). (2016-07-01).
+ * configs/freedom-k64f: Add support for the NXP Freedom-K64F board.
+ This is primarily the work of Jordan Macintyre. I leveraged this
+ code from https://github.com/jmacintyre/nuttx-k64f but with
+ significant corrections (LEDs, buttons, README, etc) and extensions
+ and updates to match more recent BSPs (2016-07-01).
+ * libc/signal: Add raise() (2016-07-04).
+ * drivers/syslog: Add a SYSLOG character device that can be used to re-
+ direct output to the SYSLOG (2016-07-05).
+ * net/netdev: Break out internal interface psock_ioctl() (2016-07-06).
+ * configs/stm32f4disovery: add can driver for stm32f4discovery. From
+ Matthias Renner (2016-07-06).
+ * configs/freedom-k64f: Increase MCU clock to 120MHz (2016-07-06).
+ * arch/arm/src/stm32: Add support for Tickless mode (two timer
+ implementation). From Max Neklyudov (2016-07-06).
+ * drivers/usbdev: cdcacm_unbind leaks write request objects. This
+ arises due to freeing the bulk IN endpoint before the loop that
+ frees the requests via cdcasm_freereq. That function checks the
+ parameters and skips the freeing if either is NULL. Freeing the bulk
+ IN enpoint will cause the first param to be NULL, thereby bypassing
+ the free operation. To fix, I moved the release of the bulk IN
+ endpoint until after to loop (much as was the case for the OUT and
+ read requests, which did not exhibit the problem). From ziggurat29
+ (2016-07-07).
+ * arch/arm/src/stm32l4: Update usb dev/host controller drivers to
+ reflect new(ish) logging standards; augment device enpoint and fifo
+ allocation #defines to do more sanity checking, and be automatically
+ adaptive to size changes. Update README.txt to reflect current status
+ of the implementation. From ziggurat29 (2016-07-07).
+ * arch/arm/src/stm32f7: Fixed STM32F7 DMA stm32_dmacapable. DMA working
+ on SDMMC. From David Sidrane (2016-07-07).
+ * configs/stm32f4discovery: add configuration files for canard. From
+ Matthias Renner (2016-07-08).
+ * drivers/pipe: Add missing configuration for pipe ring buffer size.
+ From Frank Benkert (2016-07-08).
diff --git a/Directories.mk b/Directories.mk
index 2e42a8a435f25de41b1646e5bcea5a60787b7a86..2e55b91a94007f210ad4b6ab58700092a32e3bb3 100644
--- a/Directories.mk
+++ b/Directories.mk
@@ -74,7 +74,7 @@ endif
NONFSDIRS = sched drivers configs $(ARCH_SRC) $(NUTTX_ADDONS)
FSDIRS = fs binfmt
-CONTEXTDIRS = $(APPDIR)
+CONTEXTDIRS = configs $(APPDIR)
USERDIRS =
OTHERDIRS = lib
@@ -114,6 +114,10 @@ else
OTHERDIRS += syscall
endif
+ifeq ($(CONFIG_LIB_ZONEINFO_ROMFS),y)
+CONTEXTDIRS += libc
+endif
+
ifeq ($(CONFIG_NX),y)
NONFSDIRS += graphics libnx
CONTEXTDIRS += graphics libnx
diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html
index b067a8c13983b15f2d557eee1c985a07865cb281..d36ca6f21049566911241ccbfc14b953f1a35161 100644
--- a/Documentation/NuttxPortingGuide.html
+++ b/Documentation/NuttxPortingGuide.html
@@ -12,7 +12,7 @@
+ The NuttX implementation does not support any special formatting characters beyond those supported by printf()
.
+
+
+ REVISIT: Per POSIX the SYSLOG mask should be a per-process value but in NuttX, the scope of the mask is dependent on the nature of the build:
+
+
+ In NuttX, syslog output is really synonymous to debug output and, herefore, the debugging interface macros defined in the header file
+ include/debug.h
are also syslogging interfaces. Those macros are simply wrappers around syslog()
. The debugging interfaces differ from the syslog interfaces in that:
+
+
+ Each debug macro has a base name that represents the priority and a prefix that represents the sub-system. Each macro is individually initialized by both priority and sub-system. For example, uerr()
is the macro used for error level messages from the USB subsystem and is enabled with CONFIG_DEBUG_USB_ERROR
.
+
+
+ The base debug macro names, their priority, and configuration variable are summarized below:
+
+
+ In the NuttX SYSLOG implementation, the underlying device logic the supports the SYSLOG output is referred to as a SYSLOG channel. Each SYSLOG channel is represented by an interface defined in include/nuttx/syslog/syslog.h
:
+
+
+ The initial, default SYSLOG channel is established with statically initialized global variables so that some level of SYSLOG output may be available immediately upon reset. This initialized data is in the file drivers/syslog/syslog_channel.c
. The initial SYSLOG capability is determined by the selected SYSLOG channel:
+
+
+ Different types of SYSLOG devices have different OS initialization
+ requirements. Some are available immediately at reset, some are available
+ after some basic OS initialization, and some only after OS is fully
+ initialized. In order to satisfy these different initialization
+ requirements, syslog_initialize()
is called twice from the boot-up logic:
+
+
+ There are other types of SYSLOG channel devices that may require even further initialization. For example, the file SYSLOG channel (described below) cannot be initialized until the necessary file systems have been mounted.
+
+
+
+ As a general statement, SYSLOG output only supports //normal// output from NuttX tasks. However, for debugging purposes, it is also useful to get SYSLOG output from interrupt level logic. In an embedded system, that is often where the most critical operations are performed.
+
+
+ There are three conditions under which SYSLOG output generated from interrupt level processing can a included the SYSLOG output stream:
+
+
+ The typical SYSLOG device is the system console. If you are using a serial console, for example, then the SYSLOG output will appear on that serial port.
+
+
+ Interrupt level SYSLOG output will be lost unless: (1) the interrupt buffer
+ is enabled to support serialization, or (2) a serial console is used and
+ up_putc()
is supported.
+
+
+ Files can also be used as the sink for SYSLOG output. There is, however, a very fundamental difference in using a file as opposed the system console, a RAM buffer, or character device: You must first mount the file system that supports the SYSLOG file. That difference means that the file SYSLOG channel cannot be supported during the boot-up phase but can be instantiated later when board level logic configures the application environment, including mounting of the file systems.
+
+
+ File SYSLOG channels differ from other SYSLOG channels in that they cannot be established until after fully booting and mounting the target file system. This function would need to be called from board-specific bring-up logic AFTER mounting the file system containing devpath
.
+
+
+ NOTE interrupt level SYSLOG output will be lost in this case unless the interrupt buffer is used.
+
+
+
+ The RAMLOG is a standalone feature that can be used to buffer any
+ character data in memory. There are, however, special configurations
+ that can be used to configure the RAMLOG as a SYSLOG channel. The RAMLOG
+ functionality is described in a more general way in the following
+ paragraphs.
+
+
+
+ The RAM logging driver can also accept debug output data from interrupt handler with no special serialization buffering. As an added benefit, the RAM logging driver is much less invasive. Since no actual I/O is performed with the debug output is generated, the RAM logger tends to be much faster and will interfere much less when used with time critical drivers.
+
+
+ The RAM logging driver is similar to a pipe in that it saves the debugging output in a circular buffer in RAM. It differs from a pipe in numerous details as needed to support logging.
+
+
+ When the RAMLOG (with SYSLOG) is enabled, a new NuttShell (NSH) command will appear: dmesg
. The dmesg
command will dump the contents of the circular buffer to the console (and also clear the circular buffer).
+
+
+
diff --git a/Documentation/UsbTrace.html b/Documentation/UsbTrace.html
index a6800983d5bcb272c099f6bfba24de374b9a707a..25c8736b7b3a45d131cb0725eac59c2811b55df5 100644
--- a/Documentation/UsbTrace.html
+++ b/Documentation/UsbTrace.html
@@ -396,7 +396,7 @@ static int pl2303_setup(FAR struct uart_dev_s *dev)
- CONFIG_SYSTEM_USBMONITOR_TRACEINIT=y
- CONFIG_SYSTEM_USBMONITOR_TRACECLASS=y
- CONFIG_SYSTEM_USBMONITOR_TRACETRANSFERS=y
- CONFIG_SYSTEM_USBMONITOR_TRACECONTROLLER=y
- CONFIG_SYSTEM_USBMONITOR_TRACEINTERRUPTS=y
+ CONFIG_USBMONITOR_TRACEINIT=y
+ CONFIG_USBMONITOR_TRACECLASS=y
+ CONFIG_USBMONITOR_TRACETRANSFERS=y
+ CONFIG_USBMONITOR_TRACECONTROLLER=y
+ CONFIG_USBMONITOR_TRACEINTERRUPTS=y
|
Selects which USB event(s) that you want to be traced.
diff --git a/Makefile.unix b/Makefile.unix
index 022c7962169728566385ea3666e8b05b01815b47..a117f171fc1b795d2902e33bef76f43ffb9645b1 100644
--- a/Makefile.unix
+++ b/Makefile.unix
@@ -280,16 +280,6 @@ tools/cnvwindeps$(HOSTEXEEXT):
# setting up symbolic links with 'generic' directory names to specific,
# configured directories.
#
-# Link the apps/include directory to include/apps
-
-include/apps: Make.defs
-ifneq ($(APPDIR),)
- @echo "LN: include/apps to $(APPDIR)/include"
- $(Q) if [ -d $(TOPDIR)/$(APPDIR)/include ]; then \
- $(DIRLINK) $(TOPDIR)/$(APPDIR)/include include/apps; \
- fi
-endif
-
# Link the arch//include directory to include/arch
include/arch: Make.defs
@@ -324,7 +314,7 @@ ifneq ($(CONFIG_ARCH_CHIP),)
$(Q) $(DIRLINK) $(TOPDIR)/$(ARCH_INC)/$(CONFIG_ARCH_CHIP) include/arch/chip
endif
-dirlinks: include/arch include/arch/board include/arch/chip $(ARCH_SRC)/board $(ARCH_SRC)/chip include/apps
+dirlinks: include/arch include/arch/board include/arch/chip $(ARCH_SRC)/board $(ARCH_SRC)/chip
# context
#
@@ -344,6 +334,7 @@ context: check_context include/nuttx/config.h include/nuttx/version.h include/ma
# and symbolic links created by the context target.
clean_context:
+ $(Q) $(MAKE) -C configs TOPDIR="$(TOPDIR)" clean_context
$(call DELFILE, include/nuttx/config.h)
$(call DELFILE, include/nuttx/version.h)
$(call DELFILE, include/math.h)
@@ -353,7 +344,6 @@ clean_context:
$(Q) $(DIRUNLINK) include/arch
$(Q) $(DIRUNLINK) $(ARCH_SRC)/board
$(Q) $(DIRUNLINK) $(ARCH_SRC)/chip
- $(Q) $(DIRUNLINK) include/apps
# check_context
#
@@ -480,24 +470,36 @@ pass2dep: context tools/mkdeps$(HOSTEXEEXT) tools/cnvwindeps$(HOSTEXEEXT)
# location: http://ymorin.is-a-geek.org/projects/kconfig-frontends. See
# README.txt file in the NuttX tools GIT repository for additional information.
-config: apps_preconfig
+do_config: context apps_preconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf Kconfig
-oldconfig: apps_preconfig
+config: do_config clean_context
+
+do_oldconfig: context apps_preconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf --oldconfig Kconfig
-olddefconfig: apps_preconfig
+oldconfig: do_oldconfig clean_context
+
+do_olddefconfig: context apps_preconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-conf --olddefconfig Kconfig
-menuconfig: apps_preconfig
+olddefconfig: do_olddefconfig clean_context
+
+do_menuconfig: context apps_preconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-mconf Kconfig
-qconfig: apps_preconfig
+menuconfig: do_menuconfig clean_context
+
+do_qconfig: context apps_preconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-qconf Kconfig
-gconfig: apps_preconfig
+qconfig: do_qconfig clean_context
+
+gconfig: context apps_preconfig
$(Q) APPSDIR=${CONFIG_APPS_DIR} kconfig-gconf Kconfig
+gconfig: do_gconfig clean_context
+
# export
#
# The export target will package the NuttX libraries and header files into
diff --git a/Makefile.win b/Makefile.win
index 5a71a42122b76d51fa96d2422549c6f45480c04a..1f30310525ec6784ac9c26df9b1ab8dd27946355 100644
--- a/Makefile.win
+++ b/Makefile.win
@@ -275,19 +275,6 @@ tools\mkdeps$(HOSTEXEEXT):
# setting up symbolic links with 'generic' directory names to specific,
# configured directories.
#
-# Link the apps\include directory to include\apps
-
-include\apps: Make.defs
-ifneq ($(APPDIR),)
- @echo LN: include\apps $(APPDIR)\include
-ifeq ($(CONFIG_WINDOWS_MKLINK),y)
- $(Q) /user:administrator mklink /d include\apps $(APPDIR)\include
-else
- $(Q) xcopy $(APPDIR)\include include\apps /c /q /s /e /y /i
- $(Q) echo FAKELNK > include\apps\.fakelnk
-endif
-endif
-
# Link the arch\\include directory to include\arch
include\arch: Make.defs
@@ -347,7 +334,7 @@ else
endif
endif
-dirlinks: include\arch include\arch\board include\arch\chip $(ARCH_SRC)\board $(ARCH_SRC)\chip include\apps
+dirlinks: include\arch include\arch\board include\arch\chip $(ARCH_SRC)\board $(ARCH_SRC)\chip
# context
#
@@ -374,7 +361,6 @@ clean_context:
$(call DELDIR, include\arch)
$(call DELDIR, $(ARCH_SRC)\board)
$(call DELDIR, $(ARCH_SRC)\chip)
- $(call DELDIR, include\apps)
# check_context
#
@@ -480,18 +466,26 @@ pass2dep: context tools\mkdeps$(HOSTEXEEXT)
# location: http://ymorin.is-a-geek.org/projects/kconfig-frontends. See
# misc\tools\README.txt for additional information.
-config: apps_preconfig
+do_config: context apps_preconfig
$(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf Kconfig
-oldconfig: apps_preconfig
+config: do_config clean_context
+
+do_oldconfig: context apps_preconfig
$(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf --oldconfig Kconfig
-olddefconfig: apps_preconfig
+oldconfig: do_oldconfig clean_context
+
+do_olddefconfig: context apps_preconfig
$(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-conf --olddefconfig Kconfig
-menuconfig: configenv apps_preconfig
+olddefconfig: do_olddefconfig clean_context
+
+do_menuconfig: context configenv apps_preconfig
$(Q) set APPSDIR=$(patsubst "%",%,${CONFIG_APPS_DIR})& kconfig-mconf Kconfig
+menuconfig: do_menuconfig clean_context
+
# export
#
# The export target will package the NuttX libraries and header files into
diff --git a/README.txt b/README.txt
index b3cb19a407d1186cd21c99a0e3c7c5ec67d60efc..4c12dca85ac5157cc5830d7a24eeee3e84acb2c8 100644
--- a/README.txt
+++ b/README.txt
@@ -1283,6 +1283,8 @@ nuttx/
| | `- README.txt
| |- fire-stm32v2/
| | `- README.txt
+ | |- freedom-k64f/
+ | | `- README.txt
| |- freedom-kl25z/
| | `- README.txt
| |- freedom-kl26z/
@@ -1325,8 +1327,6 @@ nuttx/
| | `- README.txt
| |- mirtoo/
| | `- README.txt
- | |- mt-db-x3/
- | | `- README.txt
| |- moteino-mega/
| | `- README.txt
| |- mx1ads/
@@ -1524,6 +1524,8 @@ nuttx/
|- lib/
| `- README.txt
|- libc/
+ | |- zoneinfo
+ | | `- README.txt
| `- README.txt
|- libnx/
| `- README.txt
@@ -1590,9 +1592,7 @@ apps/
| | `- README.txt
| |- usbmsc
| | `- README.txt
- | |- zmodem
- | | `- README.txt
- | `- zoneinfo
+ | `- zmodem
| `- README.txt
`- README.txt
diff --git a/ReleaseNotes b/ReleaseNotes
index c760fca73723f71cf5a0ac0ae51f45a043ffefad..5afe3d5724e0f352a9149d8b9e7e674b1d0e8d8f 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -2570,7 +2570,7 @@ New features and extended functionality:
particular for a CDC/ACM with MSC USB composite driver).
Added a new RAM logging driver. This will allow debug output into
- a RAM buffer associated with a character driver at /dev/syslog.
+ a RAM buffer associated with a character driver at /dev/ramlog.
Added the new command 'dmesg' to NSH that can be used to dump the
current contents of the log. This is useful for systems that do not
have the usual serial console (for example, if you only have a
@@ -8991,7 +8991,7 @@ Additional new features and extended functionality:
* Applications: apps/system:
- - apps/system/zoneinfo: Add logic to build a ROMFS file system
+ - nuttx/zoneinfo: Add logic to build a ROMFS file system
containing the timezone data.
* Applications: apps/nshlib:
diff --git a/TODO b/TODO
index a4c960e2e18b5004b1242728731a7c3ee3caa424..bbc8f7657aca6a49d7c4c9b7c80807be22da7b0b 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-NuttX TODO List (Last updated June 6, 2016)
+NuttX TODO List (Last updated July 3, 2016)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with
@@ -17,7 +17,7 @@ nuttx/:
(9) Kernel/Protected Build
(3) C++ Support
(6) Binary loaders (binfmt/)
- (12) Network (net/, drivers/net)
+ (11) Network (net/, drivers/net)
(4) USB (drivers/usbdev, drivers/usbhost)
(0) Other drivers (drivers/)
(11) Libraries (libc/, libm/)
@@ -937,7 +937,9 @@ o Network (net/, drivers/net)
LM3S NO NO
TM4C YES YES
eZ80 NO NO
+ Kinetis YES YES (not tested)
LPC17xx YES YES (not tested)
+ LPC43xx YES YES (not tested)
DMxxx NIC NO NO
PIC32 NO NO
RGMP ??? ???
@@ -1352,12 +1354,6 @@ o File system / Generic drivers (fs/, drivers/)
Status: Open
Priority: Low
- Title: CAN POLL SUPPORT
- Description: At present, the CAN driver does not support the poll() method.
- See drivers/can.c
- Status: Open
- Priority: Low
-
Title: ROMFS CHECKSUMS
Description: The ROMFS file system does not verify checksums on either
volume header on on the individual files.
@@ -1602,7 +1598,7 @@ o Build system
Priority: Low.
Title: NATIVE WINDOWS BUILD BROKEN
- Description: The way that apps/ no generates Kmenu files depends on changes added
+ Description: The way that apps/ now generates Kmenu files depends on changes added
to apps/tools/mkkconfig.sh. Similar changes need to be made to
apps/tools/mkkconfig.bat to restore the Windows Native build.
UPDATE: The mkkconfig.bat script has been updated and appears to work.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f31f81277830e7249f328ecf6073c4173cc8e48a..87282302762904379c8769166c1f6c61508df6af 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -213,6 +213,7 @@ config ARCH_CHIP_SAMV7
select ARCH_HAVE_RAMFUNCS
select ARCH_HAVE_TICKLESS
select ARMV7M_HAVE_STACKCHECK
+ select ARCH_HAVE_I2CRESET
---help---
Atmel SAMV7 (ARM Cortex-M7) architectures
@@ -223,6 +224,7 @@ config ARCH_CHIP_STM32
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_I2CRESET
select ARCH_HAVE_HEAPCHECK
+ select ARCH_HAVE_TICKLESS
select ARMV7M_HAVE_STACKCHECK
---help---
STMicro STM32 architectures (ARM Cortex-M3/4).
@@ -249,6 +251,7 @@ config ARCH_CHIP_STM32L4
select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_I2CRESET
select ARCH_HAVE_HEAPCHECK
+ select ARCH_HAVE_TICKLESS
select ARMV7M_HAVE_STACKCHECK
---help---
STMicro STM32 architectures (ARM Cortex-M4).
diff --git a/arch/arm/include/kinetis/chip.h b/arch/arm/include/kinetis/chip.h
index dd8582e564fc8e78472ed6b53c9e4eaf200d10a1..f2fa5fbb4e707b0732f369f6a4d9e0e27dc9a117 100644
--- a/arch/arm/include/kinetis/chip.h
+++ b/arch/arm/include/kinetis/chip.h
@@ -1,7 +1,7 @@
/************************************************************************************
* arch/arm/include/kinetis/chip.h
*
- * Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2013, 2015-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -72,6 +72,7 @@
# define KINETIS_K20 1 /* Kinetics K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# undef KINETIS_K60 /* Not Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
#if defined(CONFIG_ARCH_CHIP_MK20DN32VLH5)
# define KINETIS_FLASH_SIZE (64*1024) /* 32Kb */
@@ -153,6 +154,7 @@
# define KINETIS_K20 1 /* Kinetics K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# undef KINETIS_K60 /* Not Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
#if defined(CONFIG_ARCH_CHIP_MK20DX64VLH7)
# define KINETIS_FLASH_SIZE (64*1024) /* 64Kb */
@@ -207,6 +209,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# define KINETIS_K40 1 /* Kinetics K40 family */
# undef KINETIS_K60 /* Not Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (64*1024) /* 64Kb */
# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */
# define KINETIS_SRAM_SIZE (16*1024) /* 16Kb */
@@ -257,6 +260,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# define KINETIS_K40 1 /* Kinetics K40 family */
# undef KINETIS_K60 /* Not Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (128*1024) /* 128Kb */
# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */
# define KINETIS_SRAM_SIZE (32*1024) /* 32Kb */
@@ -299,6 +303,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# define KINETIS_K40 1 /* Kinetics K40 family */
# undef KINETIS_K60 /* Not Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXMEM_SIZE (32*1024) /* 32Kb */
# define KINETIS_SRAM_SIZE (32*1024) /* 64Kb */
@@ -340,6 +345,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# define KINETIS_K40 1 /* Kinetics K40 family */
# undef KINETIS_K60 /* Not Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (128*1024) /* 128Kb */
# define KINETIS_FLEXMEM_SIZE (128*1024) /* 128Kb */
# define KINETIS_SRAM_SIZE (32*1024) /* 32Kb */
@@ -381,6 +387,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# define KINETIS_K40 1 /* Kinetics K40 family */
# undef KINETIS_K60 /* Not Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXMEM_SIZE (256*1024) /* 256Kb */
# define KINETIS_SRAM_SIZE (64*1024) /* 32Kb */
@@ -424,6 +431,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# define KINETIS_K40 1 /* Kinetics K40 family */
# undef KINETIS_K60 /* Not Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (512*1024) /* 512Kb */
# undef KINETIS_FLEXMEM_SIZE /* No FlexMemory */
# define KINETIS_SRAM_SIZE (128*1024) /* 128Kb */
@@ -465,6 +473,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */
# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */
@@ -509,6 +518,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXNVM_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXRAM_SIZE (4*1024) /* 32Kb */
@@ -553,6 +563,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (512*1024) /* 256Kb */
# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */
# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */
@@ -598,6 +609,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */
# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */
@@ -642,6 +654,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXNVM_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
@@ -686,6 +699,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (512*1024) /* 256Kb */
# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */
# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */
@@ -730,6 +744,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */
# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */
@@ -774,6 +789,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXNVM_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
@@ -818,6 +834,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (512*1024) /* 512Kb */
# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */
# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */
@@ -862,6 +879,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */
# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */
@@ -906,6 +924,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXNVM_SIZE (256*1024) /* 256Kb */
# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
@@ -950,6 +969,7 @@
# undef KINETIS_K20 /* Not Kinetis K20 family */
# undef KINETIS_K40 /* Not Kinetics K40 family */
# define KINETIS_K60 1 /* Kinetis K60 family */
+# undef KINETIS_K64 /* Not Kinetis K64 family */
# define KINETIS_FLASH_SIZE (512*1024) /* 512Kb */
# undef KINETIS_FLEXNVM_SIZE /* No FlexNVM */
# undef KINETIS_FLEXRAM_SIZE /* No FlexRAM */
@@ -990,6 +1010,278 @@
# undef KINETIS_NTAMPER /* No tamper detect */
# define KINETIS_NCRC 1 /* CRC */
+#elif defined(CONFIG_ARCH_CHIP_MK64FN1M0VLL12)
+# undef KINETIS_K20 /* Not Kinetics K20 family */
+# undef KINETIS_K40 /* Not Kinetics K40 family */
+# undef KINETIS_K60 /* Not Kinetis K60 family */
+# define KINETIS_K64 1 /* Kinetis K64 family */
+# define KINETIS_FLASH_SIZE (1024*1024) /* 1Mb */
+# define KINETIS_FLEXNVM_SIZE (0*1024) /* 0Kb */
+# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
+# define KINETIS_SRAM_SIZE (256*1024) /* 256Kb */
+# define KINETIS_MPU 1 /* Memory protection unit */
+# define KINETIS_EXTBUS 1 /* External bus interface */
+# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */
+# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */
+# define KINETIS_NUSBOTG 1 /* With USB OTG controller */
+# define KINETIS_NUSBDEV 1 /* One USB device controller */
+# define KINETIS_NSDHC 1 /* SD host controller */
+# define KINETIS_NI2C 3 /* Three I2C modules */
+# define KINETIS_NUART 6 /* Six UART modues */
+# define KINETIS_NSPI 3 /* Three SPI modules */
+# define KINETIS_NCAN 1 /* One CAN controllers */
+# define KINETIS_NI2S 1 /* One I2S modules */
+# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */
+# define KINETIS_NADC16 2 /* Four 16-bit ADC */
+# define KINETIS_NCMP 3 /* Three analog comparators */
+# define KINETIS_NDAC6 3 /* Three 6-bit DAC */
+# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
+# define KINETIS_NVREF 1 /* Voltage reference */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel timers */
+# define KINETIS_NRTC 1 /* Real time clock */
+# define KINETIS_NRNG 1 /* Random number generator */
+# define KINETIS_NMMCAU 1 /* Hardware encryption */
+# define KINETIS_NCRC 1 /* CRC */
+
+#elif defined(CONFIG_ARCH_CHIP_MK64FX512VLL12)
+# undef KINETIS_K20 /* Not Kinetics K20 family */
+# undef KINETIS_K40 /* Not Kinetics K40 family */
+# undef KINETIS_K60 /* Not Kinetis K60 family */
+# define KINETIS_K64 1 /* Kinetis K64 family */
+# define KINETIS_FLASH_SIZE (1024*1024) /* 1Mb */
+# define KINETIS_FLEXNVM_SIZE (0*1024) /* 0Kb */
+# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
+# define KINETIS_SRAM_SIZE (256*1024) /* 256Kb */
+# define KINETIS_MPU 1 /* Memory protection unit */
+# define KINETIS_EXTBUS 1 /* External bus interface */
+# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */
+# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */
+# define KINETIS_NUSBOTG 1 /* With USB OTG controller */
+# define KINETIS_NUSBDEV 1 /* One USB device controller */
+# define KINETIS_NSDHC 1 /* SD host controller */
+# define KINETIS_NI2C 3 /* Three I2C modules */
+# define KINETIS_NUART 6 /* Six UART modues */
+# define KINETIS_NSPI 3 /* Three SPI modules */
+# define KINETIS_NCAN 1 /* One CAN controllers */
+# define KINETIS_NI2S 1 /* One I2S modules */
+# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */
+# define KINETIS_NADC16 2 /* Four 16-bit ADC */
+# define KINETIS_NCMP 3 /* Three analog comparators */
+# define KINETIS_NDAC6 3 /* Three 6-bit DAC */
+# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
+# define KINETIS_NVREF 1 /* Voltage reference */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel timers */
+# define KINETIS_NRTC 1 /* Real time clock */
+# define KINETIS_NRNG 1 /* Random number generator */
+# define KINETIS_NMMCAU 1 /* Hardware encryption */
+# define KINETIS_NCRC 1 /* CRC */
+
+#elif defined(CONFIG_ARCH_CHIP_MK64FX512VDC12)
+# undef KINETIS_K20 /* Not Kinetics K20 family */
+# undef KINETIS_K40 /* Not Kinetics K40 family */
+# undef KINETIS_K60 /* Not Kinetis K60 family */
+# define KINETIS_K64 1 /* Kinetis K64 family */
+# define KINETIS_FLASH_SIZE (1024*1024) /* 1Mb */
+# define KINETIS_FLEXNVM_SIZE (0*1024) /* 0Kb */
+# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
+# define KINETIS_SRAM_SIZE (256*1024) /* 256Kb */
+# define KINETIS_MPU 1 /* Memory protection unit */
+# define KINETIS_EXTBUS 1 /* External bus interface */
+# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */
+# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */
+# define KINETIS_NUSBOTG 1 /* With USB OTG controller */
+# define KINETIS_NUSBDEV 1 /* One USB device controller */
+# define KINETIS_NSDHC 1 /* SD host controller */
+# define KINETIS_NI2C 3 /* Three I2C modules */
+# define KINETIS_NUART 6 /* Six UART modues */
+# define KINETIS_NSPI 3 Three SPI modules
+# define KINETIS_NCAN 1 /* One CAN controllers */
+# define KINETIS_NI2S 1 /* One I2S modules */
+# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */
+# define KINETIS_NADC16 2 /* Four 16-bit ADC */
+# define KINETIS_NCMP 3 /* Three analog comparators */
+# define KINETIS_NDAC6 3 /* Three 6-bit DAC */
+# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
+# define KINETIS_NVREF 1 /* Voltage reference */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel timers */
+# define KINETIS_NRTC 1 /* Real time clock */
+# define KINETIS_NRNG 1 /* Random number generator */
+# define KINETIS_NMMCAU 1 /* Hardware encryption */
+# define KINETIS_NCRC 1 /* CRC */
+
+#elif defined(CONFIG_ARCH_CHIP_MK64FN1M0VDC12)
+# undef KINETIS_K20 /* Not Kinetics K20 family */
+# undef KINETIS_K40 /* Not Kinetics K40 family */
+# undef KINETIS_K60 /* Not Kinetis K60 family */
+# define KINETIS_K64 1 /* Kinetis K64 family */
+# define KINETIS_FLASH_SIZE (1024*1024) /* 1Mb */
+# define KINETIS_FLEXNVM_SIZE (0*1024) /* 0Kb */
+# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
+# define KINETIS_SRAM_SIZE (256*1024) /* 256Kb */
+# define KINETIS_MPU 1 /* Memory protection unit */
+# define KINETIS_EXTBUS 1 /* External bus interface */
+# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */
+# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */
+# define KINETIS_NUSBOTG 1 /* With USB OTG controller */
+# define KINETIS_NUSBDEV 1 /* One USB device controller */
+# define KINETIS_NSDHC 1 /* SD host controller */
+# define KINETIS_NI2C 3 /* Three I2C modules */
+# define KINETIS_NUART 6 /* Six UART modues */
+# define KINETIS_NSPI 3 Three SPI modules
+# define KINETIS_NCAN 1 /* One CAN controllers */
+# define KINETIS_NI2S 1 /* One I2S modules */
+# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */
+# define KINETIS_NADC16 2 /* Four 16-bit ADC */
+# define KINETIS_NCMP 3 /* Three analog comparators */
+# define KINETIS_NDAC6 3 /* Three 6-bit DAC */
+# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
+# define KINETIS_NVREF 1 /* Voltage reference */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel timers */
+# define KINETIS_NRTC 1 /* Real time clock */
+# define KINETIS_NRNG 1 /* Random number generator */
+# define KINETIS_NMMCAU 1 /* Hardware encryption */
+# define KINETIS_NCRC 1 /* CRC */
+
+#elif defined(CONFIG_ARCH_CHIP_MK64FX512VLQ12)
+# undef KINETIS_K20 /* Not Kinetics K20 family */
+# undef KINETIS_K40 /* Not Kinetics K40 family */
+# undef KINETIS_K60 /* Not Kinetis K60 family */
+# define KINETIS_K64 1 /* Kinetis K64 family */
+# define KINETIS_FLASH_SIZE (1024*1024) /* 1Mb */
+# define KINETIS_FLEXNVM_SIZE (0*1024) /* 0Kb */
+# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
+# define KINETIS_SRAM_SIZE (256*1024) /* 256Kb */
+# define KINETIS_MPU 1 /* Memory protection unit */
+# define KINETIS_EXTBUS 1 /* External bus interface */
+# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */
+# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */
+# define KINETIS_NUSBOTG 1 /* With USB OTG controller */
+# define KINETIS_NUSBDEV 1 /* One USB device controller */
+# define KINETIS_NSDHC 1 /* SD host controller */
+# define KINETIS_NI2C 3 /* Three I2C modules */
+# define KINETIS_NUART 6 /* Six UART modues */
+# define KINETIS_NSPI 3 /* Three SPI modules */
+# define KINETIS_NCAN 1 /* One CAN controllers */
+# define KINETIS_NI2S 1 /* One I2S modules */
+# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */
+# define KINETIS_NADC16 2 /* Four 16-bit ADC */
+# define KINETIS_NCMP 3 /* Three analog comparators */
+# define KINETIS_NDAC6 3 /* Three 6-bit DAC */
+# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
+# define KINETIS_NVREF 1 /* Voltage reference */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel timers */
+# define KINETIS_NRTC 1 /* Real time clock */
+# define KINETIS_NRNG 1 /* Random number generator */
+# define KINETIS_NMMCAU 1 /* Hardware encryption */
+# define KINETIS_NCRC 1 /* CRC */
+
+#elif defined(CONFIG_ARCH_CHIP_MK64FN1M0VLQ12)
+# undef KINETIS_K20 /* Not Kinetics K20 family */
+# undef KINETIS_K40 /* Not Kinetics K40 family */
+# undef KINETIS_K60 /* Not Kinetis K60 family */
+# define KINETIS_K64 1 /* Kinetis K64 family */
+# define KINETIS_FLASH_SIZE (1024*1024) /* 1Mb */
+# define KINETIS_FLEXNVM_SIZE (0*1024) /* 0Kb */
+# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
+# define KINETIS_SRAM_SIZE (256*1024) /* 256Kb */
+# define KINETIS_MPU 1 /* Memory protection unit */
+# define KINETIS_EXTBUS 1 /* External bus interface */
+# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */
+# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */
+# define KINETIS_NUSBOTG 1 /* With USB OTG controller */
+# define KINETIS_NUSBDEV 1 /* One USB device controller */
+# define KINETIS_NSDHC 1 /* SD host controller */
+# define KINETIS_NI2C 3 /* Three I2C modules */
+# define KINETIS_NUART 6 /* Six UART modues */
+# define KINETIS_NSPI 3 /* Three SPI modules */
+# define KINETIS_NCAN 1 /* One CAN controllers */
+# define KINETIS_NI2S 1 /* One I2S modules */
+# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */
+# define KINETIS_NADC16 2 /* Four 16-bit ADC */
+# define KINETIS_NCMP 3 /* Three analog comparators */
+# define KINETIS_NDAC6 3 /* Three 6-bit DAC */
+# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
+# define KINETIS_NVREF 1 /* Voltage reference */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel timers */
+# define KINETIS_NRTC 1 /* Real time clock */
+# define KINETIS_NRNG 1 /* Random number generator */
+# define KINETIS_NMMCAU 1 /* Hardware encryption */
+# define KINETIS_NCRC 1 /* CRC */
+
+#elif defined(CONFIG_ARCH_CHIP_MK64FX512VMD12)
+# undef KINETIS_K20 /* Not Kinetics K20 family */
+# undef KINETIS_K40 /* Not Kinetics K40 family */
+# undef KINETIS_K60 /* Not Kinetis K60 family */
+# define KINETIS_K64 1 /* Kinetis K64 family */
+# define KINETIS_FLASH_SIZE (1024*1024) /* 1Mb */
+# define KINETIS_FLEXNVM_SIZE (0*1024) /* 0Kb */
+# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
+# define KINETIS_SRAM_SIZE (256*1024) /* 256Kb */
+# define KINETIS_MPU 1 /* Memory protection unit */
+# define KINETIS_EXTBUS 1 /* External bus interface */
+# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */
+# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */
+# define KINETIS_NUSBOTG 1 /* With USB OTG controller */
+# define KINETIS_NUSBDEV 1 /* One USB device controller */
+# define KINETIS_NSDHC 1 /* SD host controller */
+# define KINETIS_NI2C 3 /* Three I2C modules */
+# define KINETIS_NUART 6 /* Six UART modues */
+# define KINETIS_NSPI 3 /* Three SPI modules */
+# define KINETIS_NCAN 1 /* One CAN controllers */
+# define KINETIS_NI2S 1 /* One I2S modules */
+# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */
+# define KINETIS_NADC16 2 /* Four 16-bit ADC */
+# define KINETIS_NCMP 3 /* Three analog comparators */
+# define KINETIS_NDAC6 3 /* Three 6-bit DAC */
+# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
+# define KINETIS_NVREF 1 /* Voltage reference */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel timers */
+# define KINETIS_NRTC 1 /* Real time clock */
+# define KINETIS_NRNG 1 /* Random number generator */
+# define KINETIS_NMMCAU 1 /* Hardware encryption */
+# define KINETIS_NCRC 1 /* CRC */
+
+#elif defined(CONFIG_ARCH_CHIP_MK64FN1M0VMD12)
+# undef KINETIS_K20 /* Not Kinetics K20 family */
+# undef KINETIS_K40 /* Not Kinetics K40 family */
+# undef KINETIS_K60 /* Not Kinetis K60 family */
+# define KINETIS_K64 1 /* Kinetis K64 family */
+# define KINETIS_FLASH_SIZE (1024*1024) /* 1Mb */
+# define KINETIS_FLEXNVM_SIZE (0*1024) /* 0Kb */
+# define KINETIS_FLEXRAM_SIZE (4*1024) /* 4Kb */
+# define KINETIS_SRAM_SIZE (256*1024) /* 256Kb */
+# define KINETIS_MPU 1 /* Memory protection unit */
+# define KINETIS_EXTBUS 1 /* External bus interface */
+# define KINETIS_NDMACH 16 /* Up to 16 DMA channels */
+# define KINETIS_NENET 1 /* One IEEE 1588 Ethernet controller */
+# define KINETIS_NUSBOTG 1 /* With USB OTG controller */
+# define KINETIS_NUSBDEV 1 /* One USB device controller */
+# define KINETIS_NSDHC 1 /* SD host controller */
+# define KINETIS_NI2C 3 /* Three I2C modules */
+# define KINETIS_NUART 6 /* Six UART modues */
+# define KINETIS_NSPI 3 /* Three SPI modules */
+# define KINETIS_NCAN 1 /* One CAN controllers */
+# define KINETIS_NI2S 1 /* One I2S modules */
+# define KINETIS_NSLCD 1 /* One segment LCD interface (up to 36x8/40x4) */
+# define KINETIS_NADC16 2 /* Four 16-bit ADC */
+# define KINETIS_NCMP 3 /* Three analog comparators */
+# define KINETIS_NDAC6 3 /* Three 6-bit DAC */
+# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
+# define KINETIS_NVREF 1 /* Voltage reference */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel timers */
+# define KINETIS_NRTC 1 /* Real time clock */
+# define KINETIS_NRNG 1 /* Random number generator */
+# define KINETIS_NMMCAU 1 /* Hardware encryption */
+# define KINETIS_NCRC 1 /* CRC */
+
#else
# error "Unsupported Kinetis chip"
#endif
diff --git a/arch/arm/include/kinetis/irq.h b/arch/arm/include/kinetis/irq.h
index 16b59ab8ae96fc4054e91e16ac849c0cb2f2293f..1e45a5b4c63be0f1c6ee3cd1a5009fb165f02885 100644
--- a/arch/arm/include/kinetis/irq.h
+++ b/arch/arm/include/kinetis/irq.h
@@ -83,7 +83,7 @@
* K20P64M72SF1RM
*/
-#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7)
+#if defined(CONFIG_ARCH_FAMILY_K20)
# define KINETIS_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */
# define KINETIS_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */
# define KINETIS_IRQ_DMACH2 (18) /* Vector 18: DMA channel 2 transfer complete */
@@ -162,9 +162,7 @@
* K40P144M100SF2RM
*/
-#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100)
+#elif defined(CONFIG_ARCH_FAMILY_K40)
# define KINETIS_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */
# define KINETIS_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */
@@ -274,10 +272,7 @@
* K60P144M100SF2RM
*/
-#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \
- defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK60N512VLL100)
+#elif defined(CONFIG_ARCH_FAMILY_K60)
# define KINETIS_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */
# define KINETIS_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */
@@ -383,6 +378,105 @@
# define NR_VECTORS (120) /* 120 vectors */
# define NR_IRQS (108) /* 120 interrupts but 108 IRQ numbers */
+/* K64 Family ***********************************************************************
+ *
+ * The memory map for the following parts is defined in NXP document
+ * K64P144M120SF5RM.pdf
+ */
+
+#elif defined(CONFIG_ARCH_FAMILY_K64)
+
+# define KINETIS_IRQ_DMACH0 (16) /* Vector 16: DMA channel 0 transfer complete */
+# define KINETIS_IRQ_DMACH1 (17) /* Vector 17: DMA channel 1 transfer complete */
+# define KINETIS_IRQ_DMACH2 (18) /* Vector 18: DMA channel 2 transfer complete */
+# define KINETIS_IRQ_DMACH3 (19) /* Vector 19: DMA channel 3 transfer complete */
+# define KINETIS_IRQ_DMACH4 (20) /* Vector 20: DMA channel 4 transfer complete */
+# define KINETIS_IRQ_DMACH5 (21) /* Vector 21: DMA channel 5 transfer complete */
+# define KINETIS_IRQ_DMACH6 (22) /* Vector 22: DMA channel 6 transfer complete */
+# define KINETIS_IRQ_DMACH7 (23) /* Vector 23: DMA channel 7 transfer complete */
+# define KINETIS_IRQ_DMACH8 (24) /* Vector 24: DMA channel 8 transfer complete */
+# define KINETIS_IRQ_DMACH9 (25) /* Vector 25: DMA channel 9 transfer complete */
+# define KINETIS_IRQ_DMACH10 (26) /* Vector 26: DMA channel 10 transfer complete */
+# define KINETIS_IRQ_DMACH11 (27) /* Vector 27: DMA channel 11 transfer complete */
+# define KINETIS_IRQ_DMACH12 (28) /* Vector 28: DMA channel 12 transfer complete */
+# define KINETIS_IRQ_DMACH13 (29) /* Vector 29: DMA channel 13 transfer complete */
+# define KINETIS_IRQ_DMACH14 (30) /* Vector 30: DMA channel 14 transfer complete */
+# define KINETIS_IRQ_DMACH15 (31) /* Vector 31: DMA channel 15 transfer complete */
+# define KINETIS_IRQ_DMAERR (32) /* Vector 32: DMA error interrupt channels 0-15 */
+# define KINETIS_IRQ_MCM (33) /* Vector 33: MCM Normal interrupt */
+# define KINETIS_IRQ_FLASHCC (34) /* Vector 34: Flash memory command complete */
+# define KINETIS_IRQ_FLASHRC (35) /* Vector 35: Flash memory read collision */
+# define KINETIS_IRQ_SMCLVD (36) /* Vector 36: Mode Controller low-voltage
+ * detect, low-voltage warning */
+# define KINETIS_IRQ_LLWU (37) /* Vector 37: LLWU Normal Low Leakage Wakeup */
+# define KINETIS_IRQ_WDOG (38) /* Vector 38: Watchdog */
+# define KINETIS_IRQ_RNGB (39) /* Vector 39: Random number generator */
+# define KINETIS_IRQ_I2C0 (40) /* Vector 40: I2C0 */
+# define KINETIS_IRQ_I2C1 (41) /* Vector 41: I2C1 */
+# define KINETIS_IRQ_SPI0 (42) /* Vector 42: SPI0 all sources */
+# define KINETIS_IRQ_SPI1 (43) /* Vector 43: SPI1 all sources */
+# define KINETIS_IRQ_I2S0 (44) /* Vector 44: Transmit */
+# define KINETIS_IRQ_I2S1 (45) /* Vector 45: Transmit */
+ /* Vector 46: Reserved */
+# define KINETIS_IRQ_UART0S (47) /* Vector 47: UART0 status */
+# define KINETIS_IRQ_UART0E (48) /* Vector 48: UART0 error */
+# define KINETIS_IRQ_UART1S (49) /* Vector 49: UART1 status */
+# define KINETIS_IRQ_UART1E (50) /* Vector 50: UART1 error */
+# define KINETIS_IRQ_UART2S (51) /* Vector 51: UART2 status */
+# define KINETIS_IRQ_UART2E (52) /* Vector 52: UART2 error */
+# define KINETIS_IRQ_UART3S (53) /* Vector 53: UART3 status */
+# define KINETIS_IRQ_UART3E (54) /* Vector 54: UART3 error */
+# define KINETIS_IRQ_ADC0 (55) /* Vector 55: ADC0 */
+# define KINETIS_IRQ_CMP0 (56) /* Vector 56: CMP0 */
+# define KINETIS_IRQ_CMP1 (57) /* Vector 57: CMP1 */
+# define KINETIS_IRQ_FTM0 (58) /* Vector 58: FTM0 all sources */
+# define KINETIS_IRQ_FTM1 (59) /* Vector 59: FTM1 all sources */
+# define KINETIS_IRQ_FTM2 (60) /* Vector 60: FTM2 all sources */
+# define KINETIS_IRQ_CMT (61) /* Vector 61: CMT */
+# define KINETIS_IRQ_RTC0 (62) /* Vector 62: RTC alarm interrupt */
+# define KINETIS_IRQ_RTC1 (63) /* Vector 63: RTC seconds interrupt */
+# define KINETIS_IRQ_PITCH0 (64) /* Vector 64: PIT channel 0 */
+# define KINETIS_IRQ_PITCH1 (65) /* Vector 65: PIT channel 1 */
+# define KINETIS_IRQ_PITCH2 (66) /* Vector 66: PIT channel 2 */
+# define KINETIS_IRQ_PITCH3 (67) /* Vector 67: PIT channel 3 */
+# define KINETIS_IRQ_PDB (68) /* Vector 68: PDB */
+# define KINETIS_IRQ_USBOTG (69) /* Vector 68: USB OTG */
+# define KINETIS_IRQ_USBCD (70) /* Vector 70: USB charger detect */
+ /* Vector 71: Reserved */
+# define KINETIS_IRQ_DAC0 (72) /* Vector 72: DAC0 */
+# define KINETIS_IRQ_MCG (73) /* Vector 73: MCG */
+# define KINETIS_IRQ_LPT (74) /* Vector 74: Low power timer */
+# define KINETIS_IRQ_PORTA (75) /* Vector 75: Pin detect port A */
+# define KINETIS_IRQ_PORTB (76) /* Vector 76: Pin detect port B */
+# define KINETIS_IRQ_PORTC (77) /* Vector 77: Pin detect port C */
+# define KINETIS_IRQ_PORTD (78) /* Vector 78: Pin detect port D */
+# define KINETIS_IRQ_PORTE (79) /* Vector 79: Pin detect port E */
+# define KINETIS_IRQ_SOFTWARE (80) /* Vector 80: Software interrupt */
+# define KINETIS_IRQ_SPI2 (81) /* Vector 81: SPI2 all sources */
+# define KINETIS_IRQ_UART4S (82) /* Vector 82: UART4 status */
+# define KINETIS_IRQ_UART4E (83) /* Vector 83: UART4 error */
+# define KINETIS_IRQ_UART5S (84) /* Vector 84: UART5 status */
+# define KINETIS_IRQ_UART5E (85) /* Vector 85: UART5 error */
+# define KINETIS_IRQ_CMP2 (86) /* Vector 86: CMP2 */
+# define KINETIS_IRQ_FTM3 (87) /* Vector 87: FTM3 all sources */
+# define KINETIS_IRQ_DAC1 (88) /* Vector 88: DAC1 */
+# define KINETIS_IRQ_ADC1 (89) /* Vector 89: ADC1 */
+# define KINETIS_IRQ_I2C2 (90) /* Vector 90: I2C2 */
+# define KINETIS_IRQ_CAN0MB (91) /* Vector 91: CAN0 OR'ed Message buffer (0-15) */
+# define KINETIS_IRQ_CAN0BO (92) /* Vector 92: CAN0 Bus Off */
+# define KINETIS_IRQ_CAN0ERR (93) /* Vector 93: CAN0 Error */
+# define KINETIS_IRQ_CAN0TW (94) /* Vector 94: CAN0 Transmit Warning */
+# define KINETIS_IRQ_CAN0RW (95) /* Vector 95: CAN0 Receive Warning */
+# define KINETIS_IRQ_CAN0WU (96) /* Vector 96: CAN0 Wake UP */
+# define KINETIS_IRQ_SDHC (97) /* Vector 97: SDHC */
+# define KINETIS_IRQ_EMACTMR (98) /* Vector 91: Ethernet MAC IEEE 1588 timer interrupt */
+# define KINETIS_IRQ_EMACTX (99) /* Vector 92: Ethernet MAC transmit interrupt */
+# define KINETIS_IRQ_EMACRX (100) /* Vector 93: Ethernet MAC receive interrupt */
+# define KINETIS_IRQ_EMACMISC (101) /* Vector 94: Ethernet MAC error and misc interrupt */
+
+# define NR_VECTORS (102) /* 102 vectors */
+# define NR_IRQS (102) /* 85 interrupts but 102 IRQ numbers */
+
#else
/* The interrupt vectors for other parts are defined in other documents and may or
* may not be the same as above (the family members are all very similar) This
diff --git a/arch/arm/src/common/up_checkstack.c b/arch/arm/src/common/up_checkstack.c
index 55f89388e3ee983d72ce5ccabdf23acb71677733..f6b4034cbcb588c62a5e1d970d956c5573b9667d 100644
--- a/arch/arm/src/common/up_checkstack.c
+++ b/arch/arm/src/common/up_checkstack.c
@@ -84,7 +84,13 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
FAR uint32_t *ptr;
size_t mark;
+ if (size == 0)
+ {
+ return 0;
+ }
+
/* Get aligned addresses of the top and bottom of the stack */
+
#ifdef CONFIG_TLS
/* Skip over the TLS data structure at the bottom of the stack */
@@ -122,7 +128,8 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
#if 0
if (mark + 16 > nwords)
{
- int i, j;
+ int i;
+ int j;
ptr = (FAR uint32_t *)start;
for (i = 0; i < size; i += 4*64)
diff --git a/arch/arm/src/efm32/efm32_irq.c b/arch/arm/src/efm32/efm32_irq.c
index 63fa4b18ec7bc2e873cfeb0a8a91215691797480..63a82b194ca197d4eb01c373a90e562667a0e7e2 100644
--- a/arch/arm/src/efm32/efm32_irq.c
+++ b/arch/arm/src/efm32/efm32_irq.c
@@ -251,61 +251,25 @@ static inline void efm32_prioritize_syscall(int priority)
static int efm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit,
uintptr_t offset)
{
+ int n;
+
DEBUGASSERT(irq >= EFM32_IRQ_NMI && irq < NR_IRQS);
- /* Check for external interrupt or (a second level GPIO interrupt) */
+ /* Check for external interrupt or a second level GPIO interrupt */
if (irq >= EFM32_IRQ_INTERRUPTS)
{
- /* Is this an external interrupt? */
-
if (irq < NR_VECTORS)
{
- /* Yes.. We have support implemented for vectors 0-95 */
-
- DEBUGASSERT(irq < (EFM32_IRQ_INTERRUPTS + 96));
-
-#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32)
- /* Check for vectors 0-31 */
-
- if (irq < EFM32_IRQ_INTERRUPTS + 32)
-#endif
- {
- *regaddr = (NVIC_IRQ0_31_ENABLE + offset);
- *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS);
- }
-#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32)
- /* Yes.. Check for vectors 32-63 */
+ n = irq - EFM32_IRQ_INTERRUPTS;
+ *regaddr = NVIC_IRQ_ENABLE(n) + offset;
- else
-#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64)
- if (irq < EFM32_IRQ_INTERRUPTS + 64)
-#endif
+ while (n >= 32)
{
- *regaddr = (NVIC_IRQ32_63_ENABLE + offset);
- *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS - 32);
+ n -= 32;
}
-#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64)
- /* Yes.. Check for vectors 64-95 */
-
- else
-#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 96)
- /* Yes.. Check for vectors 64-95 */
- if (irq < NR_VECTORS)
-#endif
- {
- *regaddr = (NVIC_IRQ64_95_ENABLE + offset);
- *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS - 64);
- }
-#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 96)
- else
- {
- return -EINVAL; /* We should never get here */
- }
-#endif
-#endif
-#endif
+ *bit = 1 << n;
}
else
{
@@ -356,16 +320,14 @@ void up_irqinitialize(void)
{
uint32_t regaddr;
int num_priority_registers;
+ int i;
/* Disable all interrupts */
- putreg32(0, NVIC_IRQ0_31_ENABLE);
-#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32)
- putreg32(0, NVIC_IRQ32_63_ENABLE);
-#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64)
- putreg32(0, NVIC_IRQ64_95_ENABLE);
-#endif
-#endif
+ for (i = 0; i < NR_VECTORS - EFM32_IRQ_INTERRUPTS; i += 32)
+ {
+ putreg32(0xffffffff, NVIC_IRQ_CLEAR(i));
+ }
#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3
/* Colorize the interrupt stack for debug purposes */
diff --git a/arch/arm/src/kinetis/Kconfig b/arch/arm/src/kinetis/Kconfig
index 5710c2d32ce6c7e4067fcc53e430f3aa734dde0b..6a0c0367657d1403751286306c39b2bc575c646f 100644
--- a/arch/arm/src/kinetis/Kconfig
+++ b/arch/arm/src/kinetis/Kconfig
@@ -98,6 +98,34 @@ config ARCH_CHIP_MK60X256VMD100
bool "MK60X256VMD100"
select ARCH_FAMILY_K60
+config ARCH_CHIP_MK64FN1M0VLL12
+ bool "MK64FN1M0VLL12"
+ select ARCH_FAMILY_K64
+
+config ARCH_CHIP_MK64FX512VLL12
+ bool "MK64FX512VLL12"
+ select ARCH_FAMILY_K64
+
+config ARCH_CHIP_MK64FX512VDC12
+ bool "MK64FX512VDC12"
+ select ARCH_FAMILY_K64
+
+config ARCH_CHIP_MK64FN1M0VDC12
+ bool "MK64FN1M0VDC12"
+ select ARCH_FAMILY_K64
+
+config ARCH_CHIP_MK64FX512VLQ12
+ bool "MK64FX512VLQ12"
+ select ARCH_FAMILY_K64
+
+config ARCH_CHIP_MK64FX512VMD12
+ bool "MK64FX512VMD12"
+ select ARCH_FAMILY_K64
+
+config ARCH_CHIP_MK64FN1M0VMD12
+ bool "MK64FN1M0VMD12"
+ select ARCH_FAMILY_K64
+
endchoice
# Chip families
@@ -114,6 +142,10 @@ config ARCH_FAMILY_K60
bool
default n
+config ARCH_FAMILY_K64
+ bool
+ default n
+
menu "Kinetis Peripheral Support"
config KINETIS_TRACE
@@ -173,19 +205,22 @@ config KINETIS_UART5
config KINETIS_ENET
bool "Ethernet"
default n
- depends on ARCH_FAMILY_K60
- select NET
+ depends on ARCH_FAMILY_K60 || ARCH_FAMILY_K64
+ select ARCH_HAVE_PHY
select ARCH_HAVE_NETDEV_STATISTICS
+ select NET
+ select NETDEVICES
+ select NET_MULTIBUFFER
---help---
- Support Ethernet (K60 only)
+ Support Ethernet (K6x only)
config KINETIS_RNGB
bool "Random number generator"
default n
- depends on ARCH_FAMILY_K60
+ depends on ARCH_FAMILY_K60 || ARCH_FAMILY_K64
select ARCH_HAVE_RNG
---help---
- Support the random number generator(K60 only)
+ Support the random number generator(K6x only)
config KINETIS_FLEXCAN0
bool "FlexCAN0"
@@ -446,7 +481,7 @@ config KINETIS_FTM2_CHANNEL
If FTM2 is enabled for PWM usage, you also need specifies the timer output
channel {0,..,1}
-comment "Kinetis GPIO Interrupt Configuration"
+menu "Kinetis GPIO Interrupt Configuration"
config GPIO_IRQ
bool "GPIO pin interrupts"
@@ -481,55 +516,63 @@ config KINETIS_PORTEINTS
Enable support for 32 interrupts from GPIO port E pins
endif
+endmenu # Kinetis GPIO Interrupt Configuration
-if KINETIS_ENET
+menu "Kinetis Ethernet Configuration"
+ depends on KINETIS_ENET
-comment "Kinetis Ethernet Configuration"
-
-config ENET_ENHANCEDBD
+config KINETIS_ENETENHANCEDBD
bool "Use enhanced buffer descriptors"
default n
---help---
Use enhanced, 32-byte buffer descriptors
-config ENET_NETHIFS
+config KINETIS_ENETNETHIFS
int "Number of Ethernet interfaces"
default 1
---help---
Number of Ethernet interfaces supported by the hardware. Must be
one for now.
-config ENET_NRXBUFFERS
+config KINETIS_ENETNRXBUFFERS
int "Number of Ethernet Rx buffers"
default 6
---help---
Number of Ethernet Rx buffers to use. The size of one buffer is
determined by NET_BUFSIZE
-config ENET_NTXBUFFERS
+config KINETIS_ENETNTXBUFFERS
int "Number of Ethernet Tx buffers"
default 2
---help---
Number of Ethernet Tx buffers to use. The size of one buffer is
determined by NET_BUFSIZE
-config ENET_PHYADDR
- int "PHY address"
- default 1
- ---help---
- MII/RMII address of the PHY
-
-config ENET_USEMII
+config KINETIS_ENETUSEMII
bool "Use MII interface"
default n
---help---
The the MII PHY interface. Default: Use RMII interface
-endif
+config KINETIS_ENET_MDIOPULLUP
+ bool "MDIO pull-up"
+ default n
+ ---help---
+ If there is no on-board pull-up resister on the MII/RMII MDIO line,
+ then this option may be selected in order to configure an internal
+ pull-up on MDIO.
+
+config KINETIS_ENET_NORXER
+ bool "Suppress RXER"
+ default n
+ ---help---
+ If selected, then the MII/RMII RXER output will be configured as a
+ GPIO and pulled low.
-if KINETIS_SDHC
+endmenu # Kinetis Ethernet Configuration
-comment "Kinetis SDHC Configuration"
+menu "Kinetis SDHC Configuration"
+ depends on KINETIS_SDHC
config KINETIS_SDHC_ABSFREQ
bool "Custom transfer frequencies"
@@ -579,11 +622,13 @@ config KINETIS_SDHC_DMAPRIO
---help---
SDHC DMA priority
-endif
+endmenu # Kinetis SDHC Configuration
-comment "Kinetis UART Configuration"
+menu "Kinetis UART Configuration"
config KINETIS_UARTFIFOS
bool "Enable UART0 FIFO"
default n
depends on KINETIS_UART0
+
+endmenu # Kinetis UART Configuration
diff --git a/arch/arm/src/kinetis/chip.h b/arch/arm/src/kinetis/chip.h
index 0ed152bac2f52203fe3ac39ebe4a6a48b6eac622..26fa7e38a0daaed85b59748db1c91cf6a1ba7ac1 100644
--- a/arch/arm/src/kinetis/chip.h
+++ b/arch/arm/src/kinetis/chip.h
@@ -47,7 +47,7 @@
*/
#include
-#include "kinetis_memorymap.h"
+#include "chip/kinetis_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/kinetis/kinetis_adc.h b/arch/arm/src/kinetis/chip/kinetis_adc.h
similarity index 93%
rename from arch/arm/src/kinetis/kinetis_adc.h
rename to arch/arm/src/kinetis/chip/kinetis_adc.h
index a17aa06c7f4274ca8a612e933cafec3c43c9bd71..6b3b74fa9c32c51efdddcaa71d5b4bd7bbbbe0c7 100644
--- a/arch/arm/src/kinetis/kinetis_adc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_adc.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_adc.h
+ * arch/arm/src/kinetis/chip/kinetis_adc.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_ADC_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_ADC_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_ADC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_ADC_H
/********************************************************************************************
* Included Files
@@ -70,7 +70,9 @@
#define KINETIS_ADC_CLP2_OFFSET 0x0044 /* ADC plus-side general calibration value register */
#define KINETIS_ADC_CLP1_OFFSET 0x0048 /* ADC plus-side general calibration value register */
#define KINETIS_ADC_CLP0_OFFSET 0x004c /* ADC plus-side general calibration value register */
-#define KINETIS_ADC_PGA_OFFSET 0x0050 /* ADC PGA register */
+#ifndef KINETIS_K64
+# define KINETIS_ADC_PGA_OFFSET 0x0050 /* ADC PGA register */
+#endif
#define KINETIS_ADC_CLMD_OFFSET 0x0054 /* ADC minus-side general calibration value register */
#define KINETIS_ADC_CLMS_OFFSET 0x0058 /* ADC minus-side general calibration value register */
#define KINETIS_ADC_CLM4_OFFSET 0x005c /* ADC minus-side general calibration value register */
@@ -80,7 +82,7 @@
#define KINETIS_ADC_CLM0_OFFSET 0x006c /* ADC minus-side general calibration value register */
/* Register Addresses ***********************************************************************/
-# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
+# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
#define KINETIS_ADC0_SC1A (KINETIS_ADC0_BASE+KINETIS_ADC_SC1A_OFFSET)
#define KINETIS_ADC0_SC1B (KINETIS_ADC0_BASE+KINETIS_ADC_SC1B_OFFSET)
@@ -102,7 +104,9 @@
#define KINETIS_ADC0_CLP2 (KINETIS_ADC0_BASE+KINETIS_ADC_CLP2_OFFSET)
#define KINETIS_ADC0_CLP1 (KINETIS_ADC0_BASE+KINETIS_ADC_CLP1_OFFSET)
#define KINETIS_ADC0_CLP0 (KINETIS_ADC0_BASE+KINETIS_ADC_CLP0_OFFSET)
-#define KINETIS_ADC0_PGA (KINETIS_ADC0_BASE+KINETIS_ADC_PGA_OFFSET)
+#ifndef KINETIS_K64
+# define KINETIS_ADC0_PGA (KINETIS_ADC0_BASE+KINETIS_ADC_PGA_OFFSET)
+#endif
#define KINETIS_ADC0_CLMD (KINETIS_ADC0_BASE+KINETIS_ADC_CLMD_OFFSET)
#define KINETIS_ADC0_CLMS (KINETIS_ADC0_BASE+KINETIS_ADC_CLMS_OFFSET)
#define KINETIS_ADC0_CLM4 (KINETIS_ADC0_BASE+KINETIS_ADC_CLM4_OFFSET)
@@ -131,7 +135,9 @@
#define KINETIS_ADC1_CLP2 (KINETIS_ADC1_BASE+KINETIS_ADC_CLP2_OFFSET)
#define KINETIS_ADC1_CLP1 (KINETIS_ADC1_BASE+KINETIS_ADC_CLP1_OFFSET)
#define KINETIS_ADC1_CLP0 (KINETIS_ADC1_BASE+KINETIS_ADC_CLP0_OFFSET)
-#define KINETIS_ADC1_PGA (KINETIS_ADC1_BASE+KINETIS_ADC_PGA_OFFSET)
+#ifndef KINETIS_K64
+# define KINETIS_ADC1_PGA (KINETIS_ADC1_BASE+KINETIS_ADC_PGA_OFFSET)
+#endif
#define KINETIS_ADC1_CLMD (KINETIS_ADC1_BASE+KINETIS_ADC_CLMD_OFFSET)
#define KINETIS_ADC1_CLMS (KINETIS_ADC1_BASE+KINETIS_ADC_CLMS_OFFSET)
#define KINETIS_ADC1_CLM4 (KINETIS_ADC1_BASE+KINETIS_ADC_CLM4_OFFSET)
@@ -272,22 +278,26 @@
#define ADC_CLP0_MASK (0x3f) /* Bits 0-5: Calibration value */
/* ADC PGA register */
+
+#ifndef KINETIS_K64
/* Bits 0-15: Reserved */
-#define ADC_PGA_PGAG_SHIFT (16) /* Bits 16-19: PGA gain setting*/
-#define ADC_PGA_PGAG_MASK (15 << ADC_PGA_PGAG_SHIFT)
-# define ADC_PGA_PGAG_1 (0 << ADC_PGA_PGAG_SHIFT)
-# define ADC_PGA_PGAG_2 (1 << ADC_PGA_PGAG_SHIFT)
-# define ADC_PGA_PGAG_4 (2 << ADC_PGA_PGAG_SHIFT)
-# define ADC_PGA_PGAG_8 (3 << ADC_PGA_PGAG_SHIFT)
-# define ADC_PGA_PGAG_16 (4 << ADC_PGA_PGAG_SHIFT)
-# define ADC_PGA_PGAG_32 (5 << ADC_PGA_PGAG_SHIFT)
-# define ADC_PGA_PGAG_64 (6 << ADC_PGA_PGAG_SHIFT)
-#ifdef KINETIS_K40
-# define ADC_PGA_PGALP (1 << 20) /* Bit 20: PGA low-power mode control */
-#endif
+# define ADC_PGA_PGAG_SHIFT (16) /* Bits 16-19: PGA gain setting*/
+# define ADC_PGA_PGAG_MASK (15 << ADC_PGA_PGAG_SHIFT)
+# define ADC_PGA_PGAG_1 (0 << ADC_PGA_PGAG_SHIFT)
+# define ADC_PGA_PGAG_2 (1 << ADC_PGA_PGAG_SHIFT)
+# define ADC_PGA_PGAG_4 (2 << ADC_PGA_PGAG_SHIFT)
+# define ADC_PGA_PGAG_8 (3 << ADC_PGA_PGAG_SHIFT)
+# define ADC_PGA_PGAG_16 (4 << ADC_PGA_PGAG_SHIFT)
+# define ADC_PGA_PGAG_32 (5 << ADC_PGA_PGAG_SHIFT)
+# define ADC_PGA_PGAG_64 (6 << ADC_PGA_PGAG_SHIFT)
+# ifdef KINETIS_K40
+# define ADC_PGA_PGALP (1 << 20) /* Bit 20: PGA low-power mode control */
+# endif
/* Bits 21-22: Reserved */
-#define ADC_PGA_PGAEN (1 << 23) /* Bit 23: PGA enable*/
+# define ADC_PGA_PGAEN (1 << 23) /* Bit 23: PGA enable*/
/* Bits 24-31: Reserved */
+#endif
+
/* ADC minus-side general calibration value registers */
#define ADC_CLMD_MASK (0x3f) /* Bits 0-5: Calibration value */
@@ -310,4 +320,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_ADC_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_ADC_H */
diff --git a/arch/arm/src/kinetis/kinetis_aips.h b/arch/arm/src/kinetis/chip/kinetis_aips.h
similarity index 87%
rename from arch/arm/src/kinetis/kinetis_aips.h
rename to arch/arm/src/kinetis/chip/kinetis_aips.h
index 8f460567f76125052a24664fdc02843624729dba..a8050fb61397771f32b90c52fe0387920e39f285 100644
--- a/arch/arm/src/kinetis/kinetis_aips.h
+++ b/arch/arm/src/kinetis/chip/kinetis_aips.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_aips.h
+ * arch/arm/src/kinetis/chip/kinetis_aips.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_AIPS_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_AIPS_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_AIPS_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_AIPS_H
/************************************************************************************
* Included Files
@@ -68,6 +68,9 @@
#define KINETIS_AIPS_PACRN_OFFSET 0x0064 /* Peripheral Access Control Register */
#define KINETIS_AIPS_PACRO_OFFSET 0x0068 /* Peripheral Access Control Register */
#define KINETIS_AIPS_PACRP_OFFSET 0x006c /* Peripheral Access Control Register */
+#ifdef KINETIS_K64
+# define KINETIS_AIPS_PACRU_OFFSET 0x0080 /* Peripheral Access Control Register */
+#endif
/* Register Addresses ***************************************************************/
@@ -88,24 +91,30 @@
#define KINETIS_AIPS0_PACRN (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRN_OFFSET)
#define KINETIS_AIPS0_PACRO (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRO_OFFSET)
#define KINETIS_AIPS0_PACRP (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRP_OFFSET)
-
-#define KINETIS_AIPS1_MPRA (KINETIS_AIPS0_BASE+KINETIS_AIPS_MPRA_OFFSET)
-#define KINETIS_AIPS1_PACRA (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRA_OFFSET)
-#define KINETIS_AIPS1_PACRB (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRB_OFFSET)
-#define KINETIS_AIPS1_PACRC (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRC_OFFSET)
-#define KINETIS_AIPS1_PACRD (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRD_OFFSET)
-#define KINETIS_AIPS1_PACRE (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRE_OFFSET)
-#define KINETIS_AIPS1_PACRF (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRF_OFFSET)
-#define KINETIS_AIPS1_PACRG (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRG_OFFSET)
-#define KINETIS_AIPS1_PACRH (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRH_OFFSET)
-#define KINETIS_AIPS1_PACRI (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRI_OFFSET)
-#define KINETIS_AIPS1_PACRJ (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRJ_OFFSET)
-#define KINETIS_AIPS1_PACRK (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRK_OFFSET)
-#define KINETIS_AIPS1_PACRL (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRL_OFFSET)
-#define KINETIS_AIPS1_PACRM (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRM_OFFSET)
-#define KINETIS_AIPS1_PACRN (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRN_OFFSET)
-#define KINETIS_AIPS1_PACRO (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRO_OFFSET)
-#define KINETIS_AIPS1_PACRP (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRP_OFFSET)
+#ifdef KINETIS_K64
+# define KINETIS_AIPS0_PACRU (KINETIS_AIPS0_BASE+KINETIS_AIPS_PACRU_OFFSET)
+#endif
+
+#define KINETIS_AIPS1_MPRA (KINETIS_AIPS1_BASE+KINETIS_AIPS_MPRA_OFFSET)
+#define KINETIS_AIPS1_PACRA (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRA_OFFSET)
+#define KINETIS_AIPS1_PACRB (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRB_OFFSET)
+#define KINETIS_AIPS1_PACRC (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRC_OFFSET)
+#define KINETIS_AIPS1_PACRD (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRD_OFFSET)
+#define KINETIS_AIPS1_PACRE (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRE_OFFSET)
+#define KINETIS_AIPS1_PACRF (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRF_OFFSET)
+#define KINETIS_AIPS1_PACRG (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRG_OFFSET)
+#define KINETIS_AIPS1_PACRH (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRH_OFFSET)
+#define KINETIS_AIPS1_PACRI (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRI_OFFSET)
+#define KINETIS_AIPS1_PACRJ (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRJ_OFFSET)
+#define KINETIS_AIPS1_PACRK (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRK_OFFSET)
+#define KINETIS_AIPS1_PACRL (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRL_OFFSET)
+#define KINETIS_AIPS1_PACRM (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRM_OFFSET)
+#define KINETIS_AIPS1_PACRN (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRN_OFFSET)
+#define KINETIS_AIPS1_PACRO (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRO_OFFSET)
+#define KINETIS_AIPS1_PACRP (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRP_OFFSET)
+#ifdef KINETIS_K64
+# define KINETIS_AIPS1_PACRU (KINETIS_AIPS1_BASE+KINETIS_AIPS_PACRU_OFFSET)
+#endif
/* Register Bit Definitions *********************************************************/
@@ -205,4 +214,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_AIPS_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_AIPS_H */
diff --git a/arch/arm/src/kinetis/kinetis_axbs.h b/arch/arm/src/kinetis/chip/kinetis_axbs.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_axbs.h
rename to arch/arm/src/kinetis/chip/kinetis_axbs.h
index bf8543d4dac5a5dc5b13a4b110e447483d1dcdb7..7aab308593c3a3b56a32ef8c9703f55e4b9cec92 100644
--- a/arch/arm/src/kinetis/kinetis_axbs.h
+++ b/arch/arm/src/kinetis/chip/kinetis_axbs.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_axbs.h
+ * arch/arm/src/kinetis/chip/kinetis_axbs.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_AXBS_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_AXBS_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_AXBS_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_AXBS_H
/************************************************************************************
* Included Files
@@ -248,4 +248,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_AXBS_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_AXBS_H */
diff --git a/arch/arm/src/kinetis/kinetis_cmp.h b/arch/arm/src/kinetis/chip/kinetis_cmp.h
similarity index 96%
rename from arch/arm/src/kinetis/kinetis_cmp.h
rename to arch/arm/src/kinetis/chip/kinetis_cmp.h
index 822b7a339f5de9603af3e3236f03d1e5b47068ba..09e9eb19f6a9846b58fb0be5f686a1c0c49da08f 100644
--- a/arch/arm/src/kinetis/kinetis_cmp.h
+++ b/arch/arm/src/kinetis/chip/kinetis_cmp.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_cmp.h
+ * arch/arm/src/kinetis/chip/kinetis_cmp.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_CMP_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_CMP_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CMP_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CMP_H
/********************************************************************************************
* Included Files
@@ -172,7 +172,9 @@
# define CMP_MUXCR_PSEL_IN5 (5 << CMP_MUXCR_PSEL_SHIFT)
# define CMP_MUXCR_PSEL_IN6 (6 << CMP_MUXCR_PSEL_SHIFT)
# define CMP_MUXCR_PSEL_IN7 (7 << CMP_MUXCR_PSEL_SHIFT)
-#define CMP_MUXCR_MEN (1 << 6) /* Bit 6: MMUX Enable */
+#ifndef KINETIS_K64
+# define CMP_MUXCR_MEN (1 << 6) /* Bit 6: MMUX Enable */
+#endif
#define CMP_MUXCR_PEN (1 << 7) /* Bit 7: PMUX Enable */
/********************************************************************************************
@@ -187,4 +189,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_CMP_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CMP_H */
diff --git a/arch/arm/src/kinetis/kinetis_cmt.h b/arch/arm/src/kinetis/chip/kinetis_cmt.h
similarity index 96%
rename from arch/arm/src/kinetis/kinetis_cmt.h
rename to arch/arm/src/kinetis/chip/kinetis_cmt.h
index c3c47bb6761254a0ce4c86484a43e41809433cdf..e86720db91e02a4d55df9c9baec355c9a51f152f 100644
--- a/arch/arm/src/kinetis/kinetis_cmt.h
+++ b/arch/arm/src/kinetis/chip/kinetis_cmt.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_cmt.h
+ * arch/arm/src/kinetis/chip/kinetis_cmt.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_CMT_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_CMT_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CMT_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CMT_H
/************************************************************************************
* Included Files
@@ -135,4 +135,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_CMT_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CMT_H */
diff --git a/arch/arm/src/kinetis/kinetis_crc.h b/arch/arm/src/kinetis/chip/kinetis_crc.h
similarity index 85%
rename from arch/arm/src/kinetis/kinetis_crc.h
rename to arch/arm/src/kinetis/chip/kinetis_crc.h
index 7b590cf3a9a0c39374982f0c8b747da54bb71ccf..d2f0fc7fddb10ecae0286603b9d50c7f4139477f 100644
--- a/arch/arm/src/kinetis/kinetis_crc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_crc.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_crc.h
+ * arch/arm/src/kinetis/chip/kinetis_crc.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_CRC_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_CRC_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CRC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CRC_H
/************************************************************************************
* Included Files
@@ -52,13 +52,13 @@
/* Register Offsets *****************************************************************/
-#define KINETIS_CRC_CRC_OFFSET 0x0000 /* CRC Data Register */
+#define KINETIS_CRC_DATA_OFFSET 0x0000 /* CRC Data Register */
#define KINETIS_CRC_GPOLY_OFFSET 0x0004 /* CRC Polynomial Register */
#define KINETIS_CRC_CTRL_OFFSET 0x0008 /* CRC Control Register */
/* Register Addresses ***************************************************************/
-#define KINETIS_CRC_CRC (KINETIS_CRC_BASE+KINETIS_CRC_CRC_OFFSET)
+#define KINETIS_CRC_DATA (KINETIS_CRC_BASE+KINETIS_CRC_DATA_OFFSET)
#define KINETIS_CRC_GPOLY (KINETIS_CRC_BASE+KINETIS_CRC_GPOLY_OFFSET)
#define KINETIS_CRC_CTRL (KINETIS_CRC_BASE+KINETIS_CRC_CTRL_OFFSET)
@@ -66,14 +66,14 @@
/* CRC Data Register (32-bit) */
-#define CRC_CRC_LL_SHIFT (0) /* Bits 0-7: CRC Low Lower Byte */
-#define CRC_CRC_LL_MASK (0xff << CRC_CRC_LL_SHIFT)
-#define CRC_CRC_LU_SHIFT (8) /* Bits 8-15: CRC Low Upper Byte */
-#define CRC_CRC_LU_MASK (0xff << CRC_CRC_LU_SHIFT)
-#define CRC_CRC_HL_SHIFT (16) /* Bits 16-23: CRC High Lower Byte */
-#define CRC_CRC_HL_MASK (0xff << CRC_CRC_HL_SHIFT)
-#define CRC_CRC_HU_SHIFT (24) /* Bits 24-31: CRC High Upper Byte */
-#define CRC_CRC_HU_MASK (0xff << CRC_CRC_HU_SHIFT)
+#define CRC_DATA_LL_SHIFT (0) /* Bits 0-7: CRC Low Lower Byte */
+#define CRC_DATA_LL_MASK (0xff << CRC_DATA_LL_SHIFT)
+#define CRC_DATA_LU_SHIFT (8) /* Bits 8-15: CRC Low Upper Byte */
+#define CRC_DATA_LU_MASK (0xff << CRC_DATA_LU_SHIFT)
+#define CRC_DATA_HL_SHIFT (16) /* Bits 16-23: CRC High Lower Byte */
+#define CRC_DATA_HL_MASK (0xff << CRC_DATA_HL_SHIFT)
+#define CRC_DATA_HU_SHIFT (24) /* Bits 24-31: CRC High Upper Byte */
+#define CRC_DATA_HU_MASK (0xff << CRC_DATA_HU_SHIFT)
/* CRC Polynomial Register */
@@ -114,4 +114,4 @@
************************************************************************************/
#endif /* KINETIS_NCRC && KINETIS_NCRC > 0 */
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_CRC_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_CRC_H */
diff --git a/arch/arm/src/kinetis/kinetis_dac.h b/arch/arm/src/kinetis/chip/kinetis_dac.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_dac.h
rename to arch/arm/src/kinetis/chip/kinetis_dac.h
index 5c3b5c0c037503fc669c2427f5581f6b2322285d..bf2184382632158f1270fec96d536a0e9ff363d7 100644
--- a/arch/arm/src/kinetis/kinetis_dac.h
+++ b/arch/arm/src/kinetis/chip/kinetis_dac.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_dac.h
+ * arch/arm/src/kinetis/chip/kinetis_dac.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_DACE_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_DACE_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DAC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DAC_H
/********************************************************************************************
* Included Files
@@ -232,4 +232,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_DACE_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DAC_H */
diff --git a/arch/arm/src/kinetis/kinetis_dma.h b/arch/arm/src/kinetis/chip/kinetis_dma.h
similarity index 96%
rename from arch/arm/src/kinetis/kinetis_dma.h
rename to arch/arm/src/kinetis/chip/kinetis_dma.h
index 9876a46a0f0fdc794f55676c284e2f446ea5dd8a..aec14d32f4fd5d7e88adf8082560486bbd608345 100644
--- a/arch/arm/src/kinetis/kinetis_dma.h
+++ b/arch/arm/src/kinetis/chip/kinetis_dma.h
@@ -1,7 +1,7 @@
/****************************************************************************************************
- * arch/arm/src/kinetis/kinetis_dma.h
+ * arch/arm/src/kinetis/chip/kinetis_dma.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
****************************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_DMA_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_DMA_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DMA_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DMA_H
/****************************************************************************************************
* Included Files
@@ -83,18 +83,20 @@
#define KINETIS_DMA_DCHPRI13_OFFSET 0x010e /* Channel 13 Priority Register */
#define KINETIS_DMA_DCHPRI12_OFFSET 0x010f /* Channel 12 Priority Register */
-#define KINETIS_DMA_TCD_OFFSET(n) (0x0000+((n) << 5))
-#define KINETIS_DMA_TCD_SADDR_OFFSET 0x0000 /* TCD Source Address */
-#define KINETIS_DMA_TCD_SOFF_OFFSET 0x0004 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD_ATTR_OFFSET 0x0006 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD_NBYTES_OFFSET 0x0008 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD_SLAST_OFFSET 0x000c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD_DADDR_OFFSET 0x0010 /* TCD Destination Address */
-#define KINETIS_DMA_TCD_DOFF_OFFSET 0x0014 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD_CITER_OFFSET 0x0016 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD_DLASTSGA_OFFSET 0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD_CSR_OFFSET 0x001c /* TCD Control and Status */
-#define KINETIS_DMA_TCD_BITER_OFFSET 0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */
+#ifndef KINETIS_K64
+# define KINETIS_DMA_TCD_OFFSET(n) (0x0000+((n) << 5))
+# define KINETIS_DMA_TCD_SADDR_OFFSET 0x0000 /* TCD Source Address */
+# define KINETIS_DMA_TCD_SOFF_OFFSET 0x0004 /* TCD Signed Source Address Offset */
+# define KINETIS_DMA_TCD_ATTR_OFFSET 0x0006 /* TCD Transfer Attributes */
+# define KINETIS_DMA_TCD_NBYTES_OFFSET 0x0008 /* TCD Minor Byte Count */
+# define KINETIS_DMA_TCD_SLAST_OFFSET 0x000c /* TCD Last Source Address Adjustment */
+# define KINETIS_DMA_TCD_DADDR_OFFSET 0x0010 /* TCD Destination Address */
+# define KINETIS_DMA_TCD_DOFF_OFFSET 0x0014 /* TCD Signed Destination Address Offset */
+# define KINETIS_DMA_TCD_CITER_OFFSET 0x0016 /* TCD Current Minor Loop Link, Major Loop Count */
+# define KINETIS_DMA_TCD_DLASTSGA_OFFSET 0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+# define KINETIS_DMA_TCD_CSR_OFFSET 0x001c /* TCD Control and Status */
+# define KINETIS_DMA_TCD_BITER_OFFSET 0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */
+#endif
#define KINETIS_DMA_TCD0_SADDR_OFFSET 0x0000 /* TCD Source Address */
#define KINETIS_DMA_TCD0_SOFF_OFFSET 0x0004 /* TCD Signed Source Address Offset */
@@ -323,19 +325,21 @@
#define KINETIS_DMA_DCHPRI13 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI13_OFFSET)
#define KINETIS_DMA_DCHPRI12 (KINETIS_DMAC_BASE+KINETIS_DMA_DCHPRI12_OFFSET)
-#define KINETIS_DMA_TCD_BASE(n) (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD_OFFSET(n))
-
-#define KINETIS_DMA_TCD_SADDR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SADDR_OFFSET)
-#define KINETIS_DMA_TCD_SOFF(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SOFF_OFFSET)
-#define KINETIS_DMA_TCD_ATTR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_ATTR_OFFSET)
-#define KINETIS_DMA_TCD_NBYTES(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD_SLAST(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SLAST_OFFSET)
-#define KINETIS_DMA_TCD_DADDR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DADDR_OFFSET)
-#define KINETIS_DMA_TCD_DOFF(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DOFF_OFFSET)
-#define KINETIS_DMA_TCD_CITER(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CITER_OFFSET)
-#define KINETIS_DMA_TCD_DLASTSGA(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD_CSR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CSR_OFFSET)
-#define KINETIS_DMA_TCD_BITER(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_BITER_OFFSET)
+#ifndef KINETIS_K64
+# define KINETIS_DMA_TCD_BASE(n) (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD_OFFSET(n))
+
+# define KINETIS_DMA_TCD_SADDR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SADDR_OFFSET)
+# define KINETIS_DMA_TCD_SOFF(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SOFF_OFFSET)
+# define KINETIS_DMA_TCD_ATTR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_ATTR_OFFSET)
+# define KINETIS_DMA_TCD_NBYTES(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_NBYTES_OFFSET)
+# define KINETIS_DMA_TCD_SLAST(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SLAST_OFFSET)
+# define KINETIS_DMA_TCD_DADDR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DADDR_OFFSET)
+# define KINETIS_DMA_TCD_DOFF(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DOFF_OFFSET)
+# define KINETIS_DMA_TCD_CITER(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CITER_OFFSET)
+# define KINETIS_DMA_TCD_DLASTSGA(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DLASTSGA_OFFSET)
+# define KINETIS_DMA_TCD_CSR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CSR_OFFSET)
+# define KINETIS_DMA_TCD_BITER(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_BITER_OFFSET)
+#endif
#define KINETIS_DMA_TCD0_SADDR (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_SADDR_OFFSET)
#define KINETIS_DMA_TCD0_SOFF (KINETIS_DMADESC_BASE+KINETIS_DMA_TCD0_SOFF_OFFSET)
@@ -772,4 +776,4 @@
* Public Functions
****************************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_DMA_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DMA_H */
diff --git a/arch/arm/src/kinetis/kinetis_dmamux.h b/arch/arm/src/kinetis/chip/kinetis_dmamux.h
similarity index 95%
rename from arch/arm/src/kinetis/kinetis_dmamux.h
rename to arch/arm/src/kinetis/chip/kinetis_dmamux.h
index b83579180ea0ca53d2d0b99d55ac6de604ab51e8..d63feb8da31e3d562ea1c033afc094a7d1121f67 100644
--- a/arch/arm/src/kinetis/kinetis_dmamux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_dmamux.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_dmamux.h
+ * arch/arm/src/kinetis/chip/kinetis_dmamux.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_DMAMUX_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_DMAMUX_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DMAMUX_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DMAMUX_H
/********************************************************************************************
* Included Files
@@ -108,4 +108,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_DMAMUX_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DMAMUX_H */
diff --git a/arch/arm/src/kinetis/kinetis_dspi.h b/arch/arm/src/kinetis/chip/kinetis_dspi.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_dspi.h
rename to arch/arm/src/kinetis/chip/kinetis_dspi.h
index e682ef23e8555ab5f706903846579803d7c16e39..99507cb9e851bb1ab1c1274617205eec2c532e72 100644
--- a/arch/arm/src/kinetis/kinetis_dspi.h
+++ b/arch/arm/src/kinetis/chip/kinetis_dspi.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_dspi.h
+ * arch/arm/src/kinetis/chip/kinetis_dspi.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_DSPI_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_DSPI_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DSPI_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DSPI_H
/********************************************************************************************
* Included Files
@@ -318,4 +318,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_DSPI_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_DSPI_H */
diff --git a/arch/arm/src/kinetis/kinetis_enet.h b/arch/arm/src/kinetis/chip/kinetis_enet.h
similarity index 99%
rename from arch/arm/src/kinetis/kinetis_enet.h
rename to arch/arm/src/kinetis/chip/kinetis_enet.h
index cadd006d8ce114644b37fc9a77b5c2cb87dd67f3..8f34d0c7f6468ecfd1f6fd9ed32442786d240107 100644
--- a/arch/arm/src/kinetis/kinetis_enet.h
+++ b/arch/arm/src/kinetis/chip/kinetis_enet.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_enet.h
+ * arch/arm/src/kinetis/chip/kinetis_enet.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_ENET_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_ENET_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_ENET_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_ENET_H
/********************************************************************************************
* Included Files
@@ -649,4 +649,4 @@ struct enet_desc_s
********************************************************************************************/
#endif /* KINETIS_NENET && KINETIS_NENET > 0 */
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_ENET_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_ENET_H */
diff --git a/arch/arm/src/kinetis/kinetis_ewm.h b/arch/arm/src/kinetis/chip/kinetis_ewm.h
similarity index 93%
rename from arch/arm/src/kinetis/kinetis_ewm.h
rename to arch/arm/src/kinetis/chip/kinetis_ewm.h
index e259a3cf29af2f891e40532f4afd01ff3e5626bc..e91bc28c2c60fda5d1397b45092b62bd81f6618e 100644
--- a/arch/arm/src/kinetis/kinetis_ewm.h
+++ b/arch/arm/src/kinetis/chip/kinetis_ewm.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_ewm.h
+ * arch/arm/src/kinetis/chip/kinetis_ewm.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_EWM_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_EWM_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_EWM_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_EWM_H
/************************************************************************************
* Included Files
@@ -87,4 +87,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_EWM_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_EWM_H */
diff --git a/arch/arm/src/kinetis/kinetis_flexbus.h b/arch/arm/src/kinetis/chip/kinetis_flexbus.h
similarity index 97%
rename from arch/arm/src/kinetis/kinetis_flexbus.h
rename to arch/arm/src/kinetis/chip/kinetis_flexbus.h
index 37992320fb18804f50c1d985bcfe5a3e13a85bef..7c063d086976a06e039aa101ffccfe775084b21d 100644
--- a/arch/arm/src/kinetis/kinetis_flexbus.h
+++ b/arch/arm/src/kinetis/chip/kinetis_flexbus.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_flexbus.h
+ * arch/arm/src/kinetis/chip/kinetis_flexbus.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXBUS_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXBUS_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FLEXBUS_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FLEXBUS_H
/************************************************************************************
* Included Files
@@ -210,4 +210,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXBUS_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FLEXBUS_H */
diff --git a/arch/arm/src/kinetis/kinetis_flexcan.h b/arch/arm/src/kinetis/chip/kinetis_flexcan.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_flexcan.h
rename to arch/arm/src/kinetis/chip/kinetis_flexcan.h
index db151d5403474d7dd1dc48ee249a8043846ae774..9d3ec74a38168c2a7ef7a0de6897dd401fdbb17e 100644
--- a/arch/arm/src/kinetis/kinetis_flexcan.h
+++ b/arch/arm/src/kinetis/chip/kinetis_flexcan.h
@@ -1,7 +1,7 @@
/****************************************************************************************************
- * arch/arm/src/kinetis/kinetis_flexcan.h
+ * arch/arm/src/kinetis/chip/kinetis_flexcan.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
****************************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXCAN_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXCAN_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FLEXCAN_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FLEXCAN_H
/****************************************************************************************************
* Included Files
@@ -315,4 +315,4 @@
* Public Functions
****************************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FLEXCAN_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FLEXCAN_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_fmc.h b/arch/arm/src/kinetis/chip/kinetis_fmc.h
new file mode 100644
index 0000000000000000000000000000000000000000..d189d657ddd135af9d3b45b70ee36953c5717296
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_fmc.h
@@ -0,0 +1,75 @@
+/********************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_fmc.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FMC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FMC_H
+
+/********************************************************************************************
+ * Included Files
+ ********************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/* This file is just a wrapper around pin muxing header files for the Kinetis family selected
+ * by the logic in chip.h.
+ */
+
+#if defined(KINETIS_K20) || defined(KINETIS_K40) || defined(KINETIS_K60)
+# include "chip/kinetis_k20k40k60fmc.h"
+#elif defined(KINETIS_K64)
+# include "chip/kinetis_k64fmc.h"
+#else
+# error "No FMC definitions for this Kinetis part"
+#endif
+
+/********************************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Types
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Functions
+ ********************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FMC_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_ftfe.h b/arch/arm/src/kinetis/chip/kinetis_ftfe.h
new file mode 100644
index 0000000000000000000000000000000000000000..13794d97dbe08a6ad7809ac2a5380fde12fd0c95
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_ftfe.h
@@ -0,0 +1,159 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_ftfe.h
+ *
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FTFE_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FTFE_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Register Offsets *****************************************************************/
+
+#define KINETIS_FTFE_FSTAT_OFFSET 0x0000 /* Flash Status Register */
+#define KINETIS_FTFE_FCNFG_OFFSET 0x0001 /* Flash Configuration Register */
+#define KINETIS_FTFE_FSEC_OFFSET 0x0002 /* Flash Security Register */
+#define KINETIS_FTFE_FOPT_OFFSET 0x0003 /* Flash Option Register */
+
+#define KINETIS_FTFE_FCCOB3_OFFSET 0x0004 /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB2_OFFSET 0x0005 /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB1_OFFSET 0x0006 /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB0_OFFSET 0x0007 /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB7_OFFSET 0x0008 /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB6_OFFSET 0x0009 /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB5_OFFSET 0x000a /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB4_OFFSET 0x000b /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOBB_OFFSET 0x000c /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOBA_OFFSET 0x000d /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB9_OFFSET 0x000e /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FCCOB8_OFFSET 0x000f /* Flash Common Command Object Registers */
+#define KINETIS_FTFE_FPROT3_OFFSET 0x0010 /* Program Flash Protection Registers */
+#define KINETIS_FTFE_FPROT2_OFFSET 0x0011 /* Program Flash Protection Registers */
+#define KINETIS_FTFE_FPROT1_OFFSET 0x0012 /* Program Flash Protection Registers */
+#define KINETIS_FTFE_FPROT0_OFFSET 0x0013 /* Program Flash Protection Registers */
+#define KINETIS_FTFE_FEPROT_OFFSET 0x0016 /* EEPROM Protection Register */
+#define KINETIS_FTFE_FDPROT_OFFSET 0x0017 /* Data Flash Protection Register */
+
+/* Register Addresses ***************************************************************/
+
+#define KINETIS_FTFE_FSTAT (KINETIS_FTFE_BASE+KINETIS_FTFE_FSTAT_OFFSET)
+#define KINETIS_FTFE_FCNFG (KINETIS_FTFE_BASE+KINETIS_FTFE_FCNFG_OFFSET)
+#define KINETIS_FTFE_FSEC (KINETIS_FTFE_BASE+KINETIS_FTFE_FSEC_OFFSET)
+#define KINETIS_FTFE_FOPT (KINETIS_FTFE_BASE+KINETIS_FTFE_FOPT_OFFSET)
+#define KINETIS_FTFE_FCCOB3 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB3_OFFSET)
+#define KINETIS_FTFE_FCCOB2 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB2_OFFSET)
+#define KINETIS_FTFE_FCCOB1 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB1_OFFSET)
+#define KINETIS_FTFE_FCCOB0 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB0_OFFSET)
+#define KINETIS_FTFE_FCCOB7 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB7_OFFSET)
+#define KINETIS_FTFE_FCCOB6 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB6_OFFSET)
+#define KINETIS_FTFE_FCCOB5 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB5_OFFSET)
+#define KINETIS_FTFE_FCCOB4 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB4_OFFSET)
+#define KINETIS_FTFE_FCCOBB (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOBB_OFFSET)
+#define KINETIS_FTFE_FCCOBA (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOBA_OFFSET)
+#define KINETIS_FTFE_FCCOB9 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB9_OFFSET)
+#define KINETIS_FTFE_FCCOB8 (KINETIS_FTFE_BASE+KINETIS_FTFE_FCCOB8_OFFSET)
+#define KINETIS_FTFE_FPROT3 (KINETIS_FTFE_BASE+KINETIS_FTFE_FPROT3_OFFSET)
+#define KINETIS_FTFE_FPROT2 (KINETIS_FTFE_BASE+KINETIS_FTFE_FPROT2_OFFSET)
+#define KINETIS_FTFE_FPROT1 (KINETIS_FTFE_BASE+KINETIS_FTFE_FPROT1_OFFSET)
+#define KINETIS_FTFE_FPROT0 (KINETIS_FTFE_BASE+KINETIS_FTFE_FPROT0_OFFSET)
+#define KINETIS_FTFE_FEPROT (KINETIS_FTFE_BASE+KINETIS_FTFE_FEPROT_OFFSET)
+#define KINETIS_FTFE_FDPROT (KINETIS_FTFE_BASE+KINETIS_FTFE_FDPROT_OFFSET)
+
+/* Register Bit Definitions *********************************************************/
+
+/* Flash Status Register */
+
+#define FTFE_FSTAT_MGSTAT0 (1 << 0) /* Bit 0: Memory Controller Command Completion Status Flag */
+ /* Bits 1-3: Reserved */
+#define FTFE_FSTAT_FPVIOL (1 << 4) /* Bit 4: Flash Protection Violation Flag */
+#define FTFE_FSTAT_ACCERR (1 << 5) /* Bit 5: Flash Access Error Flag */
+#define FTFE_FSTAT_RDCOLERR (1 << 6) /* Bit 6: FTFE Read Collision Error Flag */
+#define FTFE_FSTAT_CCIF (1 << 7) /* Bit 7: Command Complete Interrupt Flag */
+
+/* Flash Configuration Register */
+
+#define FTFE_FCNFG_EEERDY (1 << 0) /* Bit 0: FEEPROM backup data copied to FlexRAM */
+#define FTFE_FCNFG_RAMRDY (1 << 1) /* Bit 1: RAM Ready */
+#define FTFE_FCNFG_PFLSH (1 << 2) /* Bit 2: FTFE configuration */
+#define FTFE_FCNFG_SWAP (1 << 3) /* Bit 3: Swap */
+#define FTFE_FCNFG_ERSSUSP (1 << 4) /* Bit 4: Erase Suspend */
+#define FTFE_FCNFG_ERSAREQ (1 << 5) /* Bit 5: Erase All Request */
+#define FTFE_FCNFG_RDCOLLIE (1 << 6) /* Bit 6: Read Collision Error Interrupt Enable */
+#define FTFE_FCNFG_CCIE (1 << 7) /* Bit 7: Command Complete Interrupt Enable */
+
+/* Flash Security Register */
+
+#define FTFE_FSEC_SEC_SHIFT (0) /* Bits 0-1: Flash Security */
+#define FTFE_FSEC_SEC_MASK (3 << FTFE_FSEC_SEC_SHIFT)
+# define FTFE_FSEC_SEC_SECURE (0 << FTFE_FSEC_SEC_SHIFT) /* 00,01,11: status is secure */
+# define FTFE_FSEC_SEC_UNSECURE (2 << FTFE_FSEC_SEC_SHIFT) /* 10: status is insecure */
+#define FTFE_FSEC_FSLACC_SHIFT (2) /* Bits 2-3: Freescale Failure Analysis Access Code */
+#define FTFE_FSEC_FSLACC_MASK (3 << FTFE_FSEC_FSLACC_SHIFT)
+# define FTFE_FSEC_FSLACC_GRANTED (0 << FTFE_FSEC_FSLACC_SHIFT) /* 00 or 11: Access granted */
+# define FTFE_FSEC_FSLACC_DENIED (1 << FTFE_FSEC_FSLACC_SHIFT) /* 01 or 10: Access denied */
+#define FTFE_FSEC_MEEN_SHIFT (4) /* Bits 4-5: Mass Erase Enable Bits */
+#define FTFE_FSEC_MEEN_MASK (3 << FTFE_FSEC_MEEN_SHIFT)
+# define FTFE_FSEC_MEEN_ENABLED (0 << FTFE_FSEC_MEEN_SHIFT) /* All values are enabled */
+#define FTFE_FSEC_KEYEN_SHIFT (6) /* Bits 6-7: Backdoor Key Security Enable */
+#define FTFE_FSEC_KEYEN_MASK (3 << FTFE_FSEC_KEYEN_SHIFT)
+# define FTFE_FSEC_KEYEN_DISABLED (1 << FTFE_FSEC_KEYEN_SHIFT) /* All values are disabled */
+
+/* Flash Option Register (32-bits, see Chip Configuration details) */
+/* Flash Common Command Object Registers (8-bit flash command data) */
+/* Program Flash Protection Registers (8-bit flash protection data) */
+/* EEPROM Protection Register (8-bit eeprom protection data) */
+/* Data Flash Protection Register (8-bit data flash protection data) */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FTFE_H */
diff --git a/arch/arm/src/kinetis/kinetis_ftm.h b/arch/arm/src/kinetis/chip/kinetis_ftm.h
similarity index 90%
rename from arch/arm/src/kinetis/kinetis_ftm.h
rename to arch/arm/src/kinetis/chip/kinetis_ftm.h
index 2f031b5dd9b68e6e1d71831b638a213f72478d04..1402f5e8d8a3af88caace4bc3e0d17d6d12b8b0d 100644
--- a/arch/arm/src/kinetis/kinetis_ftm.h
+++ b/arch/arm/src/kinetis/chip/kinetis_ftm.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_ftm.h
+ * arch/arm/src/kinetis/chip/kinetis_ftm.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FTM_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_FTM_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FTM_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FTM_H
/********************************************************************************************
* Included Files
@@ -228,6 +228,50 @@
#define KINETIS_FTM2_SWOCTRL (KINETIS_FTM2_BASE+KINETIS_FTM_SWOCTRL_OFFSET)
#define KINETIS_FTM2_PWMLOAD (KINETIS_FTM2_BASE+KINETIS_FTM_PWMLOAD_OFFSET)
+#define KINETIS_FTM3_SC (KINETIS_FTM3_BASE+KINETIS_FTM_SC_OFFSET)
+#define KINETIS_FTM3_CNT (KINETIS_FTM3_BASE+KINETIS_FTM_CNT_OFFSET)
+#define KINETIS_FTM3_MOD (KINETIS_FTM3_BASE+KINETIS_FTM_MOD_OFFSET)
+
+#define KINETIS_FTM3_CSC(n) (KINETIS_FTM3_BASE+KINETIS_FTM_CSC_OFFSET(n))
+#define KINETIS_FTM3_CV(n) (KINETIS_FTM3_BASE+KINETIS_FTM_CV_OFFSET(n))
+#define KINETIS_FTM3_C0SC (KINETIS_FTM3_BASE+KINETIS_FTM_C0SC_OFFSET)
+#define KINETIS_FTM3_C0V (KINETIS_FTM3_BASE+KINETIS_FTM_C0V_OFFSET)
+#define KINETIS_FTM3_C1SC (KINETIS_FTM3_BASE+KINETIS_FTM_C1SC_OFFSET)
+#define KINETIS_FTM3_C1V (KINETIS_FTM3_BASE+KINETIS_FTM_C1V_OFFSET)
+#define KINETIS_FTM3_C2SC (KINETIS_FTM3_BASE+KINETIS_FTM_C2SC_OFFSET)
+#define KINETIS_FTM3_C2V (KINETIS_FTM3_BASE+KINETIS_FTM_C2V_OFFSET)
+#define KINETIS_FTM3_C3SC (KINETIS_FTM3_BASE+KINETIS_FTM_C3SC_OFFSET)
+#define KINETIS_FTM3_C3V (KINETIS_FTM3_BASE+KINETIS_FTM_C3V_OFFSET)
+#define KINETIS_FTM3_C4SC (KINETIS_FTM3_BASE+KINETIS_FTM_C4SC_OFFSET)
+#define KINETIS_FTM3_C4V (KINETIS_FTM3_BASE+KINETIS_FTM_C4V_OFFSET)
+#define KINETIS_FTM3_C5SC (KINETIS_FTM3_BASE+KINETIS_FTM_C5SC_OFFSET)
+#define KINETIS_FTM3_C5V (KINETIS_FTM3_BASE+KINETIS_FTM_C5V_OFFSET)
+#define KINETIS_FTM3_C6SC (KINETIS_FTM3_BASE+KINETIS_FTM_C6SC_OFFSET)
+#define KINETIS_FTM3_C6V (KINETIS_FTM3_BASE+KINETIS_FTM_C6V_OFFSET)
+#define KINETIS_FTM3_C7SC (KINETIS_FTM3_BASE+KINETIS_FTM_C7SC_OFFSET)
+#define KINETIS_FTM3_C7V (KINETIS_FTM3_BASE+KINETIS_FTM_C7V_OFFSET)
+
+#define KINETIS_FTM3_CNTIN (KINETIS_FTM3_BASE+KINETIS_FTM_CNTIN_OFFSET)
+#define KINETIS_FTM3_STATUS (KINETIS_FTM3_BASE+KINETIS_FTM_STATUS_OFFSET)
+#define KINETIS_FTM3_MODE (KINETIS_FTM3_BASE+KINETIS_FTM_MODE_OFFSET)
+#define KINETIS_FTM3_SYNC (KINETIS_FTM3_BASE+KINETIS_FTM_SYNC_OFFSET)
+#define KINETIS_FTM3_OUTINIT (KINETIS_FTM3_BASE+KINETIS_FTM_OUTINIT_OFFSET)
+#define KINETIS_FTM3_OUTMASK (KINETIS_FTM3_BASE+KINETIS_FTM_OUTMASK_OFFSET)
+#define KINETIS_FTM3_COMBINE (KINETIS_FTM3_BASE+KINETIS_FTM_COMBINE_OFFSET)
+#define KINETIS_FTM3_DEADTIME (KINETIS_FTM3_BASE+KINETIS_FTM_DEADTIME_OFFSET)
+#define KINETIS_FTM3_EXTTRIG (KINETIS_FTM3_BASE+KINETIS_FTM_EXTTRIG_OFFSET)
+#define KINETIS_FTM3_POL (KINETIS_FTM3_BASE+KINETIS_FTM_POL_OFFSET)
+#define KINETIS_FTM3_FMS (KINETIS_FTM3_BASE+KINETIS_FTM_FMS_OFFSET)
+#define KINETIS_FTM3_FILTER (KINETIS_FTM3_BASE+KINETIS_FTM_FILTER_OFFSET)
+#define KINETIS_FTM3_FLTCTRL (KINETIS_FTM3_BASE+KINETIS_FTM_FLTCTRL_OFFSET)
+#define KINETIS_FTM3_QDCTRL (KINETIS_FTM3_BASE+KINETIS_FTM_QDCTRL_OFFSET)
+#define KINETIS_FTM3_CONF (KINETIS_FTM3_BASE+KINETIS_FTM_CONF_OFFSET)
+#define KINETIS_FTM3_FLTPOL (KINETIS_FTM3_BASE+KINETIS_FTM_FLTPOL_OFFSET)
+#define KINETIS_FTM3_SYNCONF (KINETIS_FTM3_BASE+KINETIS_FTM_SYNCONF_OFFSET)
+#define KINETIS_FTM3_INVCTRL (KINETIS_FTM3_BASE+KINETIS_FTM_INVCTRL_OFFSET)
+#define KINETIS_FTM3_SWOCTRL (KINETIS_FTM3_BASE+KINETIS_FTM_SWOCTRL_OFFSET)
+#define KINETIS_FTM3_PWMLOAD (KINETIS_FTM3_BASE+KINETIS_FTM_PWMLOAD_OFFSET)
+
/* Register Bit Definitions *****************************************************************/
/* Status and Control */
@@ -525,4 +569,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FTM_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_FTM_H */
diff --git a/arch/arm/src/kinetis/kinetis_gpio.h b/arch/arm/src/kinetis/chip/kinetis_gpio.h
similarity index 100%
rename from arch/arm/src/kinetis/kinetis_gpio.h
rename to arch/arm/src/kinetis/chip/kinetis_gpio.h
diff --git a/arch/arm/src/kinetis/kinetis_i2c.h b/arch/arm/src/kinetis/chip/kinetis_i2c.h
similarity index 89%
rename from arch/arm/src/kinetis/kinetis_i2c.h
rename to arch/arm/src/kinetis/chip/kinetis_i2c.h
index bee9ef92db16c19ffe2dc0eb1815140211295345..94d071727b36e6625a1523b0eeb4d0bae2421bff 100644
--- a/arch/arm/src/kinetis/kinetis_i2c.h
+++ b/arch/arm/src/kinetis/chip/kinetis_i2c.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_i2c.h
+ * arch/arm/src/kinetis/chip/kinetis_i2c.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_I2CE_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_I2CE_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_I2CE_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_I2CE_H
/********************************************************************************************
* Included Files
@@ -91,6 +91,19 @@
#define KINETIS_I2C1_SLTH (KINETIS_I2C1_BASE+KINETIS_I2C_SLTH_OFFSET)
#define KINETIS_I2C1_SLTL (KINETIS_I2C1_BASE+KINETIS_I2C_SLTL_OFFSET)
+#define KINETIS_I2C2_A1 (KINETIS_I2C2_BASE+KINETIS_I2C_A1_OFFSET)
+#define KINETIS_I2C2_F (KINETIS_I2C2_BASE+KINETIS_I2C_F_OFFSET)
+#define KINETIS_I2C2_C1 (KINETIS_I2C2_BASE+KINETIS_I2C_C1_OFFSET)
+#define KINETIS_I2C2_S (KINETIS_I2C2_BASE+KINETIS_I2C_S_OFFSET)
+#define KINETIS_I2C2_D (KINETIS_I2C2_BASE+KINETIS_I2C_D_OFFSET)
+#define KINETIS_I2C2_C2 (KINETIS_I2C2_BASE+KINETIS_I2C_C2_OFFSET)
+#define KINETIS_I2C2_FLT (KINETIS_I2C2_BASE+KINETIS_I2C_FLT_OFFSET)
+#define KINETIS_I2C2_RA (KINETIS_I2C2_BASE+KINETIS_I2C_RA_OFFSET)
+#define KINETIS_I2C2_SMB (KINETIS_I2C2_BASE+KINETIS_I2C_SMB_OFFSET)
+#define KINETIS_I2C2_A2 (KINETIS_I2C2_BASE+KINETIS_I2C_A2_OFFSET)
+#define KINETIS_I2C2_SLTH (KINETIS_I2C2_BASE+KINETIS_I2C_SLTH_OFFSET)
+#define KINETIS_I2C2_SLTL (KINETIS_I2C2_BASE+KINETIS_I2C_SLTL_OFFSET)
+
/* Register Bit Definitions *****************************************************************/
/* I2C Address Register 1 (8-bit) */
@@ -182,4 +195,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_I2CE_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_I2CE_H */
diff --git a/arch/arm/src/kinetis/kinetis_i2s.h b/arch/arm/src/kinetis/chip/kinetis_i2s.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_i2s.h
rename to arch/arm/src/kinetis/chip/kinetis_i2s.h
index 11bcc0995562bbb550a7380bf8191bf8534e2c42..5de08843bb078e71422f3b61270dbb821306489f 100644
--- a/arch/arm/src/kinetis/kinetis_i2s.h
+++ b/arch/arm/src/kinetis/chip/kinetis_i2s.h
@@ -1,7 +1,7 @@
/****************************************************************************************************
- * arch/arm/src/kinetis/kinetis_i2s.h
+ * arch/arm/src/kinetis/chip/kinetis_i2s.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
****************************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_I2S_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_I2S_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_I2S_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_I2S_H
/****************************************************************************************************
* Included Files
@@ -294,4 +294,4 @@
* Public Functions
****************************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_I2S_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_I2S_H */
diff --git a/arch/arm/src/kinetis/kinetis_fmc.h b/arch/arm/src/kinetis/chip/kinetis_k20k40k60fmc.h
similarity index 97%
rename from arch/arm/src/kinetis/kinetis_fmc.h
rename to arch/arm/src/kinetis/chip/kinetis_k20k40k60fmc.h
index 66f3a390926777330a36fed3374cc2a7632741d7..8dce4d682ef0289abb74d260a66c4b7b27b4633b 100644
--- a/arch/arm/src/kinetis/kinetis_fmc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k20k40k60fmc.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_fmc.h
+ * arch/arm/src/kinetis/kinetis_k20k40k60fmc.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_FMC_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_FMC_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20K40K60FMC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20K40K60FMC_H
/************************************************************************************
* Included Files
@@ -50,13 +50,13 @@
/* Register Offsets *****************************************************************/
-#define KINETIS_FMC_PFAPR_OFFSET 0x0000 /* Flash Access Protection Register */
-#define KINETIS_FMC_PFB0CR_OFFSET 0x0004 /* Flash Bank 0 Control Register */
-#define KINETIS_FMC_PFB1CR_OFFSET 0x0008 /* Flash Bank 1 Control Register */
+#define KINETIS_FMC_PFAPR_OFFSET 0x0000 /* Flash Access Protection Register */
+#define KINETIS_FMC_PFB0CR_OFFSET 0x0004 /* Flash Bank 0 Control Register */
+#define KINETIS_FMC_PFB1CR_OFFSET 0x0008 /* Flash Bank 1 Control Register */
/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */
-#define KINETIS_FMC_TAGVD_OFFSET(w,s) (0x100+((w)<<5)+((s)<<2))
+#define KINETIS_FMC_TAGVD_OFFSET(w,s) (0x100 + ((w) << 5) + ((s) << 2))
#define KINETIS_FMC_TAGVDW0S0_OFFSET 0x0100 /* Cache Directory Storage */
#define KINETIS_FMC_TAGVDW0S1_OFFSET 0x0104 /* Cache Directory Storage */
@@ -96,8 +96,8 @@
/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7 */
-#define KINETIS_FMC_DATAU_OFFSET(w,s) (0x200+((w)<<6)+((s)<<2))
-#define KINETIS_FMC_DATAL_OFFSET(w,s) (0x204+((w)<<6)+((s)<<2))
+#define KINETIS_FMC_DATAU_OFFSET(w,s) (0x200 + ((w) << 6) + ((s) << 2))
+#define KINETIS_FMC_DATAL_OFFSET(w,s) (0x204 + ((w) << 6) + ((s) << 2))
#define KINETIS_FMC_DATAW0S0U_OFFSET 0x0200 /* Cache Data Storage (upper word) */
#define KINETIS_FMC_DATAW0S0L_OFFSET 0x0204 /* Cache Data Storage (lower word) */
@@ -386,4 +386,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FMC_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20K40K60FMC_H */
diff --git a/arch/arm/src/kinetis/kinetis_mpu.h b/arch/arm/src/kinetis/chip/kinetis_k20k40k60mpu.h
similarity index 100%
rename from arch/arm/src/kinetis/kinetis_mpu.h
rename to arch/arm/src/kinetis/chip/kinetis_k20k40k60mpu.h
diff --git a/arch/arm/src/kinetis/chip/kinetis_k20memorymap.h b/arch/arm/src/kinetis/chip/kinetis_k20memorymap.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d5aa615cd3512c74c66304030e973ea17f3a229
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_k20memorymap.h
@@ -0,0 +1,180 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_k20memorymap.h
+ *
+ * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20MEMORYMAP_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20MEMORYMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+#ifdef KINETIS_K20
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Memory Map ***********************************************************************/
+/* K20 Family
+ *
+ * The memory map for the following parts is defined in Freescale document
+ * K20P64M72SF1RM
+ */
+
+#define KINETIS_FLASH_BASE 0x00000000 /* –0x0fffffff Program flash and read-
+ * only data (Includes exception
+ * vectors in first 1024 bytes) */
+#if !defined(KINETIS_FLEXMEM_SIZE)
+# define KINETIS_FLEXNVM_BASE 0x10000000 /* –0x13ffffff FlexNVM */
+# define KINETIS_FLEXRAM_BASE 0x14000000 /* –0x17ffffff FlexRAM */
+#endif
+ /* 0x18000000 * –0x1bffffff Reserved */
+#define KINETIS_SRAML_BASE 0x1c000000 /* –0x1fffffff SRAM_L: Lower SRAM
+ * (ICODE/DCODE) */
+#define KINETIS_SRAMU_BASE 0x20000000 /* –0x200fffff SRAM_U: Upper SRAM bitband
+ * region */
+ /* 0x20100000 * –0x21ffffff Reserved */
+#define KINETIS_SALIAS_BASE 0x22000000 /* –0x23ffffff Aliased to SRAM_U bitband */
+ /* 0x24000000 * –0x3fffffff Reserved */
+#define KINETIS_BRIDGE0_BASE 0x40000000 /* –0x4007ffff Bitband region for peripheral
+ * bridge 0 (AIPS-Lite0) */
+#define KINETIS_BRIDGE1_BASE 0x40080000 /* –0x400fffff Bitband region for peripheral
+ * bridge 1 (AIPS-Lite1) */
+#define KINETIS_GPIOBB_BASE 0x400ff000 /* –0x400fffff Bitband region for general
+ * purpose input/output (GPIO) */
+ /* 0x40100000 * –0x41ffffff Reserved */
+#define KINETIS_PALIAS_BASE 0x42000000 /* –0x43ffffff Aliased to peripheral bridge
+ * (AIPS-Lite) and general purpose
+ * input/output (GPIO) bitband */
+ /* 0x44000000 * –0xdfffffff Reserved */
+#define KINETIS_PERIPH_BASE 0xe0000000 /* –0xe00fffff Private peripherals */
+ /* 0xe0100000 * –0xffffffff Reserved */
+
+/* Peripheral Bridge 0 Memory Map ***************************************************/
+
+#define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */
+#define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */
+#define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */
+#define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */
+#define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */
+#define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */
+#define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */
+#define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */
+#define KINETIS_SPI0_BASE 0x4002c000 /* SPI 0 */
+#define KINETIS_SPI1_BASE 0x4002d000 /* SPI 1 */
+#define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */
+#define KINETIS_CRC_BASE 0x40032000 /* CRC */
+#define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */
+#define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */
+#define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */
+#define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer 0 */
+#define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer 1 */
+#define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */
+#define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */
+#define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */
+#define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */
+#define KINETIS_SYSR_BASE 0x40041000 /* System register file */
+#define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */
+#define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */
+#define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */
+#define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12))
+#define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */
+#define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */
+#define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */
+#define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */
+#define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */
+#define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */
+#define KINETIS_EWM_BASE 0x40061000 /* External watchdog */
+#define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */
+#define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */
+#define KINETIS_OSC_BASE 0x40065000 /* System oscillator (OSC) */
+#define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */
+#define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */
+#define KINETIS_UART0_BASE 0x4006a000 /* UART0 */
+#define KINETIS_UART1_BASE 0x4006b000 /* UART1 */
+#define KINETIS_UART2_BASE 0x4006c000 /* UART2 */
+#define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */
+#define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */
+#define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */
+#define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */
+#define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */
+#define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */
+
+/* Peripheral Bridge 1 Memory Map ***************************************************/
+
+#define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */
+#define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */
+#define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
+#define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */
+
+#define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general
+ * purpose input/output module that shares the
+ * crossbar switch slave port with the AIPS-Lite
+ * is accessed at this address. */
+#define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6))
+#define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */
+#define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */
+#define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */
+#define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */
+#define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */
+
+/* Private Peripheral Bus (PPB) Memory Map ******************************************/
+
+#define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */
+#define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */
+#define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */
+#define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */
+#define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */
+#define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */
+#define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* KINETIS_K20 */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20MEMORYMAP_H */
diff --git a/arch/arm/src/kinetis/kinetis_k20pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k20pinmux.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_k20pinmux.h
rename to arch/arm/src/kinetis/chip/kinetis_k20pinmux.h
index a4ca3eda29b7dfd8ee96ff4d4be9b89133adf717..ca708acfdf8aa4b6c6252384a16c0c31dfd6ac05 100644
--- a/arch/arm/src/kinetis/kinetis_k20pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k20pinmux.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_k40pinmux.h
+ * arch/arm/src/kinetis/chip/kinetis_k20pinmux.h
*
- * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_K20PINMUX_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_K20PINMUX_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20PINMUX_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20PINMUX_H
/********************************************************************************************
* Included Files
@@ -349,4 +349,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_K20PINMUX_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K20PINMUX_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_k40memorymap.h b/arch/arm/src/kinetis/chip/kinetis_k40memorymap.h
new file mode 100644
index 0000000000000000000000000000000000000000..65f2788ab6c3ba84c069173531f5db7cd5387ccd
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_k40memorymap.h
@@ -0,0 +1,199 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_k40memorymap.h
+ *
+ * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K40MEMORYMAP_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K40MEMORYMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+#ifdef KINETIS_K40
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Memory Map ***********************************************************************/
+/* K40 Family
+ *
+ * The memory map for the following parts is defined in Freescale document
+ * K40P144M100SF2RM
+ */
+
+#define KINETIS_FLASH_BASE 0x00000000 /* -0x0fffffff Program flash and read-
+ * only data (Includes exception
+ * vectors in first 1024 bytes) */
+# if !defined(KINETIS_FLEXMEM_SIZE)
+# define KINETIS_FLEXNVM_BASE 0x10000000 /* -0x13ffffff FlexNVM */
+# define KINETIS_FLEXRAM_BASE 0x14000000 /* -0x17ffffff FlexRAM */
+# endif
+#define KINETIS_SRAML_BASE 0x18000000 /* -0x1fffffff SRAM_L: Lower SRAM
+ * (ICODE/DCODE) */
+#define KINETIS_SRAMU_BASE 0x20000000 /* -0x200fffff SRAM_U: Upper SRAM bitband
+ * region */
+ /* 0x20100000 * -0x21ffffff Reserved */
+#define KINETIS_SALIAS_BASE 0x22000000 /* -0x23ffffff Aliased to SRAM_U bitband */
+ /* 0x24000000 * -0x3fffffff Reserved */
+#define KINETIS_BRIDGE0_BASE 0x40000000 /* -0x4007ffff Bitband region for peripheral
+ * bridge 0 (AIPS-Lite0) */
+#define KINETIS_BRIDGE1_BASE 0x40080000 /* -0x400fffff Bitband region for peripheral
+ * bridge 1 (AIPS-Lite1) */
+#define KINETIS_GPIOBB_BASE 0x400ff000 /* -0x400fffff Bitband region for general
+ * purpose input/output (GPIO) */
+ /* 0x40100000 * -0x41ffffff Reserved */
+#define KINETIS_PALIAS_BASE 0x42000000 /* -0x43ffffff Aliased to peripheral bridge
+ * (AIPS-Lite) and general purpose
+ * input/output (GPIO) bitband */
+ /* 0x44000000 * -0x5fffffff Reserved */
+#define KINETIS_FLEXBUS_WBBASE 0x60000000 /* -0x7fffffff FlexBus (External Memory -
+ * Write-back) */
+#define KINETIS_FLEXBUS_WTBASE 0x80000000 /* -0x9fffffff FlexBus (External Memory -
+ * Write-through) */
+#define KINETIS_FLEXBUS_NXBASE 0xa0000000 /* -0xdfffffff FlexBus (External Memory -
+ * Non-executable) */
+#define KINETIS_PERIPH_BASE 0xe0000000 /* -0xe00fffff Private peripherals */
+ /* 0xe0100000 * -0xffffffff Reserved */
+
+/* Peripheral Bridge 0 Memory Map ***************************************************/
+
+#define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */
+#define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */
+#define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */
+#define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */
+#define KINETIS_FLEXBUSC_BASE 0x4000c000 /* FlexBus controller */
+#define KINETIS_MPU_BASE 0x4000d000 /* MPU */
+#define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */
+#define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */
+#define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */
+#define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */
+#define KINETIS_SPI0_BASE 0x4002c000 /* SPI 0 */
+#define KINETIS_SPI1_BASE 0x4002d000 /* SPI 1 */
+#define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */
+#define KINETIS_CRC_BASE 0x40032000 /* CRC */
+#define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */
+#define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */
+#define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */
+#define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer 0 */
+#define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer 1 */
+#define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */
+#define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */
+#define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */
+#define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */
+#define KINETIS_SYSR_BASE 0x40041000 /* System register file */
+#define KINETIS_DRYICE_BASE 0x40042000 /* DryIce */
+#define KINETIS_DRYICESS_BASE 0x40043000 /* DryIce secure storage */
+#define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */
+#define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */
+#define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */
+#define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12))
+#define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */
+#define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */
+#define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */
+#define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */
+#define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */
+#define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */
+#define KINETIS_EWM_BASE 0x40061000 /* External watchdog */
+#define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */
+#define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */
+#define KINETIS_OSC_BASE 0x40065000 /* System oscillator (OSC) */
+#define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */
+#define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */
+#define KINETIS_UART0_BASE 0x4006a000 /* UART0 */
+#define KINETIS_UART1_BASE 0x4006b000 /* UART1 */
+#define KINETIS_UART2_BASE 0x4006c000 /* UART2 */
+#define KINETIS_UART3_BASE 0x4006d000 /* UART3 */
+#define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */
+#define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */
+#define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */
+#define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */
+#define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */
+#define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */
+
+/* Peripheral Bridge 1 Memory Map ***************************************************/
+
+#define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */
+#define KINETIS_CAN1_BASE 0x400a4000 /* FlexCAN 1 */
+#define KINETIS_SPI2_BASE 0x400ac000 /* SPI 2 */
+#define KINETIS_SDHC_BASE 0x400b1000 /* SDHC */
+#define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */
+#define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
+#define KINETIS_SLCD_BASE 0x400be000 /* Segment LCD */
+#define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */
+#define KINETIS_DAC1_BASE 0x400cd000 /* 12-bit digital-to-analog converter (DAC) 1 */
+#define KINETIS_UART4_BASE 0x400ea000 /* UART4 */
+#define KINETIS_UART5_BASE 0x400eb000 /* UART5 */
+#define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general
+ * purpose input/output module that shares the
+ * crossbar switch slave port with the AIPS-Lite
+ * is accessed at this address. */
+#define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6))
+#define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */
+#define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */
+#define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */
+#define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */
+#define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */
+
+/* Private Peripheral Bus (PPB) Memory Map ******************************************/
+
+#define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */
+#define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */
+#define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */
+#define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */
+#define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */
+#define KINETIS_ETM_BASE 0xe0041000 /* Embedded Trace Macrocell (ETM) */
+#define KINETIS_ETB_BASE 0xe0042000 /* Embedded Trace Buffer (ETB) */
+#define KINETIS_TFUN_BASE 0xe0043000 /* Embedded Trace Funnel */
+#define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */
+#define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* KINETIS_K40 */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K40MEMORYMAP_H */
diff --git a/arch/arm/src/kinetis/kinetis_k40pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k40pinmux.h
similarity index 99%
rename from arch/arm/src/kinetis/kinetis_k40pinmux.h
rename to arch/arm/src/kinetis/chip/kinetis_k40pinmux.h
index 9798eda6be1522e19bf0b7fc2bc1d176a61a0fed..7083b0caf7c5dccde1573fcc508ffd8e47ef9a17 100644
--- a/arch/arm/src/kinetis/kinetis_k40pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k40pinmux.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_k40pinmux.h
+ * arch/arm/src/kinetis/chip/kinetis_k40pinmux.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_K40PINMUX_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_K40PINMUX_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K40PINMUX_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K40PINMUX_H
/********************************************************************************************
* Included Files
@@ -515,4 +515,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_K40PINMUX_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K40PINMUX_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_k60memorymap.h b/arch/arm/src/kinetis/chip/kinetis_k60memorymap.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b00303ef7b245875c7460f2273b48d48f4609be
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_k60memorymap.h
@@ -0,0 +1,196 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_k60memorymap.h
+ *
+ * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K60MEMORYMAP_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K60MEMORYMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+#ifdef KINETIS_K64
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Memory Map ***********************************************************************/
+/* K60 Family
+ *
+ * The memory map for the following parts is defined in Freescale document
+ * K60P144M100SF2RM
+ */
+
+#define KINETIS_FLASH_BASE 0x00000000 /* -0x0fffffff Program flash and read-
+ * only data (Includes exception
+ * vectors in first 1024 bytes) */
+#if !defined(KINETIS_FLEXMEM_SIZE)
+# define KINETIS_FLEXNVM_BASE 0x10000000 /* -0x13ffffff FlexNVM */
+# define KINETIS_FLEXRAM_BASE 0x14000000 /* -0x17ffffff FlexRAM */
+#endif
+#define KINETIS_SRAML_BASE 0x18000000 /* -0x1fffffff SRAM_L: Lower SRAM
+ * (ICODE/DCODE) */
+#define KINETIS_SRAMU_BASE 0x20000000 /* -0x200fffff SRAM_U: Upper SRAM bitband
+ * region */
+ /* 0x20100000 * -0x21ffffff Reserved */
+#define KINETIS_SALIAS_BASE 0x22000000 /* -0x23ffffff Aliased to SRAM_U bitband */
+ /* 0x24000000 * -0x3fffffff Reserved */
+#define KINETIS_BRIDGE0_BASE 0x40000000 /* -0x4007ffff Bitband region for peripheral
+ * bridge 0 (AIPS-Lite0) */
+#define KINETIS_BRIDGE1_BASE 0x40080000 /* -0x400fffff Bitband region for peripheral
+ * bridge 1 (AIPS-Lite1) */
+#define KINETIS_GPIOBB_BASE 0x400ff000 /* -0x400fffff Bitband region for general
+ * purpose input/output (GPIO) */
+ /* 0x40100000 * -0x41ffffff Reserved */
+#define KINETIS_PALIAS_BASE 0x42000000 /* -0x43ffffff Aliased to peripheral bridge
+ * (AIPS-Lite) and general purpose
+ * input/output (GPIO) bitband */
+ /* 0x44000000 * -0x5fffffff Reserved */
+#define KINETIS_FLEXBUS_BASE 0x60000000 /* -0x7fffffff FlexBus */
+#define KINETIS_PERIPH_BASE 0xe0000000 /* -0xe00fffff Private peripherals */
+ /* 0xe0100000 * -0xffffffff Reserved */
+
+/* Peripheral Bridge 0 Memory Map ***************************************************/
+
+#define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */
+#define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */
+#define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */
+#define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */
+#define KINETIS_FLEXBUSC_BASE 0x4000c000 /* FlexBus controller */
+#define KINETIS_MPU_BASE 0x4000d000 /* MPU */
+#define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */
+#define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */
+#define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */
+#define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */
+#define KINETIS_SPI0_BASE 0x4002c000 /* DSPI 0 */
+#define KINETIS_SPI1_BASE 0x4002d000 /* DSPI 1 */
+#define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */
+#define KINETIS_CRC_BASE 0x40032000 /* CRC */
+#define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */
+#define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */
+#define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */
+#define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer (FTM) 0 */
+#define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer (FTM) 1 */
+#define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */
+#define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */
+#define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */
+#define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */
+#define KINETIS_SYSR_BASE 0x40041000 /* System register file */
+#define KINETIS_DRYICE_BASE 0x40042000 /* DryIce */
+#define KINETIS_DRYICESS_BASE 0x40043000 /* DryIce secure storage */
+#define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */
+#define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */
+#define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */
+#define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12))
+#define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */
+#define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */
+#define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */
+#define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */
+#define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */
+#define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */
+#define KINETIS_EWM_BASE 0x40061000 /* External watchdog */
+#define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */
+#define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */
+#define KINETIS_OSC_BASE 0x40065000 /* System oscillator (XOSC) */
+#define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */
+#define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */
+#define KINETIS_UART0_BASE 0x4006a000 /* UART0 */
+#define KINETIS_UART1_BASE 0x4006b000 /* UART1 */
+#define KINETIS_UART2_BASE 0x4006c000 /* UART2 */
+#define KINETIS_UART3_BASE 0x4006d000 /* UART3 */
+#define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */
+#define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */
+#define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */
+#define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */
+#define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */
+#define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */
+
+/* Peripheral Bridge 1 Memory Map ***************************************************/
+
+#define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */
+#define KINETIS_RNGB_BASE 0x400a0000 /* Random number generator (RNGB) */
+#define KINETIS_CAN1_BASE 0x400a4000 /* FlexCAN 1 */
+#define KINETIS_SPI2_BASE 0x400ac000 /* DSPI 2 */
+#define KINETIS_SDHC_BASE 0x400b1000 /* SDHC */
+#define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */
+#define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
+#define KINETIS_EMAC_BASE 0x400c0000 /* Ethernet MAC and IEEE 1588 timers */
+#define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */
+#define KINETIS_DAC1_BASE 0x400cd000 /* 12-bit digital-to-analog converter (DAC) 1 */
+#define KINETIS_UART4_BASE 0x400ea000 /* UART4 */
+#define KINETIS_UART5_BASE 0x400eb000 /* UART5 */
+#define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general
+ * purpose input/output module that shares the
+ * crossbar switch slave port with the AIPS-Lite
+ * is accessed at this address. */
+#define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6))
+#define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */
+#define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */
+#define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */
+#define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */
+#define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */
+
+/* Private Peripheral Bus (PPB) Memory Map ******************************************/
+
+#define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */
+#define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */
+#define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */
+#define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */
+#define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */
+#define KINETIS_ETM_BASE 0xe0041000 /* Embedded Trace Macrocell (ETM) */
+#define KINETIS_ETB_BASE 0xe0042000 /* Embedded Trace Buffer (ETB) */
+#define KINETIS_TFUN_BASE 0xe0043000 /* Embedded Trace Funnel */
+#define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */
+#define KINETIS_MMCAU_BASE 0xe0081000 /* Memory Mapped Cryptographic Acceleration Unit (MMCAU) */
+#define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* KINETIS_K64 */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K60MEMORYMAP_H */
diff --git a/arch/arm/src/kinetis/kinetis_k60pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k60pinmux.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_k60pinmux.h
rename to arch/arm/src/kinetis/chip/kinetis_k60pinmux.h
index 7fd69a0813e7f3c3bad938e38e69b5a77deb1719..4e7619c18fb38e9fabe5d9239b3469c96d623a9d 100644
--- a/arch/arm/src/kinetis/kinetis_k60pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k60pinmux.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_k60pinset.h
+ * arch/arm/src/kinetis/chip/kinetis_k60pinset.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_K60PINMUX_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_K60PINMUX_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K60PINMUX_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K60PINMUX_H
/********************************************************************************************
* Included Files
@@ -83,12 +83,12 @@
#define PIN_FTM0_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN4)
#define PIN_NMI (PIN_ALT7 | PIN_PORTA | PIN4)
#define PIN_FTM0_CH2_1 (PIN_ALT3 | PIN_PORTA | PIN5)
-#if 0
+#ifdef CONFIG_KINETIS_ENET_NORXER
+# define PIN_RMII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
+# define PIN_MII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
+#else
# define PIN_RMII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
# define PIN_MII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
-#else
-# define PIN_RMII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
-# define PIN_MII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
#endif
#define PIN_CMP2_OUT_1 (PIN_ALT5 | PIN_PORTA | PIN5)
#define PIN_I2S0_RX_BCLK_1 (PIN_ALT6 | PIN_PORTA | PIN5)
@@ -174,7 +174,11 @@
#define PIN_TSI0_CH0 (PIN_ANALOG | PIN_PORTB | PIN0)
#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
#define PIN_FTM1_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN0)
-#define PIN_RMII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
+#ifdef CONFIG_KINETIS_ENET_MDIOPULLUP
+# define PIN_RMII0_MDIO (PIN_ALT4_PULLUP | PIN_PORTB | PIN0)
+#else
+# define PIN_RMII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
+#endif
#define PIN_MII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
#define PIN_FTM1_QD_PHA_3 (PIN_ALT6 | PIN_PORTB | PIN0)
#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
@@ -479,4 +483,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_K60PINMUX_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K60PINMUX_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_k64fmc.h b/arch/arm/src/kinetis/chip/kinetis_k64fmc.h
new file mode 100644
index 0000000000000000000000000000000000000000..036e38f1299075c3268146a460b03119bfd098dc
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_k64fmc.h
@@ -0,0 +1,293 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/kinetis_k64fmc.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K64FMC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K64FMC_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Register Offsets *****************************************************************/
+
+#define KINETIS_FMC_PFAPR_OFFSET 0x0000 /* Flash Access Protection Register */
+#define KINETIS_FMC_PFB0CR_OFFSET 0x0004 /* Flash Bank 0 Control Register */
+#define KINETIS_FMC_PFB1CR_OFFSET 0x0008 /* Flash Bank 1 Control Register */
+
+/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */
+
+#define KINETIS_FMC_TAGVD_OFFSET(w,s) (0x100 + ((w) << 5) + ((s) << 2))
+
+#define KINETIS_FMC_TAGVDW0S0_OFFSET 0x0100 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW0S1_OFFSET 0x0104 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW0S2_OFFSET 0x0108 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW0S3_OFFSET 0x010c /* Cache Directory Storage */
+
+#define KINETIS_FMC_TAGVDW1S0_OFFSET 0x0110 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW1S1_OFFSET 0x0114 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW1S2_OFFSET 0x0118 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW1S3_OFFSET 0x011c /* Cache Directory Storage */
+
+#define KINETIS_FMC_TAGVDW2S0_OFFSET 0x0120 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW2S1_OFFSET 0x0124 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW2S2_OFFSET 0x0128 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW2S3_OFFSET 0x012c /* Cache Directory Storage */
+
+#define KINETIS_FMC_TAGVDW3S0_OFFSET 0x0130 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW3S1_OFFSET 0x0134 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW3S2_OFFSET 0x0138 /* Cache Directory Storage */
+#define KINETIS_FMC_TAGVDW3S3_OFFSET 0x013c /* Cache Directory Storage */
+
+/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7 */
+
+#define KINETIS_FMC_DATAU_OFFSET(w,s) (0x200 + ((w) << 6) + ((s) << 2))
+#define KINETIS_FMC_DATAL_OFFSET(w,s) (0x204 + ((w) << 6) + ((s) << 2))
+
+#define KINETIS_FMC_DATAW0S0U_OFFSET 0x0200 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW0S0L_OFFSET 0x0204 /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW0S1U_OFFSET 0x0208 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW0S1L_OFFSET 0x020c /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW0S2U_OFFSET 0x0210 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW0S2L_OFFSET 0x0214 /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW0S3U_OFFSET 0x0218 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW0S3L_OFFSET 0x021c /* Cache Data Storage (lower word) */
+
+#define KINETIS_FMC_DATAW1S0U_OFFSET 0x0220 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW1S0L_OFFSET 0x0224 /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW1S1U_OFFSET 0x0228 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW1S1L_OFFSET 0x022c /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW1S2U_OFFSET 0x0230 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW1S2L_OFFSET 0x0234 /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW1S3U_OFFSET 0x0238 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW1S3L_OFFSET 0x023c /* Cache Data Storage (lower word) */
+
+#define KINETIS_FMC_DATAW2S0U_OFFSET 0x0240 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW2S0L_OFFSET 0x0244 /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW2S1U_OFFSET 0x0248 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW2S1L_OFFSET 0x024c /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW2S2U_OFFSET 0x0250 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW2S2L_OFFSET 0x0254 /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW2S3U_OFFSET 0x0258 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW2S3L_OFFSET 0x025c /* Cache Data Storage (lower word) */
+
+#define KINETIS_FMC_DATAW3S0U_OFFSET 0x0260 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW3S0L_OFFSET 0x0264 /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW3S1U_OFFSET 0x0268 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW3S1L_OFFSET 0x026c /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW3S2U_OFFSET 0x0270 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW3S2L_OFFSET 0x0274 /* Cache Data Storage (lower word) */
+#define KINETIS_FMC_DATAW3S3U_OFFSET 0x0278 /* Cache Data Storage (upper word) */
+#define KINETIS_FMC_DATAW3S3L_OFFSET 0x027c /* Cache Data Storage (lower word) */
+
+/* Register Addresses ***************************************************************/
+
+#define KINETIS_FMC_PFAPR (KINETIS_FMC_BASE+KINETIS_FMC_PFAPR_OFFSET)
+#define KINETIS_FMC_PFB0CR (KINETIS_FMC_BASE+KINETIS_FMC_PFB0CR_OFFSET)
+#define KINETIS_FMC_PFB1CR (KINETIS_FMC_BASE+KINETIS_FMC_PFB1CR_OFFSET)
+
+/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */
+
+#define KINETIS_FMC_TAGVD(w,s) (KINETIS_FMC_BASE+KINETIS_FMC_TAGVD_OFFSET(w,s))
+
+#define KINETIS_FMC_TAGVDW0S0 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S0_OFFSET)
+#define KINETIS_FMC_TAGVDW0S1 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S1_OFFSET)
+#define KINETIS_FMC_TAGVDW0S2 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S2_OFFSET)
+#define KINETIS_FMC_TAGVDW0S3 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW0S3_OFFSET)
+
+#define KINETIS_FMC_TAGVDW1S0 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S0_OFFSET)
+#define KINETIS_FMC_TAGVDW1S1 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S1_OFFSET)
+#define KINETIS_FMC_TAGVDW1S2 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S2_OFFSET)
+#define KINETIS_FMC_TAGVDW1S3 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW1S3_OFFSET)
+
+#define KINETIS_FMC_TAGVDW2S0 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S0_OFFSET)
+#define KINETIS_FMC_TAGVDW2S1 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S1_OFFSET)
+#define KINETIS_FMC_TAGVDW2S2 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S2_OFFSET)
+#define KINETIS_FMC_TAGVDW2S3 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW2S3_OFFSET)
+
+#define KINETIS_FMC_TAGVDW3S0 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S0_OFFSET)
+#define KINETIS_FMC_TAGVDW3S1 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S1_OFFSET)
+#define KINETIS_FMC_TAGVDW3S2 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S2_OFFSET)
+#define KINETIS_FMC_TAGVDW3S3 (KINETIS_FMC_BASE+KINETIS_FMC_TAGVDW3S3_OFFSET)
+
+/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7 */
+
+#define KINETIS_FMC_DATAU(w,s) (KINETIS_FMC_BASE+KINETIS_FMC_DATAU_OFFSET(w,s))
+#define KINETIS_FMC_DATAL(w,s) (KINETIS_FMC_BASE+KINETIS_FMC_DATAL_OFFSET(w,s))
+
+#define KINETIS_FMC_DATAW0S0U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S0U_OFFSET)
+#define KINETIS_FMC_DATAW0S0L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S0L_OFFSET)
+#define KINETIS_FMC_DATAW0S1U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S1U_OFFSET)
+#define KINETIS_FMC_DATAW0S1L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S1L_OFFSET)
+#define KINETIS_FMC_DATAW0S2U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S2U_OFFSET)
+#define KINETIS_FMC_DATAW0S2L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S2L_OFFSET)
+#define KINETIS_FMC_DATAW0S3U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S3U_OFFSET)
+#define KINETIS_FMC_DATAW0S3L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW0S3L_OFFSET)
+
+#define KINETIS_FMC_DATAW1S0U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S0U_OFFSET)
+#define KINETIS_FMC_DATAW1S0L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S0L_OFFSET)
+#define KINETIS_FMC_DATAW1S1U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S1U_OFFSET)
+#define KINETIS_FMC_DATAW1S1L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S1L_OFFSET)
+#define KINETIS_FMC_DATAW1S2U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S2U_OFFSET)
+#define KINETIS_FMC_DATAW1S2L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S2L_OFFSET)
+#define KINETIS_FMC_DATAW1S3U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S3U_OFFSET)
+#define KINETIS_FMC_DATAW1S3L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW1S3L_OFFSET)
+
+#define KINETIS_FMC_DATAW2S0U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S0U_OFFSET)
+#define KINETIS_FMC_DATAW2S0L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S0L_OFFSET)
+#define KINETIS_FMC_DATAW2S1U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S1U_OFFSET)
+#define KINETIS_FMC_DATAW2S1L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S1L_OFFSET)
+#define KINETIS_FMC_DATAW2S2U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S2U_OFFSET)
+#define KINETIS_FMC_DATAW2S2L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S2L_OFFSET)
+#define KINETIS_FMC_DATAW2S3U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S3U_OFFSET)
+#define KINETIS_FMC_DATAW2S3L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW2S3L_OFFSET)
+
+#define KINETIS_FMC_DATAW3S0U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S0U_OFFSET)
+#define KINETIS_FMC_DATAW3S0L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S0L_OFFSET)
+#define KINETIS_FMC_DATAW3S1U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S1U_OFFSET)
+#define KINETIS_FMC_DATAW3S1L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S1L_OFFSET)
+#define KINETIS_FMC_DATAW3S2U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S2U_OFFSET)
+#define KINETIS_FMC_DATAW3S2L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S2L_OFFSET)
+#define KINETIS_FMC_DATAW3S3U (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S3U_OFFSET)
+#define KINETIS_FMC_DATAW3S3L (KINETIS_FMC_BASE+KINETIS_FMC_DATAW3S3L_OFFSET)
+
+/* Register Bit Definitions *********************************************************/
+
+/* Flash Access Protection Register */
+/* Access protection bits (all masters) */
+
+#define FMC_PFAPR_NONE 0 /* No access may be performed by this master */
+#define FMC_PFAPR_RDONLY 1 /* Only read accesses may be performed by this master */
+#define FMC_PFAPR_WRONLY 2 /* Only write accesses may be performed by this master */
+#define FMC_PFAPR_RDWR 3 /* Both read and write accesses may be performed by this master */
+
+#define FMC_PFAPR_M0AP_SHIFT (0) /* Bits 0-1: Master 0 Access Protection */
+#define FMC_PFAPR_M0AP_MASK (3 << FMC_PFAPR_M0AP_SHIFT)
+#define FMC_PFAPR_M1AP_SHIFT (2) /* Bits 2-3: Master 1 Access Protection */
+#define FMC_PFAPR_M1AP_MASK (3 << FMC_PFAPR_M1AP_SHIFT)
+#define FMC_PFAPR_M2AP_SHIFT (4) /* Bits 4-5: Master 2 Access Protection */
+#define FMC_PFAPR_M2AP_MASK (3 << FMC_PFAPR_M2AP_SHIFT)
+#define FMC_PFAPR_M3AP_SHIFT (6) /* Bits 6-7: Master 3 Access Protection */
+#define FMC_PFAPR_M3AP_MASK (3 << FMC_PFAPR_M3AP_SHIFT)
+#define FMC_PFAPR_M4AP_SHIFT (8) /* Bits 8-9: Master 4 Access Protection */
+#define FMC_PFAPR_M4AP_MASK (3 << FMC_PFAPR_M4AP_SHIFT)
+#define FMC_PFAPR_M5AP_SHIFT (10) /* Bits 10-11: Master 5 Access Protection */
+#define FMC_PFAPR_M5AP_MASK (3 << FMC_PFAPR_M5AP_SHIFT)
+#define FMC_PFAPR_M6AP_SHIFT (12) /* Bits 12-13: Master 6 Access Protection */
+#define FMC_PFAPR_M6AP_MASK (3 << FMC_PFAPR_M6AP_SHIFT)
+#define FMC_PFAPR_M7AP_SHIFT (14) /* Bits 14-15: Master 7 Access Protection */
+#define FMC_PFAPR_M7AP_MASK (3 << FMC_PFAPR_M7AP_SHIFT)
+#define FMC_PFAPR_M0PFD (1 << 16) /* Bit 16: Master 0 Prefetch Disable */
+#define FMC_PFAPR_M1PFD (1 << 17) /* Bit 17: Master 1 Prefetch Disable */
+#define FMC_PFAPR_M2PFD (1 << 18) /* Bit 18: Master 2 Prefetch Disable */
+#define FMC_PFAPR_M3PFD (1 << 19) /* Bit 19: Master 3 Prefetch Disable */
+#define FMC_PFAPR_M4PFD (1 << 20) /* Bit 20: Master 4 Prefetch Disable */
+#define FMC_PFAPR_M5PFD (1 << 21) /* Bit 21: Master 5 Prefetch Disable */
+#define FMC_PFAPR_M6PFD (1 << 22) /* Bit 22: Master 6 Prefetch Disable */
+#define FMC_PFAPR_M7PFD (1 << 23) /* Bit 23: Master 7 Prefetch Disable */
+ /* Bits 24-31: Reserved */
+/* Flash Bank 0 Control Register */
+
+#define FMC_PFB0CR_B0SEBE (1 << 0) /* Bit 0: Bank 0 Single Entry Buffer Enable */
+#define FMC_PFB0CR_B0IPE (1 << 1) /* Bit 1: Bank 0 Instruction Prefetch Enable */
+#define FMC_PFB0CR_B0DPE (1 << 2) /* Bit 2: Bank 0 Data Prefetch Enable */
+#define FMC_PFB0CR_B0ICE (1 << 3) /* Bit 3: Bank 0 Instruction Cache Enable */
+#define FMC_PFB0CR_B0DCE (1 << 4) /* Bit 4: Bank 0 Data Cache Enable */
+#define FMC_PFB0CR_CRC_SHIFT (5) /* Bits 5-7: Cache Replacement Control */
+#define FMC_PFB0CR_CRC_MASK (7 << FMC_PFB0CR_CRC_SHIFT)
+# define FMC_PFB0CR_CRC_ALL (0 << FMC_PFB0CR_CRC_SHIFT) /* LRU all four ways */
+# define FMC_PFB0CR_CRC_I01D23 (2 << FMC_PFB0CR_CRC_SHIFT) /* LRU ifetches 0-1 data 2-3 */
+# define FMC_PFB0CR_CRC_I012D3 (3 << FMC_PFB0CR_CRC_SHIFT) /* LRU ifetches 0-3 data 3 */
+ /* Bits 8-16: Reserved */
+#define FMC_PFB0CR_B0MW_SHIFT (17) /* Bits 17-18: Bank 0 Memory Width */
+#define FMC_PFB0CR_B0MW_MASK (3 << FMC_PFB0CR_B0MW_SHIFT)
+# define FMC_PFB0CR_B0MW_32BITS (0 << FMC_PFB0CR_B0MW_SHIFT) /* 32 bits */
+# define FMC_PFB0CR_B0MW_64BITS (1 << FMC_PFB0CR_B0MW_SHIFT) /* 64 bits */
+#define FMC_PFB0CR_S_B_INV (1 << 19) /* Bit 19: Invalidate Prefetch Speculation Buffer */
+#define FMC_PFB0CR_CINV_WAY_SHIFT (20) /* Bits 20-23: Cache Invalidate Way x */
+#define FMC_PFB0CR_CINV_WAY_MASK (15 << FMC_PFB0CR_CINV_WAY_SHIFT)
+#define FMC_PFB0CR_CLCK_WAY_SHIFT (24) /* Bits 24-27: Cache Lock Way x */
+#define FMC_PFB0CR_CLCK_WAY_MASK (15 << FMC_PFB0CR_CLCK_WAY_SHIFT)
+#define FMC_PFB0CR_B0RWSC_SHIFT (28) /* Bits 28-31: Bank 0 Read Wait State Control */
+#define FMC_PFB0CR_B0RWSC_MASK (15 << FMC_PFB0CR_B0RWSC_SHIFT)
+
+/* Flash Bank 1 Control Register */
+
+#define FMC_PFB1CR_B1SEBE (1 << 0) /* Bit 0: Bank 1 Single Entry Buffer Enable */
+#define FMC_PFB1CR_B1IPE (1 << 1) /* Bit 1: Bank 1 Instruction Prefetch Enable */
+#define FMC_PFB1CR_B1DPE (1 << 2) /* Bit 2: Bank 1 Data Prefetch Enable */
+#define FMC_PFB1CR_B1ICE (1 << 3) /* Bit 3: Bank 1 Instruction Cache Enable */
+#define FMC_PFB1CR_B1DCE (1 << 4) /* Bit 4: Bank 1 Data Cache Enable */
+ /* Bits 5-16: Reserved */
+#define FMC_PFB1CR_B1MW_SHIFT (17) /* Bits 17-18: Bank 1 Memory Width */
+#define FMC_PFB1CR_B1MW_MASK (3 << FMC_PFB1CR_B1MW_SHIFT)
+# define FMC_PFB1CR_B1MW_32BITS (0 << FMC_PFB1CR_B1MW_SHIFT) /* 32 bits */
+# define FMC_PFB1CR_B1MW_64BITS (1 << FMC_PFB1CR_B1MW_SHIFT) /* 64 bits */
+ /* Bits 19-27: Reserved */
+#define FMC_PFB1CR_B1RWSC_SHIFT (28) /* Bits 28-31: Bank 1 Read Wait State Control */
+#define FMC_PFB1CR_B1RWSC_MASK (15 << FMC_PFB1CR_B0RWSC_SHIFT)
+
+/* Cache Directory Storage for way=w and set=s, w=0..3, s=0..7 */
+
+#define FMC_TAGVD_VALID (1 << 0) /* Bit 0: 1-bit valid for cache entry */
+ /* Bits 1-4: Reserved */
+#define FMC_TAGVD_TAG_SHIFT (5) /* Bits 5-18: 13-bit tag for cache entry */
+#define FMC_TAGVD_TAG_MASK (0x1fff << FMC_TAGVD_TAG_SHIFT)
+ /* Bits 19-31: Reserved */
+
+/* Cache Data Storage (upper and lower) for way=w and set=s, w=0..3, s=0..7.
+ * 64-bit data in two 32-bit registers.
+ */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K64FMC_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_k64memorymap.h b/arch/arm/src/kinetis/chip/kinetis_k64memorymap.h
new file mode 100644
index 0000000000000000000000000000000000000000..235343de89dca36385c028a03ea5223e80c9903b
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_k64memorymap.h
@@ -0,0 +1,213 @@
+/************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_k64memorymap.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K64MEMORYMAP_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K64MEMORYMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+#ifdef KINETIS_K64
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Memory Map ***********************************************************************/
+/* K64 Family
+ *
+ * The memory map for the following parts is defined in NXP document
+ * K64P144M120SF5RM.pdf
+ */
+
+#if defined(CONFIG_ARCH_CHIP_MK64FX512VLL12) || defined(CONFIG_ARCH_CHIP_MK64FN1M0VLL12) || \
+ defined(CONFIG_ARCH_CHIP_MK64FX512VDC12) || defined(CONFIG_ARCH_CHIP_MK64FN1M0VDC12) || \
+ defined(CONFIG_ARCH_CHIP_MK64FX512VLQ12) || defined(CONFIG_ARCH_CHIP_MK64FX512VMD12) || \
+ defined(CONFIG_ARCH_CHIP_MK64FN1M0VLQ12) || defined(CONFIG_ARCH_CHIP_MK64FN1M0VMD12)
+
+# define KINETIS_FLASH_BASE 0x00000000 /* -0x0fffffff Program flash and read-
+ * only data (Includes exception
+ * vectors in first 1024 bytes) */
+# if !defined(KINETIS_FLEXMEM_SIZE)
+# define KINETIS_FLEXNVM_BASE 0x10000000 /* -0x13ffffff FlexNVM */
+# define KINETIS_FLEXRAM_BASE 0x14000000 /* -0x17ffffff FlexRAM */
+# endif
+# define KINETIS_SRAML_BASE 0x18000000 /* -0x1fffffff SRAM_L: Lower SRAM
+ * (ICODE/DCODE) */
+# define KINETIS_SRAMU_BASE 0x20000000 /* -0x200fffff SRAM_U: Upper SRAM bitband
+ * region */
+ /* 0x20100000 * -0x21ffffff Reserved */
+# define KINETIS_SALIAS_BASE 0x22000000 /* -0x23ffffff Aliased to SRAM_U bitband */
+ /* 0x24000000 * -0x3fffffff Reserved */
+# define KINETIS_BRIDGE0_BASE 0x40000000 /* -0x4007ffff Bitband region for peripheral
+ * bridge 0 (AIPS-Lite0) */
+# define KINETIS_BRIDGE1_BASE 0x40080000 /* -0x400fffff Bitband region for peripheral
+ * bridge 1 (AIPS-Lite1) */
+# define KINETIS_GPIOBB_BASE 0x400ff000 /* -0x400fffff Bitband region for general
+ * purpose input/output (GPIO) */
+ /* 0x40100000 * -0x41ffffff Reserved */
+# define KINETIS_PALIAS_BASE 0x42000000 /* -0x43ffffff Aliased to peripheral bridge
+ * (AIPS-Lite) and general purpose
+ * input/output (GPIO) bitband */
+ /* 0x44000000 * -0x5fffffff Reserved */
+# define KINETIS_FLEXBUS_BASE 0x60000000 /* -0x7fffffff FlexBus */
+# define KINETIS_PERIPH_BASE 0xe0000000 /* -0xe00fffff Private peripherals */
+ /* 0xe0100000 * -0xffffffff Reserved */
+
+/* Peripheral Bridge 0 Memory Map ***************************************************/
+
+# define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */
+# define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */
+# define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */
+# define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */
+# define KINETIS_FLEXBUSC_BASE 0x4000c000 /* FlexBus controller */
+# define KINETIS_MPU_BASE 0x4000d000 /* MPU */
+# define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */
+# define KINETIS_FTFE_BASE 0x40020000 /* Flash memory */
+# define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */
+# define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */
+# define KINETIS_SPI0_BASE 0x4002c000 /* DSPI 0 */
+# define KINETIS_SPI1_BASE 0x4002d000 /* DSPI 1 */
+# define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */
+# define KINETIS_CRC_BASE 0x40032000 /* CRC */
+# define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */
+# define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */
+# define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */
+# define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer (FTM) 0 */
+# define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer (FTM) 1 */
+# define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */
+# define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */
+# define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */
+# define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */
+# define KINETIS_SYSR_BASE 0x40041000 /* System register file */
+# define KINETIS_DRYICE_BASE 0x40042000 /* DryIce */
+# define KINETIS_DRYICESS_BASE 0x40043000 /* DryIce secure storage */
+# define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */
+# define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */
+# define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */
+# define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12))
+# define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */
+# define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */
+# define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */
+# define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */
+# define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */
+# define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */
+# define KINETIS_EWM_BASE 0x40061000 /* External watchdog */
+# define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */
+# define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */
+# define KINETIS_OSC_BASE 0x40065000 /* System oscillator (XOSC) */
+# define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */
+# define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */
+# define KINETIS_I2C2_BASE 0x400E6000 /* I2C 2 */
+# define KINETIS_UART0_BASE 0x4006a000 /* UART0 */
+# define KINETIS_UART1_BASE 0x4006b000 /* UART1 */
+# define KINETIS_UART2_BASE 0x4006c000 /* UART2 */
+# define KINETIS_UART3_BASE 0x4006d000 /* UART3 */
+# define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */
+# define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */
+# define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */
+# define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */
+# define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */
+# define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */
+
+/* Peripheral Bridge 1 Memory Map ***************************************************/
+
+# define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */
+# define KINETIS_RNGB_BASE 0x400a0000 /* Random number generator (RNGB) */
+# define KINETIS_CAN1_BASE 0x400a4000 /* FlexCAN 1 */
+# define KINETIS_SPI2_BASE 0x400ac000 /* DSPI 2 */
+# define KINETIS_SDHC_BASE 0x400b1000 /* SDHC */
+# define KINETIS_FTM2_BASE 0x4003a000 /* FlexTimer 2 */
+# define KINETIS_FTM3_BASE 0x400b9000 /* FlexTimer 3 */
+# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
+# define KINETIS_EMAC_BASE 0x400c0000 /* Ethernet MAC and IEEE 1588 timers */
+# define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */
+# define KINETIS_DAC1_BASE 0x400cd000 /* 12-bit digital-to-analog converter (DAC) 1 */
+# define KINETIS_UART4_BASE 0x400ea000 /* UART4 */
+# define KINETIS_UART5_BASE 0x400eb000 /* UART5 */
+# define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general
+ * purpose input/output module that shares the
+ * crossbar switch slave port with the AIPS-Lite
+ * is accessed at this address. */
+# define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6))
+# define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */
+# define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */
+# define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */
+# define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */
+# define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */
+
+/* Private Peripheral Bus (PPB) Memory Map ******************************************/
+
+# define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */
+# define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */
+# define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */
+# define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */
+# define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */
+# define KINETIS_ETM_BASE 0xe0041000 /* Embedded Trace Macrocell (ETM) */
+# define KINETIS_ETB_BASE 0xe0042000 /* Embedded Trace Buffer (ETB) */
+# define KINETIS_TFUN_BASE 0xe0043000 /* Embedded Trace Funnel */
+# define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */
+# define KINETIS_MMCAU_BASE 0xe0081000 /* Memory Mapped Cryptographic Acceleration Unit (MMCAU) */
+# define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */
+
+#else
+ /* The memory map for other parts is defined in other documents and may or may not
+ * be the same as above (the family members are all very similar) This error just
+ * means that you have to look at the document and determine for yourself if the
+ * memory map is the same.
+ */
+
+# error "No memory map for this K64 part"
+#endif
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* KINETIS_K64 */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_K64MEMORYMAP_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_k64mpu.h b/arch/arm/src/kinetis/chip/kinetis_k64mpu.h
new file mode 100644
index 0000000000000000000000000000000000000000..808ff15be220fd21526815e5ed769eff8f95e638
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_k64mpu.h
@@ -0,0 +1,358 @@
+/****************************************************************************************************
+ * arch/arm/src/kinetis/kinetis_mpu.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_KINETIS_MPU_H
+#define __ARCH_ARM_SRC_KINETIS_KINETIS_MPU_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+
+/* Register Offsets *********************************************************************************/
+
+#define KINETIS_MPU_CESR_OFFSET 0x0000 /* Control/Error Status Register */
+
+#define KINETIS_MPU_EAR_OFFSET(n) (0x0010+((n)<<3)) /* Error Address Register, Slave Port n */
+#define KINETIS_MPU_EDR_OFFSET(n) (0x0014+((n)<<3)) /* Error Detail Register, Slave Port n */
+
+#define KINETIS_MPU_EAR0_OFFSET 0x0010 /* Error Address Register, Slave Port 0 */
+#define KINETIS_MPU_EDR0_OFFSET 0x0014 /* Error Detail Register, Slave Port 0 */
+#define KINETIS_MPU_EAR1_OFFSET 0x0018 /* Error Address Register, Slave Port 1 */
+#define KINETIS_MPU_EDR1_OFFSET 0x001c /* Error Detail Register, Slave Port 1 */
+#define KINETIS_MPU_EAR2_OFFSET 0x0020 /* Error Address Register, Slave Port 2 */
+#define KINETIS_MPU_EDR2_OFFSET 0x0024 /* Error Detail Register, Slave Port 2 */
+#define KINETIS_MPU_EAR3_OFFSET 0x0028 /* Error Address Register, Slave Port 3 */
+#define KINETIS_MPU_EDR3_OFFSET 0x002c /* Error Detail Register, Slave Port 3 */
+#define KINETIS_MPU_EAR4_OFFSET 0x0030 /* Error Address Register, Slave Port 4 */
+#define KINETIS_MPU_EDR4_OFFSET 0x0034 /* Error Detail Register, Slave Port 4 */
+
+#define KINETIS_MPU_RGD_WORD_OFFSET(n,m) (x0400+((n)<<4)+((m)<< 2) /* Region Descriptor n, Word m */
+
+#define KINETIS_MPU_RGD0_WORD0_OFFSET 0x0400 /* Region Descriptor 0, Word 0 */
+#define KINETIS_MPU_RGD0_WORD1_OFFSET 0x0404 /* Region Descriptor 0, Word 1 */
+#define KINETIS_MPU_RGD0_WORD2_OFFSET 0x0408 /* Region Descriptor 0, Word 2 */
+#define KINETIS_MPU_RGD0_WORD3_OFFSET 0x040c /* Region Descriptor 0, Word 3 */
+#define KINETIS_MPU_RGD1_WORD0_OFFSET 0x0410 /* Region Descriptor 1, Word 0 */
+#define KINETIS_MPU_RGD1_WORD1_OFFSET 0x0414 /* Region Descriptor 1, Word 1 */
+#define KINETIS_MPU_RGD1_WORD2_OFFSET 0x0418 /* Region Descriptor 1, Word 2 */
+#define KINETIS_MPU_RGD1_WORD3_OFFSET 0x041c /* Region Descriptor 1, Word 3 */
+#define KINETIS_MPU_RGD2_WORD0_OFFSET 0x0420 /* Region Descriptor 2, Word 0 */
+#define KINETIS_MPU_RGD2_WORD1_OFFSET 0x0424 /* Region Descriptor 2, Word 1 */
+#define KINETIS_MPU_RGD2_WORD2_OFFSET 0x0428 /* Region Descriptor 2, Word 2 */
+#define KINETIS_MPU_RGD2_WORD3_OFFSET 0x042c /* Region Descriptor 2, Word 3 */
+#define KINETIS_MPU_RGD3_WORD0_OFFSET 0x0430 /* Region Descriptor 3, Word 0 */
+#define KINETIS_MPU_RGD3_WORD1_OFFSET 0x0434 /* Region Descriptor 3, Word 1 */
+#define KINETIS_MPU_RGD3_WORD2_OFFSET 0x0438 /* Region Descriptor 3, Word 2 */
+#define KINETIS_MPU_RGD3_WORD3_OFFSET 0x043c /* Region Descriptor 3, Word 3 */
+#define KINETIS_MPU_RGD4_WORD0_OFFSET 0x0440 /* Region Descriptor 4, Word 0 */
+#define KINETIS_MPU_RGD4_WORD1_OFFSET 0x0444 /* Region Descriptor 4, Word 1 */
+#define KINETIS_MPU_RGD4_WORD2_OFFSET 0x0448 /* Region Descriptor 4, Word 2 */
+#define KINETIS_MPU_RGD4_WORD3_OFFSET 0x044c /* Region Descriptor 4, Word 3 */
+#define KINETIS_MPU_RGD5_WORD0_OFFSET 0x0450 /* Region Descriptor 5, Word 0 */
+#define KINETIS_MPU_RGD5_WORD1_OFFSET 0x0454 /* Region Descriptor 5, Word 1 */
+#define KINETIS_MPU_RGD5_WORD2_OFFSET 0x0458 /* Region Descriptor 5, Word 2 */
+#define KINETIS_MPU_RGD5_WORD3_OFFSET 0x045c /* Region Descriptor 5, Word 3 */
+#define KINETIS_MPU_RGD6_WORD0_OFFSET 0x0460 /* Region Descriptor 6, Word 0 */
+#define KINETIS_MPU_RGD6_WORD1_OFFSET 0x0464 /* Region Descriptor 6, Word 1 */
+#define KINETIS_MPU_RGD6_WORD2_OFFSET 0x0468 /* Region Descriptor 6, Word 2 */
+#define KINETIS_MPU_RGD6_WORD3_OFFSET 0x046c /* Region Descriptor 6, Word 3 */
+#define KINETIS_MPU_RGD7_WORD0_OFFSET 0x0470 /* Region Descriptor 7, Word 0 */
+#define KINETIS_MPU_RGD7_WORD1_OFFSET 0x0474 /* Region Descriptor 7, Word 1 */
+#define KINETIS_MPU_RGD7_WORD2_OFFSET 0x0478 /* Region Descriptor 7, Word 2 */
+#define KINETIS_MPU_RGD7_WORD3_OFFSET 0x047c /* Region Descriptor 7, Word 3 */
+#define KINETIS_MPU_RGD8_WORD0_OFFSET 0x0480 /* Region Descriptor 8, Word 0 */
+#define KINETIS_MPU_RGD8_WORD1_OFFSET 0x0484 /* Region Descriptor 8, Word 1 */
+#define KINETIS_MPU_RGD8_WORD2_OFFSET 0x0488 /* Region Descriptor 8, Word 2 */
+#define KINETIS_MPU_RGD8_WORD3_OFFSET 0x048c /* Region Descriptor 8, Word 3 */
+#define KINETIS_MPU_RGD9_WORD0_OFFSET 0x0490 /* Region Descriptor 9, Word 0 */
+#define KINETIS_MPU_RGD9_WORD1_OFFSET 0x0494 /* Region Descriptor 9, Word 1 */
+#define KINETIS_MPU_RGD9_WORD2_OFFSET 0x0498 /* Region Descriptor 9, Word 2 */
+#define KINETIS_MPU_RGD9_WORD3_OFFSET 0x049c /* Region Descriptor 9, Word 3 */
+#define KINETIS_MPU_RGD10_WORD0_OFFSET 0x04a0 /* Region Descriptor 10, Word 0 */
+#define KINETIS_MPU_RGD10_WORD1_OFFSET 0x04a4 /* Region Descriptor 10, Word 1 */
+#define KINETIS_MPU_RGD10_WORD2_OFFSET 0x04a8 /* Region Descriptor 10, Word 2 */
+#define KINETIS_MPU_RGD10_WORD3_OFFSET 0x04ac /* Region Descriptor 10, Word 3 */
+#define KINETIS_MPU_RGD11_WORD0_OFFSET 0x04b0 /* Region Descriptor 11, Word 0 */
+#define KINETIS_MPU_RGD11_WORD1_OFFSET 0x04b4 /* Region Descriptor 11, Word 1 */
+#define KINETIS_MPU_RGD11_WORD2_OFFSET 0x04b8 /* Region Descriptor 11, Word 2 */
+#define KINETIS_MPU_RGD11_WORD3_OFFSET 0x04bc /* Region Descriptor 11, Word 3 */
+
+#define KINETIS_MPU_RGDAAC_OFFSET(n) (0x0800+((n)<<2)) /* Region Descriptor Alternate Access Control n */
+
+#define KINETIS_MPU_RGDAAC0_OFFSET 0x0800 /* Region Descriptor Alternate Access Control 0 */
+#define KINETIS_MPU_RGDAAC1_OFFSET 0x0804 /* Region Descriptor Alternate Access Control 1 */
+#define KINETIS_MPU_RGDAAC2_OFFSET 0x0808 /* Region Descriptor Alternate Access Control 2 */
+#define KINETIS_MPU_RGDAAC3_OFFSET 0x080c /* Region Descriptor Alternate Access Control 3 */
+#define KINETIS_MPU_RGDAAC4_OFFSET 0x0810 /* Region Descriptor Alternate Access Control 4 */
+#define KINETIS_MPU_RGDAAC5_OFFSET 0x0814 /* Region Descriptor Alternate Access Control 5 */
+#define KINETIS_MPU_RGDAAC6_OFFSET 0x0818 /* Region Descriptor Alternate Access Control 6 */
+#define KINETIS_MPU_RGDAAC7_OFFSET 0x081c /* Region Descriptor Alternate Access Control 7 */
+#define KINETIS_MPU_RGDAAC8_OFFSET 0x0820 /* Region Descriptor Alternate Access Control 8 */
+#define KINETIS_MPU_RGDAAC9_OFFSET 0x0824 /* Region Descriptor Alternate Access Control 9 */
+#define KINETIS_MPU_RGDAAC10_OFFSET 0x0828 /* Region Descriptor Alternate Access Control 10 */
+#define KINETIS_MPU_RGDAAC11_OFFSET 0x082c /* Region Descriptor Alternate Access Control 11 */
+
+/* Register Addresses *******************************************************************************/
+
+#define KINETIS_MPU_CESR (KINETIS_MPU_BASE+KINETIS_MPU_CESR_OFFSET)
+
+#define KINETIS_MPU_EAR(n) (KINETIS_MPU_BASE+KINETIS_MPU_EAR_OFFSET(n))
+#define KINETIS_MPU_EDR(n) (KINETIS_MPU_BASE+KINETIS_MPU_EDR_OFFSET(n))
+
+#define KINETIS_MPU_EAR0 (KINETIS_MPU_BASE+KINETIS_MPU_EAR0_OFFSET)
+#define KINETIS_MPU_EDR0 (KINETIS_MPU_BASE+KINETIS_MPU_EDR0_OFFSET)
+#define KINETIS_MPU_EAR1 (KINETIS_MPU_BASE+KINETIS_MPU_EAR1_OFFSET)
+#define KINETIS_MPU_EDR1 (KINETIS_MPU_BASE+KINETIS_MPU_EDR1_OFFSET)
+#define KINETIS_MPU_EAR2 (KINETIS_MPU_BASE+KINETIS_MPU_EAR2_OFFSET)
+#define KINETIS_MPU_EDR2 (KINETIS_MPU_BASE+KINETIS_MPU_EDR2_OFFSET)
+#define KINETIS_MPU_EAR3 (KINETIS_MPU_BASE+KINETIS_MPU_EAR3_OFFSET)
+#define KINETIS_MPU_EDR3 (KINETIS_MPU_BASE+KINETIS_MPU_EDR3_OFFSET)
+#define KINETIS_MPU_EAR4 (KINETIS_MPU_BASE+KINETIS_MPU_EAR4_OFFSET)
+#define KINETIS_MPU_EDR4 (KINETIS_MPU_BASE+KINETIS_MPU_EDR4_OFFSET)
+
+#define KINETIS_MPU_RGD_WORD(n,m) (KINETIS_MPU_BASE+KINETIS_MPU_RGD_WORD_OFFSET(n,m))
+
+#define KINETIS_MPU_RGD0_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD0_WORD0_OFFSET)
+#define KINETIS_MPU_RGD0_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD0_WORD1_OFFSET)
+#define KINETIS_MPU_RGD0_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD0_WORD2_OFFSET)
+#define KINETIS_MPU_RGD0_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD0_WORD3_OFFSET)
+#define KINETIS_MPU_RGD1_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD1_WORD0_OFFSET)
+#define KINETIS_MPU_RGD1_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD1_WORD1_OFFSET)
+#define KINETIS_MPU_RGD1_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD1_WORD2_OFFSET)
+#define KINETIS_MPU_RGD1_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD1_WORD3_OFFSET)
+#define KINETIS_MPU_RGD2_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD2_WORD0_OFFSET)
+#define KINETIS_MPU_RGD2_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD2_WORD1_OFFSET)
+#define KINETIS_MPU_RGD2_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD2_WORD2_OFFSET)
+#define KINETIS_MPU_RGD2_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD2_WORD3_OFFSET)
+#define KINETIS_MPU_RGD3_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD3_WORD0_OFFSET)
+#define KINETIS_MPU_RGD3_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD3_WORD1_OFFSET)
+#define KINETIS_MPU_RGD3_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD3_WORD2_OFFSET)
+#define KINETIS_MPU_RGD3_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD3_WORD3_OFFSET)
+#define KINETIS_MPU_RGD4_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD4_WORD0_OFFSET)
+#define KINETIS_MPU_RGD4_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD4_WORD1_OFFSET)
+#define KINETIS_MPU_RGD4_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD4_WORD2_OFFSET)
+#define KINETIS_MPU_RGD4_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD4_WORD3_OFFSET)
+#define KINETIS_MPU_RGD5_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD5_WORD0_OFFSET)
+#define KINETIS_MPU_RGD5_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD5_WORD1_OFFSET)
+#define KINETIS_MPU_RGD5_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD5_WORD2_OFFSET)
+#define KINETIS_MPU_RGD5_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD5_WORD3_OFFSET)
+#define KINETIS_MPU_RGD6_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD6_WORD0_OFFSET)
+#define KINETIS_MPU_RGD6_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD6_WORD1_OFFSET)
+#define KINETIS_MPU_RGD6_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD6_WORD2_OFFSET)
+#define KINETIS_MPU_RGD6_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD6_WORD3_OFFSET)
+#define KINETIS_MPU_RGD7_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD7_WORD0_OFFSET)
+#define KINETIS_MPU_RGD7_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD7_WORD1_OFFSET)
+#define KINETIS_MPU_RGD7_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD7_WORD2_OFFSET)
+#define KINETIS_MPU_RGD7_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD7_WORD3_OFFSET)
+#define KINETIS_MPU_RGD8_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD8_WORD0_OFFSET)
+#define KINETIS_MPU_RGD8_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD8_WORD1_OFFSET)
+#define KINETIS_MPU_RGD8_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD8_WORD2_OFFSET)
+#define KINETIS_MPU_RGD8_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD8_WORD3_OFFSET)
+#define KINETIS_MPU_RGD9_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD9_WORD0_OFFSET)
+#define KINETIS_MPU_RGD9_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD9_WORD1_OFFSET)
+#define KINETIS_MPU_RGD9_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD9_WORD2_OFFSET)
+#define KINETIS_MPU_RGD9_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD9_WORD3_OFFSET)
+#define KINETIS_MPU_RGD10_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD10_WORD0_OFFSET)
+#define KINETIS_MPU_RGD10_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD10_WORD1_OFFSET)
+#define KINETIS_MPU_RGD10_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD10_WORD2_OFFSET)
+#define KINETIS_MPU_RGD10_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD10_WORD3_OFFSET)
+#define KINETIS_MPU_RGD11_WORD0 (KINETIS_MPU_BASE+KINETIS_MPU_RGD11_WORD0_OFFSET)
+#define KINETIS_MPU_RGD11_WORD1 (KINETIS_MPU_BASE+KINETIS_MPU_RGD11_WORD1_OFFSET)
+#define KINETIS_MPU_RGD11_WORD2 (KINETIS_MPU_BASE+KINETIS_MPU_RGD11_WORD2_OFFSET)
+#define KINETIS_MPU_RGD11_WORD3 (KINETIS_MPU_BASE+KINETIS_MPU_RGD11_WORD3_OFFSET)
+
+#define KINETIS_MPU_RGDAAC(n) (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC_OFFSET(n))
+
+#define KINETIS_MPU_RGDAAC0 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC0_OFFSET)
+#define KINETIS_MPU_RGDAAC1 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC1_OFFSET)
+#define KINETIS_MPU_RGDAAC2 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC2_OFFSET)
+#define KINETIS_MPU_RGDAAC3 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC3_OFFSET)
+#define KINETIS_MPU_RGDAAC4 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC4_OFFSET)
+#define KINETIS_MPU_RGDAAC5 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC5_OFFSET)
+#define KINETIS_MPU_RGDAAC6 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC6_OFFSET)
+#define KINETIS_MPU_RGDAAC7 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC7_OFFSET)
+#define KINETIS_MPU_RGDAAC8 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC8_OFFSET)
+#define KINETIS_MPU_RGDAAC9 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC9_OFFSET)
+#define KINETIS_MPU_RGDAAC10 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC10_OFFSET)
+#define KINETIS_MPU_RGDAAC11 (KINETIS_MPU_BASE+KINETIS_MPU_RGDAAC11_OFFSET)
+
+/* Register Bit Definitions *************************************************************************/
+
+/* Control/Error Status Register */
+
+#define MPU_CESR_VLD (1 << 0) /* Bit 0: Valid (global enable/disable for the MPU) */
+ /* Bits 1-7: Reserved */
+#define MPU_CESR_NRGD_SHIFT (8) /* Bits 8-11: Number of region descriptors */
+#define MPU_CESR_NRGD_MASK (15 << MPU_CESR_NRGD_SHIFT)
+# define MPU_CESR_NRGD_8DESC (0 << MPU_CESR_NRGD_SHIFT) /* 8 region descriptors */
+# define MPU_CESR_NRGD_12DESC (1 << MPU_CESR_NRGD_SHIFT) /* 12 region descriptors */
+# define MPU_CESR_NRGD_16DESC (2 << MPU_CESR_NRGD_SHIFT) /* 16 region descriptors */
+#define MPU_CESR_NSP_SHIFT (12) /* Bits 12-15: Number of slave ports */
+#define MPU_CESR_NSP_MASK (15 << MPU_CESR_NSP_SHIFT)
+#define MPU_CESR_HRL_SHIFT (16) /* Bits 16-19: Hardware revision level */
+#define MPU_CESR_HRL_MASK (15 << MPU_CESR_HRL_SHIFT)
+ /* Bits 20-26: Reserved */
+#define MPU_CESR_SPERR_SHIFT (27) /* Bits 27-31: Slave port n error */
+#define MPU_CESR_SPERR_MASK (31 << MPU_CESR_SPERR_SHIFT)
+# define MPU_CESR_SPERR_SPORT(n) ((1 << (4-(n))) << MPU_CESR_SPERR_SHIFT) /* Slave port nn */
+# define MPU_CESR_SPERR_SPORT0 (16 << MPU_CESR_SPERR_SHIFT) /* Slave port 0 */
+# define MPU_CESR_SPERR_SPORT1 (8 << MPU_CESR_SPERR_SHIFT) /* Slave port 1 */
+# define MPU_CESR_SPERR_SPORT2 (4 << MPU_CESR_SPERR_SHIFT) /* Slave port 2 */
+# define MPU_CESR_SPERR_SPORT3 (2 << MPU_CESR_SPERR_SHIFT) /* Slave port 3 */
+# define MPU_CESR_SPERR_SPORT4 (1 << MPU_CESR_SPERR_SHIFT) /* Slave port 4 */
+
+/* Error Address Register, Slave Port n. 32-bit error address. */
+
+/* Error Detail Register, Slave Port n */
+
+#define MPU_EDR_ERW (1 << 0) /* Bit 0: Error read/write */
+#define MPU_EDR_EATTR_SHIFT (1) /* Bits 1-3: Error attributes */
+#define MPU_EDR_EATTR_MASK (7 << MPU_EDR_EATTR_SHIFT)
+# define MPU_EDR_EATTR_USRINST (0 << MPU_EDR_EATTR_SHIFT) /* User mode, instruction access */
+# define MPU_EDR_EATTR_USRDATA (1 << MPU_EDR_EATTR_SHIFT) /* User mode, data access */
+# define MPU_EDR_EATTR_SUPINST (2 << MPU_EDR_EATTR_SHIFT) /* Supervisor mode, instruction access */
+# define MPU_EDR_EATTR_SUPDATA (3 << MPU_EDR_EATTR_SHIFT) /* Supervisor mode, data access */
+#define MPU_EDR_EMN_SHIFT (4) /* Bits 4-7: Error master number */
+#define MPU_EDR_EMN_MASK (15 << MPU_EDR_EMN_SHIFT)
+ /* Bits 8-15: Reserved */
+#define MPU_EDR_EACD_SHIFT (26) /* Bits 16-31: Error access control detail */
+#define MPU_EDR_EACD_MASK (0xffff << MPU_EDR_EACD_SHIFT)
+
+/* Region Descriptor n, Word 0 */
+ /* Bits 0-4: Reserved */
+#define MPU_RGD_WORD0_SRTADDR_SHIFT (5) /* Bits 5-31: Start address */
+#define MPU_RGD_WORD0_SRTADDR_MASK (0xffffffe0)
+
+/* Region Descriptor n, Word 1 */
+ /* Bits 0-4: Reserved */
+#define MPU_RGD_WORD1_ENDADDR_SHIFT (5) /* Bits 5-31: End address */
+#define MPU_RGD_WORD1_ENDADDR_MASK (0xffffffe0)
+
+/* Region Descriptor n, Word 2 */
+
+#define MPU_RGD_MSM_RWX 0 /* R/W/X; read, write and execute allowed */
+#define MPU_RGD_MSM_RX 1 /* R/X; read and execute allowed, but no write */
+#define MPU_RGD_MSM_RW 2 /* R/W; read and write allowed, but no execute */
+#define MPU_RGD_MSM_UM 3 /* Same as user mode defined in MUM */
+
+#define MPU_RGD_MUM_R 4 /* Read allowed */
+#define MPU_RGD_MUM_W 2 /* Write allowed */
+#define MPU_RGD_MUM_X 1 /* Execute allocated */
+
+#define MPU_RGD_WORD2_M0UM_SHIFT (0) /* Bits 0-2: Bus master 0 user mode access control */
+#define MPU_RGD_WORD2_M0UM_MASK (7 << MPU_RGD_WORD2_M0UM_SHIFT)
+#define MPU_RGD_WORD2_M0SM_SHIFT (3) /* Bits 3-4: Bus master 0 supervisor mode access control */
+#define MPU_RGD_WORD2_M0SM_MASK (3 << MPU_RGD_WORD2_M0SM_SHIFT)
+#define MPU_RGD_WORD2_M0PE (1 << 5) /* Bit 5: Bus Master 0 Process Identifier Enable */
+#define MPU_RGD_WORD2_M1UM_SHIFT (6) /* Bits 6-8: Bus master 1 user mode access control */
+#define MPU_RGD_WORD2_M1UM_MASK (7 << MPU_RGD_WORD2_M1UM_SHIFT)
+#define MPU_RGD_WORD2_M1SM_SHIFT (9) /* Bits 9-10: Bus master 1 supervisor mode access control */
+#define MPU_RGD_WORD2_M1SM_MASK (3 << MPU_RGD_WORD2_M1SM_SHIFT)
+#define MPU_RGD_WORD2_M1PE (1 << 11) /* Bit 11: Bus Master 1 Process Identifier Enable */
+#define MPU_RGD_WORD2_M2UM_SHIFT (12) /* Bits 12-14: Bus master 2 user mode access control */
+#define MPU_RGD_WORD2_M2UM_MASK (7 << MPU_RGD_WORD2_M2UM_SHIFT)
+#define MPU_RGD_WORD2_M2SM_SHIFT (15) /* Bits 15-16: Bus master 2 supervisor mode access control */
+#define MPU_RGD_WORD2_M2SM_MASK (3 << MPU_RGD_WORD2_M2SM_SHIFT)
+#define MPU_RGD_WORD2_M2PE (1 << 17) /* Bit 17: Bus Master 2 Process Identifier Enable */
+#define MPU_RGD_WORD2_M3UM_SHIFT (18) /* Bits 18-20: Bus master 3 user mode access control */
+#define MPU_RGD_WORD2_M3UM_MASK (7 << MPU_RGD_WORD2_M3UM_SHIFT)
+#define MPU_RGD_WORD2_M3SM_SHIFT (21) /* Bits 21-22: Bus master 3 supervisor mode access control */
+#define MPU_RGD_WORD2_M3SM_MASK (3 << MPU_RGD_WORD2_M3SM_SHIFT)
+#define MPU_RGD_WORD2_M3PE (1 << 23) /* Bit 23: Bus Master 3 Process Identifier Enable */
+#define MPU_RGD_WORD2_M4WE (1 << 24) /* Bit 24: Bus master 4 write enable */
+#define MPU_RGD_WORD2_M4RE (1 << 25) /* Bit 25: Bus master 4 read enable */
+#define MPU_RGD_WORD2_M5WE (1 << 26) /* Bit 26: Bus master 5 write enable */
+#define MPU_RGD_WORD2_M5RE (1 << 27) /* Bit 27: Bus master 5 read enable */
+#define MPU_RGD_WORD2_M6WE (1 << 28) /* Bit 28: Bus master 6 write enable */
+#define MPU_RGD_WORD2_M6RE (1 << 29) /* Bit 29: Bus master 6 read enable */
+#define MPU_RGD_WORD2_M7WE (1 << 30) /* Bit 30: Bus master 7 write enable */
+#define MPU_RGD_WORD2_M7RE (1 << 31) /* Bit 31: Bus master 7 read enable */
+
+/* Region Descriptor n, Word 3 */
+
+#define MPU_RGD_WORD3_VLD (1 << 0) /* Bit 0: Valid */
+ /* Bits 1-31: Reserved */
+/* Region Descriptor Alternate Access Control n */
+
+#define MPU_RGD_RBDACC_M0UM_SHIFT (0) /* Bits 0-2: Bus master 0 user mode access control */
+#define MPU_RGD_RBDACC_M0UM_MASK (7 << MPU_RGD_RBDACC_M0UM_SHIFT)
+#define MPU_RGD_RBDACC_M0SM_SHIFT (3) /* Bits 3-4: Bus master 0 supervisor mode access control */
+#define MPU_RGD_RBDACC_M0SM_MASK (3 << MPU_RGD_RBDACC_M0SM_SHIFT)
+ /* Bit 5: Reserved */
+#define MPU_RGD_RBDACC_M1UM_SHIFT (6) /* Bits 6-8: Bus master 1 user mode access control */
+#define MPU_RGD_RBDACC_M1UM_MASK (7 << MPU_RGD_RBDACC_M1UM_SHIFT)
+#define MPU_RGD_RBDACC_M1SM_SHIFT (9) /* Bits 9-10: Bus master 1 supervisor mode access control */
+#define MPU_RGD_RBDACC_M1SM_MASK (3 << MPU_RGD_RBDACC_M1SM_SHIFT)
+ /* Bit 11: Reserved */
+#define MPU_RGD_RBDACC_M2UM_SHIFT (12) /* Bits 12-14: Bus master 2 user mode access control */
+#define MPU_RGD_RBDACC_M2UM_MASK (7 << MPU_RGD_RBDACC_M2UM_SHIFT)
+#define MPU_RGD_RBDACC_M2SM_SHIFT (15) /* Bits 15-16: Bus master 2 supervisor mode access control */
+#define MPU_RGD_RBDACC_M2SM_MASK (3 << MPU_RGD_RBDACC_M2SM_SHIFT)
+ /* Bit 17: Reserved */
+#define MPU_RGD_RBDACC_M3UM_SHIFT (18) /* Bits 18-20: Bus master 3 user mode access control */
+#define MPU_RGD_RBDACC_M3UM_MASK (7 << MPU_RGD_RBDACC_M3UM_SHIFT)
+#define MPU_RGD_RBDACC_M3SM_SHIFT (21) /* Bits 21-22: Bus master 3 supervisor mode access control */
+#define MPU_RGD_RBDACC_M3SM_MASK (3 << MPU_RGD_RBDACC_M3SM_SHIFT)
+ /* Bit 23: Reserved */
+#define MPU_RGD_RBDACC_M4WE (1 << 24) /* Bit 24: Bus master 4 write enable */
+#define MPU_RGD_RBDACC_M4RE (1 << 25) /* Bit 25: Bus master 4 read enable */
+#define MPU_RGD_RBDACC_M5WE (1 << 26) /* Bit 26: Bus master 5 write enable */
+#define MPU_RGD_RBDACC_M5RE (1 << 27) /* Bit 27: Bus master 5 read enable */
+#define MPU_RGD_RBDACC_M6WE (1 << 28) /* Bit 28: Bus master 6 write enable */
+#define MPU_RGD_RBDACC_M6RE (1 << 29) /* Bit 29: Bus master 6 read enable */
+#define MPU_RGD_RBDACC_M7WE (1 << 30) /* Bit 30: Bus master 7 write enable */
+#define MPU_RGD_RBDACC_M7RE (1 << 31) /* Bit 31: Bus master 7 read enable */
+
+/****************************************************************************************************
+ * Public Types
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Public Data
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Public Functions
+ ****************************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MPU_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_k64pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k64pinmux.h
new file mode 100644
index 0000000000000000000000000000000000000000..3479099bf6c99c2275611636ded8721fe11f1526
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_k64pinmux.h
@@ -0,0 +1,640 @@
+/********************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_k64pinmux.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHP_KINETIS_K64PINMUX_H
+#define __ARCH_ARM_SRC_KINETIS_CHP_KINETIS_K64PINMUX_H
+
+/********************************************************************************************
+ * Included Files
+ ********************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+#ifdef KINETIS_K64
+
+/********************************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************************/
+/* In most cases, there are alternative configurations for various pins. Those alternative
+ * pins are labeled with a suffix like _1, _2, etc. in order to distinguish them. Logic in
+ * the board.h file must select the correct pin configuration for the board by defining a pin
+ * configuration (with no suffix) that maps to the correct alternative.
+ *
+ * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!
+ * Additional effort is required to select specific GPIO options such as frequency,
+ * open-drain/push-pull, and pull-up/down! Just the basics are defined for most
+ * pins in the initial version of this file.
+ */
+
+/* ADC */
+
+#define PIN_ADC0_DM2 (PIN_ANALOG | PIN_PORTE | PIN3)
+#define PIN_ADC0_DP2 (PIN_ANALOG | PIN_PORTE | PIN2)
+#define PIN_ADC0_SE4B (PIN_ANALOG | PIN_PORTC | PIN2)
+#define PIN_ADC0_SE5B (PIN_ANALOG | PIN_PORTD | PIN1)
+#define PIN_ADC0_SE6B (PIN_ANALOG | PIN_PORTD | PIN5)
+#define PIN_ADC0_SE7B (PIN_ANALOG | PIN_PORTD | PIN6)
+#define PIN_ADC0_SE8 (PIN_ANALOG | PIN_PORTB | PIN0)
+#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
+#define PIN_ADC0_SE10 (PIN_ANALOG | PIN_PORTA | PIN7)
+#define PIN_ADC0_SE11 (PIN_ANALOG | PIN_PORTA | PIN8)
+#define PIN_ADC0_SE12 (PIN_ANALOG | PIN_PORTB | PIN2)
+#define PIN_ADC0_SE13 (PIN_ANALOG | PIN_PORTB | PIN3)
+#define PIN_ADC0_SE14 (PIN_ANALOG | PIN_PORTC | PIN0)
+#define PIN_ADC0_SE15 (PIN_ANALOG | PIN_PORTC | PIN1)
+#define PIN_ADC0_SE17 (PIN_ANALOG | PIN_PORTE | PIN24)
+#define PIN_ADC0_SE18 (PIN_ANALOG | PIN_PORTE | PIN25)
+
+#define PIN_ADC1_SE4A (PIN_ANALOG | PIN_PORTE | PIN0)
+#define PIN_ADC1_SE4B (PIN_ANALOG | PIN_PORTC | PIN8)
+#define PIN_ADC1_SE5A (PIN_ANALOG | PIN_PORTE | PIN1)
+#define PIN_ADC1_SE5B (PIN_ANALOG | PIN_PORTC | PIN9)
+#define PIN_ADC1_SE6A (PIN_ANALOG | PIN_PORTE | PIN2)
+#define PIN_ADC1_SE6B (PIN_ANALOG | PIN_PORTC | PIN10)
+#define PIN_ADC1_SE7A (PIN_ANALOG | PIN_PORTE | PIN3)
+#define PIN_ADC1_SE7B (PIN_ANALOG | PIN_PORTC | PIN11)
+#define PIN_ADC1_SE8 (PIN_ANALOG | PIN_PORTB | PIN0)
+#define PIN_ADC1_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
+#define PIN_ADC1_SE10 (PIN_ANALOG | PIN_PORTB | PIN4)
+#define PIN_ADC1_SE11 (PIN_ANALOG | PIN_PORTB | PIN5)
+#define PIN_ADC1_SE12 (PIN_ANALOG | PIN_PORTB | PIN6)
+#define PIN_ADC1_SE13 (PIN_ANALOG | PIN_PORTB | PIN7)
+#define PIN_ADC1_SE14 (PIN_ANALOG | PIN_PORTB | PIN10)
+#define PIN_ADC1_SE15 (PIN_ANALOG | PIN_PORTB | PIN11)
+#define PIN_ADC1_SE17 (PIN_ANALOG | PIN_PORTA | PIN17)
+
+/* CAN */
+
+#define PIN_CAN0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN13)
+#define PIN_CAN0_RX_2 (PIN_ALT2 | PIN_PORTB | PIN19)
+#define PIN_CAN0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN12)
+#define PIN_CAN0_TX_2 (PIN_ALT2 | PIN_PORTB | PIN18)
+
+/* Output clock */
+
+#define PIN_CLKOUT_1 (PIN_ALT5 | PIN_PORTA | PIN6)
+#define PIN_CLKOUT_2 (PIN_ALT5 | PIN_PORTC | PIN3)
+
+/* Comparators */
+
+#define PIN_CMP0_IN0 (PIN_ANALOG | PIN_PORTC | PIN6)
+#define PIN_CMP0_IN1 (PIN_ANALOG | PIN_PORTC | PIN7)
+#define PIN_CMP0_IN2 (PIN_ANALOG | PIN_PORTC | PIN8)
+#define PIN_CMP0_IN3 (PIN_ANALOG | PIN_PORTC | PIN9)
+#define PIN_CMP0_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN20)
+#define PIN_CMP0_OUT_2 (PIN_ALT6 | PIN_PORTC | PIN5)
+
+#define PIN_CMP1_IN0 (PIN_ANALOG | PIN_PORTC | PIN2)
+#define PIN_CMP1_IN1 (PIN_ANALOG | PIN_PORTC | PIN3)
+#define PIN_CMP1_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN21)
+#define PIN_CMP1_OUT_2 (PIN_ALT6 | PIN_PORTC | PIN4)
+
+#define PIN_CMP2_IN0 (PIN_ANALOG | PIN_PORTA | PIN12)
+#define PIN_CMP2_IN1 (PIN_ANALOG | PIN_PORTA | PIN13)
+#define PIN_CMP2_OUT_1 (PIN_ALT5 | PIN_PORTA | PIN5)
+#define PIN_CMP2_OUT_2 (PIN_ALT6 | PIN_PORTB | PIN22)
+
+/* Carrier Modulator Transmittor (CMT) */
+
+#define PIN_CMT_IRO (PIN_ALT2 | PIN_PORTD | PIN7)
+
+/* Ethernet */
+
+#define PIN_ENET_1588_CLKIN (PIN_ALT2 | PIN_PORTE | PIN26)
+#define PIN_ENET0_1588_TMR0_1 (PIN_ALT4 | PIN_PORTB | PIN2)
+#define PIN_ENET0_1588_TMR0_2 (PIN_ALT4 | PIN_PORTC | PIN16)
+#define PIN_ENET0_1588_TMR1_1 (PIN_ALT4 | PIN_PORTB | PIN3)
+#define PIN_ENET0_1588_TMR1_2 (PIN_ALT4 | PIN_PORTC | PIN17)
+#define PIN_ENET0_1588_TMR2_1 (PIN_ALT4 | PIN_PORTB | PIN4)
+#define PIN_ENET0_1588_TMR2_2 (PIN_ALT4 | PIN_PORTC | PIN18)
+#define PIN_ENET0_1588_TMR3_1 (PIN_ALT4 | PIN_PORTB | PIN5)
+#define PIN_ENET0_1588_TMR3_2 (PIN_ALT4 | PIN_PORTC | PIN19)
+
+/* External Watchdog Monitor (EWM) */
+
+#define PIN_EWM_IN_1 (PIN_ALT6 | PIN_PORTB | PIN16)
+#define PIN_EWM_IN_2 (PIN_ALT6 | PIN_PORTD | PIN4)
+#define PIN_EWM_IN_3 (PIN_ALT6 | PIN_PORTE | PIN25)
+#define PIN_EWM_OUT_1 (PIN_ALT6 | PIN_PORTB | PIN17)
+#define PIN_EWM_OUT_2 (PIN_ALT6 | PIN_PORTD | PIN5)
+#define PIN_EWM_OUT_3 (PIN_ALT6 | PIN_PORTE | PIN24)
+
+/* FlexBus */
+
+#define PIN_FB_A16 (PIN_ALT6 | PIN_PORTD | PIN8)
+#define PIN_FB_A17 (PIN_ALT6 | PIN_PORTD | PIN9)
+#define PIN_FB_A18 (PIN_ALT6 | PIN_PORTD | PIN10)
+#define PIN_FB_A19 (PIN_ALT6 | PIN_PORTD | PIN11)
+#define PIN_FB_A20 (PIN_ALT6 | PIN_PORTD | PIN12)
+#define PIN_FB_A21 (PIN_ALT6 | PIN_PORTD | PIN13)
+#define PIN_FB_A22 (PIN_ALT6 | PIN_PORTD | PIN14)
+#define PIN_FB_A23 (PIN_ALT6 | PIN_PORTD | PIN15)
+#define PIN_FB_A24 (PIN_ALT6 | PIN_PORTA | PIN29)
+#define PIN_FB_A25 (PIN_ALT6 | PIN_PORTA | PIN28)
+#define PIN_FB_A26 (PIN_ALT6 | PIN_PORTA | PIN27)
+#define PIN_FB_A27 (PIN_ALT6 | PIN_PORTA | PIN26)
+#define PIN_FB_A28 (PIN_ALT6 | PIN_PORTA | PIN25)
+#define PIN_FB_A29 (PIN_ALT6 | PIN_PORTA | PIN24)
+#define PIN_FB_AD0 (PIN_ALT5 | PIN_PORTD | PIN6)
+#define PIN_FB_AD1 (PIN_ALT5 | PIN_PORTD | PIN5)
+#define PIN_FB_AD2 (PIN_ALT5 | PIN_PORTD | PIN4)
+#define PIN_FB_AD3 (PIN_ALT5 | PIN_PORTD | PIN3)
+#define PIN_FB_AD4 (PIN_ALT5 | PIN_PORTD | PIN2)
+#define PIN_FB_AD5 (PIN_ALT5 | PIN_PORTC | PIN10)
+#define PIN_FB_AD6 (PIN_ALT5 | PIN_PORTC | PIN9)
+#define PIN_FB_AD7 (PIN_ALT5 | PIN_PORTC | PIN8)
+#define PIN_FB_AD8 (PIN_ALT5 | PIN_PORTC | PIN7)
+#define PIN_FB_AD9 (PIN_ALT5 | PIN_PORTC | PIN6)
+#define PIN_FB_AD10 (PIN_ALT5 | PIN_PORTC | PIN5)
+#define PIN_FB_AD11 (PIN_ALT5 | PIN_PORTC | PIN4)
+#define PIN_FB_AD12 (PIN_ALT5 | PIN_PORTC | PIN2)
+#define PIN_FB_AD13 (PIN_ALT5 | PIN_PORTC | PIN1)
+#define PIN_FB_AD14 (PIN_ALT5 | PIN_PORTC | PIN0)
+#define PIN_FB_AD15 (PIN_ALT5 | PIN_PORTB | PIN18)
+#define PIN_FB_AD16 (PIN_ALT5 | PIN_PORTB | PIN17)
+#define PIN_FB_AD17 (PIN_ALT5 | PIN_PORTB | PIN16)
+#define PIN_FB_AD18 (PIN_ALT5 | PIN_PORTB | PIN11)
+#define PIN_FB_AD19 (PIN_ALT5 | PIN_PORTB | PIN10)
+#define PIN_FB_AD20 (PIN_ALT5 | PIN_PORTB | PIN9)
+#define PIN_FB_AD21 (PIN_ALT5 | PIN_PORTB | PIN8)
+#define PIN_FB_AD22 (PIN_ALT5 | PIN_PORTB | PIN7)
+#define PIN_FB_AD23 (PIN_ALT5 | PIN_PORTB | PIN6)
+#define PIN_FB_AD24 (PIN_ALT5 | PIN_PORTC | PIN15)
+#define PIN_FB_AD25 (PIN_ALT5 | PIN_PORTC | PIN14)
+#define PIN_FB_AD26 (PIN_ALT5 | PIN_PORTC | PIN13)
+#define PIN_FB_AD27 (PIN_ALT5 | PIN_PORTC | PIN12)
+#define PIN_FB_AD28 (PIN_ALT5 | PIN_PORTB | PIN23)
+#define PIN_FB_AD29 (PIN_ALT5 | PIN_PORTB | PIN22)
+#define PIN_FB_AD30 (PIN_ALT5 | PIN_PORTB | PIN21)
+#define PIN_FB_AD31 (PIN_ALT5 | PIN_PORTB | PIN20)
+#define PIN_FB_ALE (PIN_ALT5 | PIN_PORTD | PIN0)
+#define PIN_FB_BE15_8_BLS23_16 (PIN_ALT5 | PIN_PORTC | PIN18)
+#define PIN_FB_BE23_16_BLS15_8 (PIN_ALT5 | PIN_PORTC | PIN16)
+#define PIN_FB_BE31_24_BLS7_0 (PIN_ALT5 | PIN_PORTC | PIN17)
+#define PIN_FB_BE7_0_BLS31_24 (PIN_ALT5 | PIN_PORTC | PIN19)
+#define PIN_FB_CS0 (PIN_ALT5 | PIN_PORTD | PIN1)
+#define PIN_FB_CS1 (PIN_ALT5 | PIN_PORTD | PIN0)
+#define PIN_FB_CS2 (PIN_ALT5 | PIN_PORTC | PIN18)
+#define PIN_FB_CS3 (PIN_ALT5 | PIN_PORTC | PIN19)
+#define PIN_FB_CS4 (PIN_ALT5 | PIN_PORTC | PIN17)
+#define PIN_FB_CS5 (PIN_ALT5 | PIN_PORTC | PIN16)
+#define PIN_FB_OE (PIN_ALT5 | PIN_PORTB | PIN19)
+#define PIN_FB_RW (PIN_ALT5 | PIN_PORTC | PIN11)
+#define PIN_FB_TA (PIN_ALT6 | PIN_PORTC | PIN19)
+#define PIN_FB_TBST (PIN_ALT5 | PIN_PORTC | PIN18)
+#define PIN_FB_TS (PIN_ALT5 | PIN_PORTD | PIN0)
+#define PIN_FB_TSIZ0 (PIN_ALT5 | PIN_PORTC | PIN17)
+#define PIN_FB_TSIZ1 (PIN_ALT5 | PIN_PORTC | PIN16)
+
+/* FlexTimer Module (FTM) */
+
+#define PIN_FTM_CLKIN0_1 (PIN_ALT4 | PIN_PORTA | PIN18)
+#define PIN_FTM_CLKIN0_2 (PIN_ALT4 | PIN_PORTB | PIN16)
+#define PIN_FTM_CLKIN1_1 (PIN_ALT4 | PIN_PORTA | PIN19)
+#define PIN_FTM_CLKIN1_2 (PIN_ALT4 | PIN_PORTB | PIN17)
+
+#define PIN_FTM0_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN3)
+#define PIN_FTM0_CH0_2 (PIN_ALT4 | PIN_PORTC | PIN1)
+#define PIN_FTM0_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN4)
+#define PIN_FTM0_CH1_2 (PIN_ALT4 | PIN_PORTC | PIN2)
+#define PIN_FTM0_CH2_1 (PIN_ALT3 | PIN_PORTA | PIN5)
+#define PIN_FTM0_CH2_2 (PIN_ALT4 | PIN_PORTC | PIN3)
+#define PIN_FTM0_CH2_3 (PIN_ALT7 | PIN_PORTC | PIN5)
+#define PIN_FTM0_CH3_1 (PIN_ALT3 | PIN_PORTA | PIN6)
+#define PIN_FTM0_CH3_2 (PIN_ALT4 | PIN_PORTC | PIN4)
+#define PIN_FTM0_CH4_1 (PIN_ALT3 | PIN_PORTA | PIN7)
+#define PIN_FTM0_CH4_2 (PIN_ALT4 | PIN_PORTB | PIN12)
+#define PIN_FTM0_CH4_3 (PIN_ALT4 | PIN_PORTD | PIN4)
+#define PIN_FTM0_CH5_1 (PIN_ALT3 | PIN_PORTA | PIN0)
+#define PIN_FTM0_CH5_2 (PIN_ALT4 | PIN_PORTB | PIN13)
+#define PIN_FTM0_CH5_3 (PIN_ALT4 | PIN_PORTD | PIN5)
+#define PIN_FTM0_CH6_1 (PIN_ALT3 | PIN_PORTA | PIN1)
+#define PIN_FTM0_CH6_2 (PIN_ALT4 | PIN_PORTD | PIN6)
+#define PIN_FTM0_CH7_1 (PIN_ALT3 | PIN_PORTA | PIN2)
+#define PIN_FTM0_CH7_2 (PIN_ALT4 | PIN_PORTD | PIN7)
+#define PIN_FTM0_FLT0_1 (PIN_ALT6 | PIN_PORTB | PIN3)
+#define PIN_FTM0_FLT0_2 (PIN_ALT6 | PIN_PORTD | PIN6)
+#define PIN_FTM0_FLT1_1 (PIN_ALT6 | PIN_PORTB | PIN10)
+#define PIN_FTM0_FLT1_2 (PIN_ALT6 | PIN_PORTD | PIN7)
+#define PIN_FTM0_FLT2_1 (PIN_ALT3 | PIN_PORTA | PIN18)
+#define PIN_FTM0_FLT2_2 (PIN_ALT6 | PIN_PORTB | PIN11)
+#define PIN_FTM0_FLT3 (PIN_ALT6 | PIN_PORTB | PIN2)
+
+#define PIN_FTM1_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN12)
+#define PIN_FTM1_CH0_2 (PIN_ALT3 | PIN_PORTA | PIN8)
+#define PIN_FTM1_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN0)
+#define PIN_FTM1_CH0_4 (PIN_ALT3 | PIN_PORTB | PIN12)
+#define PIN_FTM1_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN13)
+#define PIN_FTM1_CH1_2 (PIN_ALT3 | PIN_PORTA | PIN9)
+#define PIN_FTM1_CH1_3 (PIN_ALT3 | PIN_PORTB | PIN1)
+#define PIN_FTM1_CH1_4 (PIN_ALT3 | PIN_PORTB | PIN13)
+#define PIN_FTM1_FLT0_1 (PIN_ALT3 | PIN_PORTA | PIN19)
+#define PIN_FTM1_FLT0_2 (PIN_ALT6 | PIN_PORTB | PIN4)
+#define PIN_FTM1_QD_PHA_1 (PIN_ALT6 | PIN_PORTA | PIN8)
+#define PIN_FTM1_QD_PHA_2 (PIN_ALT6 | PIN_PORTB | PIN0)
+#define PIN_FTM1_QD_PHA_3 (PIN_ALT6 | PIN_PORTB | PIN12)
+#define PIN_FTM1_QD_PHA_4 (PIN_ALT7 | PIN_PORTA | PIN12)
+#define PIN_FTM1_QD_PHB_1 (PIN_ALT6 | PIN_PORTA | PIN9)
+#define PIN_FTM1_QD_PHB_2 (PIN_ALT6 | PIN_PORTB | PIN1)
+#define PIN_FTM1_QD_PHB_3 (PIN_ALT6 | PIN_PORTB | PIN13)
+#define PIN_FTM1_QD_PHB_4 (PIN_ALT7 | PIN_PORTA | PIN13)
+
+#define PIN_FTM2_CH0_1 (PIN_ALT3 | PIN_PORTA | PIN10)
+#define PIN_FTM2_CH0_2 (PIN_ALT3 | PIN_PORTB | PIN18)
+#define PIN_FTM2_CH1_1 (PIN_ALT3 | PIN_PORTA | PIN11)
+#define PIN_FTM2_CH1_2 (PIN_ALT3 | PIN_PORTB | PIN19)
+#define PIN_FTM2_FLT0_1 (PIN_ALT6 | PIN_PORTB | PIN5)
+#define PIN_FTM2_FLT0_2 (PIN_ALT6 | PIN_PORTC | PIN9)
+#define PIN_FTM2_QD_PHA_1 (PIN_ALT6 | PIN_PORTA | PIN10)
+#define PIN_FTM2_QD_PHA_2 (PIN_ALT6 | PIN_PORTB | PIN18)
+#define PIN_FTM2_QD_PHB_1 (PIN_ALT6 | PIN_PORTA | PIN11)
+#define PIN_FTM2_QD_PHB_2 (PIN_ALT6 | PIN_PORTB | PIN19)
+
+#define PIN_FTM3_CH0_1 (PIN_ALT4 | PIN_PORTD | PIN0)
+#define PIN_FTM3_CH0_2 (PIN_ALT6 | PIN_PORTE | PIN5)
+#define PIN_FTM3_CH1_1 (PIN_ALT4 | PIN_PORTD | PIN1)
+#define PIN_FTM3_CH1_2 (PIN_ALT6 | PIN_PORTE | PIN6)
+#define PIN_FTM3_CH2_1 (PIN_ALT4 | PIN_PORTD | PIN2)
+#define PIN_FTM3_CH2_2 (PIN_ALT6 | PIN_PORTE | PIN7)
+#define PIN_FTM3_CH3_1 (PIN_ALT4 | PIN_PORTD | PIN3)
+#define PIN_FTM3_CH3_2 (PIN_ALT6 | PIN_PORTE | PIN8)
+#define PIN_FTM3_CH4_1 (PIN_ALT3 | PIN_PORTC | PIN8)
+#define PIN_FTM3_CH4_2 (PIN_ALT6 | PIN_PORTE | PIN9)
+#define PIN_FTM3_CH5_1 (PIN_ALT3 | PIN_PORTC | PIN9)
+#define PIN_FTM3_CH5_2 (PIN_ALT6 | PIN_PORTE | PIN10)
+#define PIN_FTM3_CH6_1 (PIN_ALT3 | PIN_PORTC | PIN10)
+#define PIN_FTM3_CH6_2 (PIN_ALT6 | PIN_PORTE | PIN11)
+#define PIN_FTM3_CH7_1 (PIN_ALT3 | PIN_PORTC | PIN11)
+#define PIN_FTM3_CH7_2 (PIN_ALT6 | PIN_PORTE | PIN12)
+#define PIN_FTM3_FLT0_1 (PIN_ALT3 | PIN_PORTD | PIN12)
+#define PIN_FTM3_FLT0_2 (PIN_ALT6 | PIN_PORTC | PIN12)
+
+/* I2C */
+
+#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
+#define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2)
+#define PIN_I2C0_SCL_3 (PIN_ALT2 | PIN_PORTD | PIN8)
+#define PIN_I2C0_SCL_4 (PIN_ALT5 | PIN_PORTE | PIN24)
+#define PIN_I2C0_SCL_5 (PIN_ALT7 | PIN_PORTD | PIN2)
+#define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1)
+#define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3)
+#define PIN_I2C0_SDA_3 (PIN_ALT2 | PIN_PORTD | PIN9)
+#define PIN_I2C0_SDA_4 (PIN_ALT5 | PIN_PORTE | PIN25)
+#define PIN_I2C0_SDA_5 (PIN_ALT7 | PIN_PORTD | PIN3)
+
+#define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10)
+#define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1)
+#define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11)
+#define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0)
+
+#define PIN_I2C2_SCL_1 (PIN_ALT5 | PIN_PORTA | PIN12)
+#define PIN_I2C2_SCL_2 (PIN_ALT5 | PIN_PORTA | PIN14)
+#define PIN_I2C2_SDA_1 (PIN_ALT5 | PIN_PORTA | PIN11)
+#define PIN_I2C2_SDA_2 (PIN_ALT5 | PIN_PORTA | PIN13)
+
+/* I2S */
+
+#define PIN_I2S0_MCLK_1 (PIN_ALT4 | PIN_PORTC | PIN8)
+#define PIN_I2S0_MCLK_2 (PIN_ALT4 | PIN_PORTE | PIN6)
+#define PIN_I2S0_MCLK_3 (PIN_ALT6 | PIN_PORTA | PIN17)
+#define PIN_I2S0_MCLK_4 (PIN_ALT6 | PIN_PORTC | PIN6)
+#define PIN_I2S0_RX_BCLK_1 (PIN_ALT4 | PIN_PORTC | PIN6)
+#define PIN_I2S0_RX_BCLK_2 (PIN_ALT4 | PIN_PORTC | PIN9)
+#define PIN_I2S0_RX_BCLK_3 (PIN_ALT4 | PIN_PORTE | PIN9)
+#define PIN_I2S0_RX_BCLK_4 (PIN_ALT6 | PIN_PORTA | PIN14)
+#define PIN_I2S0_RX_FS_1 (PIN_ALT4 | PIN_PORTC | PIN10)
+#define PIN_I2S0_RX_FS_2 (PIN_ALT4 | PIN_PORTC | PIN7)
+#define PIN_I2S0_RX_FS_3 (PIN_ALT4 | PIN_PORTE | PIN8)
+#define PIN_I2S0_RX_FS_4 (PIN_ALT6 | PIN_PORTA | PIN16)
+#define PIN_I2S0_RXD0_1 (PIN_ALT4 | PIN_PORTC | PIN5)
+#define PIN_I2S0_RXD0_2 (PIN_ALT4 | PIN_PORTE | PIN7)
+#define PIN_I2S0_RXD0_3 (PIN_ALT6 | PIN_PORTA | PIN15)
+#define PIN_I2S0_RXD1_1 (PIN_ALT2 | PIN_PORTE | PIN8)
+#define PIN_I2S0_RXD1_2 (PIN_ALT4 | PIN_PORTC | PIN11)
+#define PIN_I2S0_RXD1_3 (PIN_ALT7 | PIN_PORTA | PIN16)
+#define PIN_I2S0_TX_BCLK_1 (PIN_ALT4 | PIN_PORTB | PIN18)
+#define PIN_I2S0_TX_BCLK_2 (PIN_ALT4 | PIN_PORTE | PIN12)
+#define PIN_I2S0_TX_BCLK_3 (PIN_ALT6 | PIN_PORTA | PIN5)
+#define PIN_I2S0_TX_BCLK_4 (PIN_ALT6 | PIN_PORTC | PIN3)
+#define PIN_I2S0_TX_FS_1 (PIN_ALT4 | PIN_PORTB | PIN19)
+#define PIN_I2S0_TX_FS_2 (PIN_ALT4 | PIN_PORTE | PIN11)
+#define PIN_I2S0_TX_FS_3 (PIN_ALT6 | PIN_PORTA | PIN13)
+#define PIN_I2S0_TX_FS_4 (PIN_ALT6 | PIN_PORTC | PIN2)
+#define PIN_I2S0_TXD0_1 (PIN_ALT4 | PIN_PORTE | PIN10)
+#define PIN_I2S0_TXD0_2 (PIN_ALT6 | PIN_PORTA | PIN12)
+#define PIN_I2S0_TXD0_3 (PIN_ALT6 | PIN_PORTC | PIN1)
+#define PIN_I2S0_TXD1_1 (PIN_ALT2 | PIN_PORTE | PIN9)
+#define PIN_I2S0_TXD1_2 (PIN_ALT6 | PIN_PORTC | PIN0)
+#define PIN_I2S0_TXD1_3 (PIN_ALT7 | PIN_PORTA | PIN14)
+
+/* JTAG */
+
+#define PIN_JTAG_TCLK (PIN_ALT7 | PIN_PORTA | PIN0)
+#define PIN_JTAG_TDI (PIN_ALT7 | PIN_PORTA | PIN1)
+#define PIN_JTAG_TDO (PIN_ALT7 | PIN_PORTA | PIN2)
+#define PIN_JTAG_TMS (PIN_ALT7 | PIN_PORTA | PIN3)
+#define PIN_JTAG_TRST (PIN_ALT7 | PIN_PORTA | PIN5)
+
+/* Low-leakage wakeup module (LLWU, actually GPIO configurations) */
+
+#define PIN_LLWU_P0 (PIN_ALT1 | PIN_PORTE | PIN1)
+#define PIN_LLWU_P1 (PIN_ALT1 | PIN_PORTE | PIN2)
+#define PIN_LLWU_P2 (PIN_ALT1 | PIN_PORTE | PIN4)
+#define PIN_LLWU_P3 (PIN_ALT1 | PIN_PORTA | PIN4)
+#define PIN_LLWU_P4 (PIN_ALT1 | PIN_PORTA | PIN13)
+#define PIN_LLWU_P5 (PIN_ALT1 | PIN_PORTB | PIN0)
+#define PIN_LLWU_P6 (PIN_ALT1 | PIN_PORTC | PIN1)
+#define PIN_LLWU_P7 (PIN_ALT1 | PIN_PORTC | PIN3)
+#define PIN_LLWU_P8 (PIN_ALT1 | PIN_PORTC | PIN4)
+#define PIN_LLWU_P9 (PIN_ALT1 | PIN_PORTC | PIN5)
+#define PIN_LLWU_P10 (PIN_ALT1 | PIN_PORTC | PIN6)
+#define PIN_LLWU_P11 (PIN_ALT1 | PIN_PORTC | PIN11)
+#define PIN_LLWU_P12 (PIN_ALT1 | PIN_PORTD | PIN0)
+#define PIN_LLWU_P13 (PIN_ALT1 | PIN_PORTD | PIN2)
+#define PIN_LLWU_P14 (PIN_ALT1 | PIN_PORTD | PIN4)
+#define PIN_LLWU_P15 (PIN_ALT1 | PIN_PORTD | PIN6)
+
+/* Low-Power Timer (LPTMR) */
+
+#define PIN_LPTMR0_ALT1 (PIN_ALT6 | PIN_PORTA | PIN19)
+#define PIN_LPTMR0_ALT2 (PIN_ALT3 | PIN_PORTC | PIN5)
+
+/* MII */
+
+#define PIN_MII0_COL (PIN_ALT4 | PIN_PORTA | PIN29)
+#define PIN_MII0_CRS (PIN_ALT4 | PIN_PORTA | PIN27)
+#define PIN_MII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1)
+#ifdef CONFIG_KINETIS_ENET_MDIOPULLUP
+# define PIN_MII0_MDIO (PIN_ALT4_PULLUP | PIN_PORTB | PIN0)
+#else
+# define PIN_MII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
+#endif
+#define PIN_MII0_RXCLK (PIN_ALT4 | PIN_PORTA | PIN11)
+#define PIN_MII0_RXD0 (PIN_ALT4 | PIN_PORTA | PIN13)
+#define PIN_MII0_RXD1 (PIN_ALT4 | PIN_PORTA | PIN12)
+#define PIN_MII0_RXD2 (PIN_ALT4 | PIN_PORTA | PIN10)
+#define PIN_MII0_RXD3 (PIN_ALT4 | PIN_PORTA | PIN9)
+#define PIN_MII0_RXDV (PIN_ALT4 | PIN_PORTA | PIN14)
+#ifdef CONFIG_KINETIS_ENET_NORXER
+# define PIN_MII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
+#else
+# define PIN_MII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
+#endif
+#define PIN_MII0_TXCLK (PIN_ALT4 | PIN_PORTA | PIN25)
+#define PIN_MII0_TXD0 (PIN_ALT4 | PIN_PORTA | PIN16)
+#define PIN_MII0_TXD1 (PIN_ALT4 | PIN_PORTA | PIN17)
+#define PIN_MII0_TXD2 (PIN_ALT4 | PIN_PORTA | PIN24)
+#define PIN_MII0_TXD3 (PIN_ALT4 | PIN_PORTA | PIN26)
+#define PIN_MII0_TXEN (PIN_ALT4 | PIN_PORTA | PIN15)
+#define PIN_MII0_TXER (PIN_ALT4 | PIN_PORTA | PIN28)
+
+/* NMI */
+
+#define PIN_NMI (PIN_ALT7 | PIN_PORTA | PIN4)
+
+/* Programmable Delay Block (PDB) */
+
+#define PIN_PDB0_EXTRG_1 (PIN_ALT3 | PIN_PORTC | PIN0)
+#define PIN_PDB0_EXTRG_2 (PIN_ALT3 | PIN_PORTC | PIN6)
+
+/* RMII */
+
+#define PIN_RMII0_CRS_DV (PIN_ALT4 | PIN_PORTA | PIN14)
+#define PIN_RMII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1)
+#ifdef CONFIG_KINETIS_ENET_MDIOPULLUP
+# define PIN_RMII0_MDIO (PIN_ALT4_PULLUP | PIN_PORTB | PIN0)
+#else
+# define PIN_RMII0_MDIO (PIN_ALT4 | PIN_PORTB | PIN0)
+#endif
+#define PIN_RMII0_RXD0 (PIN_ALT4 | PIN_PORTA | PIN13)
+#define PIN_RMII0_RXD1 (PIN_ALT4 | PIN_PORTA | PIN12)
+#ifdef CONFIG_KINETIS_ENET_NORXER
+# define PIN_RMII0_RXER (GPIO_PULLDOWN | PIN_PORTA | PIN5)
+#else
+# define PIN_RMII0_RXER (PIN_ALT4 | PIN_PORTA | PIN5)
+#endif
+#define PIN_RMII0_TXD0 (PIN_ALT4 | PIN_PORTA | PIN16)
+#define PIN_RMII0_TXD1 (PIN_ALT4 | PIN_PORTA | PIN17)
+#define PIN_RMII0_TXEN (PIN_ALT4 | PIN_PORTA | PIN15)
+
+/* Real-Time Clock (RTC) */
+
+#define PIN_RTC_CLKOUT_1 (PIN_ALT6 | PIN_PORTE | PIN26)
+#define PIN_RTC_CLKOUT_2 (PIN_ALT7 | PIN_PORTE | PIN0)
+
+/* Secured digital host controller (SDHC) */
+
+#define PIN_SDHC0_CLKIN (PIN_ALT4 | PIN_PORTD | PIN11)
+#define PIN_SDHC0_CMD (PIN_ALT4 | PIN_PORTE | PIN3)
+#define PIN_SDHC0_D0 (PIN_ALT4 | PIN_PORTE | PIN1)
+#define PIN_SDHC0_D1 (PIN_ALT4 | PIN_PORTE | PIN0)
+#define PIN_SDHC0_D2 (PIN_ALT4 | PIN_PORTE | PIN5)
+#define PIN_SDHC0_D3 (PIN_ALT4 | PIN_PORTE | PIN4)
+#define PIN_SDHC0_D4 (PIN_ALT4 | PIN_PORTD | PIN12)
+#define PIN_SDHC0_D5 (PIN_ALT4 | PIN_PORTD | PIN13)
+#define PIN_SDHC0_D6 (PIN_ALT4 | PIN_PORTD | PIN14)
+#define PIN_SDHC0_D7 (PIN_ALT4 | PIN_PORTD | PIN15)
+#define PIN_SDHC0_DCLK (PIN_ALT4 | PIN_PORTE | PIN2)
+
+/* SPI */
+
+#define PIN_SPI0_PCS0_1 (PIN_ALT2 | PIN_PORTA | PIN14)
+#define PIN_SPI0_PCS0_2 (PIN_ALT2 | PIN_PORTC | PIN4)
+#define PIN_SPI0_PCS0_3 (PIN_ALT2 | PIN_PORTD | PIN0)
+#define PIN_SPI0_PCS1_1 (PIN_ALT2 | PIN_PORTC | PIN3)
+#define PIN_SPI0_PCS1_2 (PIN_ALT2 | PIN_PORTD | PIN4)
+#define PIN_SPI0_PCS2_1 (PIN_ALT2 | PIN_PORTC | PIN2)
+#define PIN_SPI0_PCS2_3 (PIN_ALT2 | PIN_PORTD | PIN5)
+#define PIN_SPI0_PCS3_1 (PIN_ALT2 | PIN_PORTC | PIN1)
+#define PIN_SPI0_PCS3_2 (PIN_ALT2 | PIN_PORTD | PIN6)
+#define PIN_SPI0_PCS4 (PIN_ALT2 | PIN_PORTC | PIN0)
+#define PIN_SPI0_PCS5 (PIN_ALT3 | PIN_PORTB | PIN23)
+#define PIN_SPI0_SCK_1 (PIN_ALT2 | PIN_PORTA | PIN15)
+#define PIN_SPI0_SCK_2 (PIN_ALT2 | PIN_PORTC | PIN5)
+#define PIN_SPI0_SCK_3 (PIN_ALT2 | PIN_PORTD | PIN1)
+#define PIN_SPI0_SIN_1 (PIN_ALT2 | PIN_PORTA | PIN17)
+#define PIN_SPI0_SIN_2 (PIN_ALT2 | PIN_PORTC | PIN7)
+#define PIN_SPI0_SIN_3 (PIN_ALT2 | PIN_PORTD | PIN3)
+#define PIN_SPI0_SOUT_1 (PIN_ALT2 | PIN_PORTA | PIN16)
+#define PIN_SPI0_SOUT_2 (PIN_ALT2 | PIN_PORTC | PIN6)
+#define PIN_SPI0_SOUT_3 (PIN_ALT2 | PIN_PORTD | PIN2)
+
+#define PIN_SPI1_PCS0_1 (PIN_ALT2 | PIN_PORTB | PIN10)
+#define PIN_SPI1_PCS0_2 (PIN_ALT2 | PIN_PORTE | PIN4)
+#define PIN_SPI1_PCS0_3 (PIN_ALT7 | PIN_PORTD | PIN4)
+#define PIN_SPI1_PCS1_1 (PIN_ALT2 | PIN_PORTB | PIN9)
+#define PIN_SPI1_PCS1_2 (PIN_ALT2 | PIN_PORTE | PIN0)
+#define PIN_SPI1_PCS2 (PIN_ALT2 | PIN_PORTE | PIN5)
+#define PIN_SPI1_PCS3 (PIN_ALT2 | PIN_PORTE | PIN6)
+#define PIN_SPI1_SCK_1 (PIN_ALT2 | PIN_PORTB | PIN11)
+#define PIN_SPI1_SCK_2 (PIN_ALT2 | PIN_PORTE | PIN2)
+#define PIN_SPI1_SCK_3 (PIN_ALT7 | PIN_PORTD | PIN5)
+#define PIN_SPI1_SIN_1 (PIN_ALT2 | PIN_PORTB | PIN17)
+#define PIN_SPI1_SIN_2 (PIN_ALT2 | PIN_PORTE | PIN3)
+#define PIN_SPI1_SIN_3 (PIN_ALT7 | PIN_PORTD | PIN7)
+#define PIN_SPI1_SIN_4 (PIN_ALT7 | PIN_PORTE | PIN1)
+#define PIN_SPI1_SOUT_1 (PIN_ALT2 | PIN_PORTB | PIN16)
+#define PIN_SPI1_SOUT_2 (PIN_ALT2 | PIN_PORTE | PIN1)
+#define PIN_SPI1_SOUT_3 (PIN_ALT7 | PIN_PORTD | PIN6)
+#define PIN_SPI1_SOUT_4 (PIN_ALT7 | PIN_PORTE | PIN3)
+
+#define PIN_SPI2_PCS0_1 (PIN_ALT2 | PIN_PORTB | PIN20)
+#define PIN_SPI2_PCS0_2 (PIN_ALT2 | PIN_PORTD | PIN11)
+#define PIN_SPI2_PCS1 (PIN_ALT2 | PIN_PORTD | PIN15)
+#define PIN_SPI2_SCK_1 (PIN_ALT2 | PIN_PORTB | PIN21)
+#define PIN_SPI2_SCK_2 (PIN_ALT2 | PIN_PORTD | PIN12)
+#define PIN_SPI2_SIN_1 (PIN_ALT2 | PIN_PORTB | PIN23)
+#define PIN_SPI2_SIN_2 (PIN_ALT2 | PIN_PORTD | PIN14)
+#define PIN_SPI2_SOUT_1 (PIN_ALT2 | PIN_PORTB | PIN22)
+#define PIN_SPI2_SOUT_2 (PIN_ALT2 | PIN_PORTD | PIN13)
+
+/* SWD */
+
+#define PIN_SWD_CLK (PIN_ALT7 | PIN_PORTA | PIN0)
+#define PIN_SWD_DIO (PIN_ALT7 | PIN_PORTA | PIN3)
+
+/* Trace */
+
+#define PIN_TRACE_CLKOUT_1 (PIN_ALT5 | PIN_PORTE | PIN0)
+#define PIN_TRACE_CLKOUT_2 (PIN_ALT7 | PIN_PORTA | PIN6)
+#define PIN_TRACE_D0_1 (PIN_ALT5 | PIN_PORTE | PIN4)
+#define PIN_TRACE_D0_2 (PIN_ALT7 | PIN_PORTA | PIN10)
+#define PIN_TRACE_D1_1 (PIN_ALT5 | PIN_PORTE | PIN3)
+#define PIN_TRACE_D1_2 (PIN_ALT7 | PIN_PORTA | PIN9)
+#define PIN_TRACE_D2_1 (PIN_ALT5 | PIN_PORTE | PIN2)
+#define PIN_TRACE_D2_2 (PIN_ALT7 | PIN_PORTA | PIN8)
+#define PIN_TRACE_D3_1 (PIN_ALT5 | PIN_PORTE | PIN1)
+#define PIN_TRACE_D3_2 (PIN_ALT7 | PIN_PORTA | PIN7)
+#define PIN_TRACE_SWO (PIN_ALT7 | PIN_PORTA | PIN2)
+
+/* UARTs */
+
+#define PIN_UART0_COL_1 (PIN_ALT2 | PIN_PORTA | PIN0)
+#define PIN_UART0_COL_2 (PIN_ALT3 | PIN_PORTA | PIN16)
+#define PIN_UART0_COL_3 (PIN_ALT3 | PIN_PORTB | PIN3)
+#define PIN_UART0_COL_4 (PIN_ALT3 | PIN_PORTD | PIN5)
+#define PIN_UART0_CTS_1 (PIN_ALT2 | PIN_PORTA | PIN0)
+#define PIN_UART0_CTS_2 (PIN_ALT3 | PIN_PORTA | PIN16)
+#define PIN_UART0_CTS_3 (PIN_ALT3 | PIN_PORTB | PIN3)
+#define PIN_UART0_CTS_4 (PIN_ALT3 | PIN_PORTD | PIN5)
+#define PIN_UART0_RTS_1 (PIN_ALT2 | PIN_PORTA | PIN3)
+#define PIN_UART0_RTS_2 (PIN_ALT3 | PIN_PORTA | PIN17)
+#define PIN_UART0_RTS_3 (PIN_ALT3 | PIN_PORTB | PIN2)
+#define PIN_UART0_RTS_4 (PIN_ALT3 | PIN_PORTD | PIN4)
+#define PIN_UART0_RX_1 (PIN_ALT2 | PIN_PORTA | PIN1)
+#define PIN_UART0_RX_2 (PIN_ALT3 | PIN_PORTA | PIN15)
+#define PIN_UART0_RX_3 (PIN_ALT3 | PIN_PORTB | PIN16)
+#define PIN_UART0_RX_4 (PIN_ALT3 | PIN_PORTD | PIN6)
+#define PIN_UART0_TX_1 (PIN_ALT2 | PIN_PORTA | PIN2)
+#define PIN_UART0_TX_2 (PIN_ALT3 | PIN_PORTA | PIN14)
+#define PIN_UART0_TX_3 (PIN_ALT3 | PIN_PORTB | PIN17)
+#define PIN_UART0_TX_4 (PIN_ALT3 | PIN_PORTD | PIN7)
+
+#define PIN_UART1_CTS_1 (PIN_ALT3 | PIN_PORTC | PIN2)
+#define PIN_UART1_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN2)
+#define PIN_UART1_RTS_1 (PIN_ALT3 | PIN_PORTC | PIN1)
+#define PIN_UART1_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN3)
+#define PIN_UART1_RX_1 (PIN_ALT3 | PIN_PORTC | PIN3)
+#define PIN_UART1_RX_2 (PIN_ALT3 | PIN_PORTE | PIN1)
+#define PIN_UART1_TX_1 (PIN_ALT3 | PIN_PORTC | PIN4)
+#define PIN_UART1_TX_2 (PIN_ALT3 | PIN_PORTE | PIN0)
+
+#define PIN_UART2_CTS (PIN_ALT3 | PIN_PORTD | PIN1)
+#define PIN_UART2_RTS (PIN_ALT3 | PIN_PORTD | PIN0)
+#define PIN_UART2_RX (PIN_ALT3 | PIN_PORTD | PIN2)
+#define PIN_UART2_TX (PIN_ALT3 | PIN_PORTD | PIN3)
+
+#define PIN_UART3_CTS_1 (PIN_ALT2 | PIN_PORTB | PIN13)
+#define PIN_UART3_CTS_2 (PIN_ALT3 | PIN_PORTB | PIN9)
+#define PIN_UART3_CTS_3 (PIN_ALT3 | PIN_PORTC | PIN19)
+#define PIN_UART3_CTS_4 (PIN_ALT3 | PIN_PORTE | PIN6)
+#define PIN_UART3_RTS_1 (PIN_ALT2 | PIN_PORTB | PIN12)
+#define PIN_UART3_RTS_2 (PIN_ALT3 | PIN_PORTB | PIN8)
+#define PIN_UART3_RTS_3 (PIN_ALT3 | PIN_PORTC | PIN18)
+#define PIN_UART3_RTS_4 (PIN_ALT3 | PIN_PORTE | PIN7)
+#define PIN_UART3_RX_1 (PIN_ALT3 | PIN_PORTB | PIN10)
+#define PIN_UART3_RX_2 (PIN_ALT3 | PIN_PORTC | PIN16)
+#define PIN_UART3_RX_3 (PIN_ALT3 | PIN_PORTE | PIN5)
+#define PIN_UART3_TX_1 (PIN_ALT3 | PIN_PORTB | PIN11)
+#define PIN_UART3_TX_2 (PIN_ALT3 | PIN_PORTC | PIN17)
+#define PIN_UART3_TX_3 (PIN_ALT3 | PIN_PORTE | PIN4)
+
+#define PIN_UART4_CTS_1 (PIN_ALT3 | PIN_PORTC | PIN13)
+#define PIN_UART4_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN26)
+#define PIN_UART4_RTS_1 (PIN_ALT3 | PIN_PORTC | PIN12)
+#define PIN_UART4_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN27)
+#define PIN_UART4_RX_1 (PIN_ALT3 | PIN_PORTC | PIN14)
+#define PIN_UART4_RX_2 (PIN_ALT3 | PIN_PORTE | PIN25)
+#define PIN_UART4_TX_1 (PIN_ALT3 | PIN_PORTC | PIN15)
+#define PIN_UART4_TX_2 (PIN_ALT3 | PIN_PORTE | PIN24)
+
+#define PIN_UART5_CTS_1 (PIN_ALT3 | PIN_PORTD | PIN11)
+#define PIN_UART5_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN10)
+#define PIN_UART5_RTS_1 (PIN_ALT3 | PIN_PORTD | PIN10)
+#define PIN_UART5_RTS_2 (PIN_ALT3 | PIN_PORTE | PIN11)
+#define PIN_UART5_RX_1 (PIN_ALT3 | PIN_PORTD | PIN8)
+#define PIN_UART5_RX_2 (PIN_ALT3 | PIN_PORTE | PIN9)
+#define PIN_UART5_TX_1 (PIN_ALT3 | PIN_PORTD | PIN9)
+#define PIN_UART5_TX_2 (PIN_ALT3 | PIN_PORTE | PIN8)
+
+/* USB */
+
+#define PIN_USB_CLKIN_1 (PIN_ALT2 | PIN_PORTA | PIN5)
+#define PIN_USB_CLKIN_2 (PIN_ALT7 | PIN_PORTE | PIN26)
+#define PIN_USB_SOF_OUT_1 (PIN_ALT3 | PIN_PORTC | PIN7)
+#define PIN_USB_SOF_OUT_2 (PIN_ALT4 | PIN_PORTC | PIN0)
+#define PIN_USB_SOF_OUT_3 (PIN_ALT7 | PIN_PORTE | PIN6)
+
+/* External Crystal */
+
+#define PIN_EXTAL0 (PIN_ANALOG | PIN_PORTA | PIN18)
+#define PIN_XTAL0 (PIN_ANALOG | PIN_PORTA | PIN19)
+
+/********************************************************************************************
+ * Public Types
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Functions
+ ********************************************************************************************/
+
+#endif /* KINETIS_K64 */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHP_KINETIS_K64PINMUX_H */
diff --git a/arch/arm/src/kinetis/kinetis_llwu.h b/arch/arm/src/kinetis/chip/kinetis_llwu.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_llwu.h
rename to arch/arm/src/kinetis/chip/kinetis_llwu.h
index 4324a76251b412e0a542816025f408c85514f8a2..ae5c6c8b04c1edf2e7031037505af25869e55b51 100644
--- a/arch/arm/src/kinetis/kinetis_llwu.h
+++ b/arch/arm/src/kinetis/chip/kinetis_llwu.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_llwu.h
+ * arch/arm/src/kinetis/chip/kinetis_llwu.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_LLWU_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_LLWU_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_LLWU_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_LLWU_H
/************************************************************************************
* Included Files
@@ -249,4 +249,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_LLWU_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_LLWU_H */
diff --git a/arch/arm/src/kinetis/kinetis_lptmr.h b/arch/arm/src/kinetis/chip/kinetis_lptmr.h
similarity index 96%
rename from arch/arm/src/kinetis/kinetis_lptmr.h
rename to arch/arm/src/kinetis/chip/kinetis_lptmr.h
index 863b24108eacec47e4808534cc2a7e93ff602132..15aeb4a5614c386f5a78b8a8c321ca6acf139fce 100644
--- a/arch/arm/src/kinetis/kinetis_lptmr.h
+++ b/arch/arm/src/kinetis/chip/kinetis_lptmr.h
@@ -1,7 +1,7 @@
/****************************************************************************************************
- * arch/arm/src/kinetis/kinetis_lptmr.h
+ * arch/arm/src/kinetis/chip/kinetis_lptmr.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
****************************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_LPTMR_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_LPTMR_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_LPTMR_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_LPTMR_H
/****************************************************************************************************
* Included Files
@@ -130,4 +130,4 @@
* Public Functions
****************************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_LPTMR_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_LPTMR_H */
diff --git a/arch/arm/src/kinetis/kinetis_mcg.h b/arch/arm/src/kinetis/chip/kinetis_mcg.h
similarity index 92%
rename from arch/arm/src/kinetis/kinetis_mcg.h
rename to arch/arm/src/kinetis/chip/kinetis_mcg.h
index 60f13cd2a0b788ef8e897b0c9adbeee28387aae0..fe8dccc60e1d8419634d008d9af9aa184c32bbe7 100644
--- a/arch/arm/src/kinetis/kinetis_mcg.h
+++ b/arch/arm/src/kinetis/chip/kinetis_mcg.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_mcg.h
+ * arch/arm/src/kinetis/chip/kinetis_mcg.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MCG_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_MCG_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MCG_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MCG_H
/************************************************************************************
* Included Files
@@ -60,6 +60,10 @@
#define KINETIS_MCG_ATC_OFFSET 0x0008 /* MCG Auto Trim Control Register */
#define KINETIS_MCG_ATCVH_OFFSET 0x000a /* MCG Auto Trim Compare Value High Register */
#define KINETIS_MCG_ATCVL_OFFSET 0x000b /* MCG Auto Trim Compare Value Low Register */
+#ifdef KINETIS_K64
+# define KINETIS_MCG_C7_OFFSET 0x000c /* MCG Control 7 Register */
+# define KINETIS_MCG_C8_OFFSET 0x000d /* MCG Control 8 Register */
+#endif
/* Register Addresses ***************************************************************/
@@ -73,6 +77,10 @@
#define KINETIS_MCG_ATC (KINETIS_MCG_BASE+KINETIS_MCG_ATC_OFFSET)
#define KINETIS_MCG_ATCVH (KINETIS_MCG_BASE+KINETIS_MCG_ATCVH_OFFSET)
#define KINETIS_MCG_ATCVL (KINETIS_MCG_BASE+KINETIS_MCG_ATCVL_OFFSET)
+#ifdef KINETIS_K64
+# define KINETIS_MCG_C7 (KINETIS_MCG_BASE+KINETIS_MCG_C7_OFFSET)
+# define KINETIS_MCG_C8 (KINETIS_MCG_BASE+KINETIS_MCG_C8_OFFSET)
+#endif
/* Register Bit Definitions *********************************************************/
@@ -134,7 +142,7 @@
#define MCG_C5_PRDIV_SHIFT (0) /* Bits 0-4: PLL External Reference Divider */
#define MCG_C5_PRDIV_MASK (31 << MCG_C5_PRDIV_SHIFT)
-# define MCG_C5_PRDIV(n) (((n)-1) << MCG_C5_PRDIV_SHIFT) /* Divide factor n=1..25 */
+# define MCG_C5_PRDIV(n) ((uint32_t)((n)-1) << MCG_C5_PRDIV_SHIFT) /* n=1..25 */
#define MCG_C5_PLLSTEN (1 << 5) /* Bit 5: PLL Stop Enable */
#define MCG_C5_PLLCLKEN (1 << 6) /* Bit 6: PLL Clock Enable */
/* Bit 7: Reserved */
@@ -143,7 +151,7 @@
#define MCG_C6_VDIV_SHIFT (0) /* Bits 0-4: VCO Divider */
#define MCG_C6_VDIV_MASK (31 << MCG_C6_VDIV_SHIFT)
-# define MCG_C6_VDIV(n) (((n)-24) << MCG_C6_VDIV_SHIFT) /* Divide factor n=24..55 */
+# define MCG_C6_VDIV(n) ((uint32_t)((n)-24) << MCG_C6_VDIV_SHIFT) /* n=24..55 */
#define MCG_C6_CME (1 << 5) /* Bit 5: Clock Monitor Enable */
#define MCG_C6_PLLS (1 << 6) /* Bit 6: PLL Select */
#define MCG_C6_LOLIE (1 << 7) /* Bit 7: Loss of Lock Interrrupt Enable */
@@ -171,6 +179,10 @@
/* MCG Auto Trim Compare Value High/Low Registers (8-bit compare value) */
+/* MCG Control 7 Register */
+
+/* MCG Control 8 Register */
+
/************************************************************************************
* Public Types
************************************************************************************/
@@ -183,4 +195,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MCG_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MCG_H */
diff --git a/arch/arm/src/kinetis/kinetis_mcm.h b/arch/arm/src/kinetis/chip/kinetis_mcm.h
similarity index 94%
rename from arch/arm/src/kinetis/kinetis_mcm.h
rename to arch/arm/src/kinetis/chip/kinetis_mcm.h
index d899b77027ac135150314bfaf214ef3cc7ba6c29..f46305056ef84f13d7cc8766a0ecfdaf26c45f9e 100644
--- a/arch/arm/src/kinetis/kinetis_mcm.h
+++ b/arch/arm/src/kinetis/chip/kinetis_mcm.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_mcm.h
+ * arch/arm/src/kinetis/chip/kinetis_mcm.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MCM_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_MCM_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MCM_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MCM_H
/************************************************************************************
* Included Files
@@ -57,6 +57,9 @@
#define KINETIS_MCM_ETBCC_OFFSET 0x0014 /* ETB counter control register */
#define KINETIS_MCM_ETBRL_OFFSET 0x0018 /* ETB reload register */
#define KINETIS_MCM_ETBCNT_OFFSET 0x001c /* ETB counter value register */
+#ifdef KINETIS_K64
+# define KINETIS_MCM_PID_OFFSET 0x0030 /* Process ID register */
+#endif
/* Register Addresses ***************************************************************/
@@ -67,6 +70,9 @@
#define KINETIS_MCM_ETBCC (KINETIS_MCM_BASE+KINETIS_MCM_ETBCC_OFFSET)
#define KINETIS_MCM_ETBRL (KINETIS_MCM_BASE+KINETIS_MCM_ETBRL_OFFSET)
#define KINETIS_MCM_ETBCNT (KINETIS_MCM_BASE+KINETIS_MCM_ETBCNT_OFFSET)
+#ifdef KINETIS_K64
+# define KINETIS_MCM_PID (KINETIS_MCM_BASE+KINETIS_MCM_PID_OFFSET)
+#endif
/* Register Bit Definitions *********************************************************/
@@ -148,4 +154,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MCM_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MCM_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_memorymap.h b/arch/arm/src/kinetis/chip/kinetis_memorymap.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec67d42820dc8cbea8c1a60409314365a3a28c06
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_memorymap.h
@@ -0,0 +1,79 @@
+/********************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_memorymap.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MEMORYMAP_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MEMORYMAP_H
+
+/********************************************************************************************
+ * Included Files
+ ********************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/* This file is just a wrapper around pin muxing header files for the Kinetis family selected
+ * by the logic in chip.h.
+ */
+
+#if defined(KINETIS_K20)
+# include "chip/kinetis_k20memorymap.h"
+#elif defined(KINETIS_K40)
+# include "chip/kinetis_k40memorymap.h"
+#elif defined(KINETIS_K60)
+# include "chip/kinetis_k60memorymap.h"
+#elif defined(KINETIS_K64)
+# include "chip/kinetis_k64memorymap.h"
+#else
+# error "No memory map for this Kinetis part"
+#endif
+
+/********************************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Types
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Functions
+ ********************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MEMORYMAP_H */
diff --git a/arch/arm/src/kinetis/kinetis_mmcau.h b/arch/arm/src/kinetis/chip/kinetis_mmcau.h
similarity index 89%
rename from arch/arm/src/kinetis/kinetis_mmcau.h
rename to arch/arm/src/kinetis/chip/kinetis_mmcau.h
index 7468a1d0bfe3b3563918e57adf8a99bdfb0aed86..90c9cf6552cdf60eafd0b00f4d924d3aac2f2326 100644
--- a/arch/arm/src/kinetis/kinetis_mmcau.h
+++ b/arch/arm/src/kinetis/chip/kinetis_mmcau.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_mmcau.h
+ * arch/arm/src/kinetis/chip/kinetis_mmcau.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_MMCAU_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_MMCAU_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MMCAU_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MMCAU_H
/************************************************************************************
* Included Files
@@ -61,9 +61,11 @@
#define KINETIS_CAU_CA3_OFFSET 0x0005 /* General Purpose Register 3 */
#define KINETIS_CAU_CA4_OFFSET 0x0006 /* General Purpose Register 4 */
#define KINETIS_CAU_CA5_OFFSET 0x0007 /* General Purpose Register 5 */
-#define KINETIS_CAU_CA6_OFFSET 0x0008 /* General Purpose Register 6 */
-#define KINETIS_CAU_CA7_OFFSET 0x0009 /* General Purpose Register 7 */
-#define KINETIS_CAU_CA8_OFFSET 0x000a /* General Purpose Register 8 */
+#ifndef KINETIS_K64
+# define KINETIS_CAU_CA6_OFFSET 0x0008 /* General Purpose Register 6 */
+# define KINETIS_CAU_CA7_OFFSET 0x0009 /* General Purpose Register 7 */
+# define KINETIS_CAU_CA8_OFFSET 0x000a /* General Purpose Register 8 */
+#endif
/* Register Addresses ***************************************************************/
@@ -77,9 +79,11 @@
#define KINETIS_CAU_CA3 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA3_OFFSET)
#define KINETIS_CAU_CA4 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA4_OFFSET)
#define KINETIS_CAU_CA5 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA5_OFFSET)
-#define KINETIS_CAU_CA6 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA6_OFFSET)
-#define KINETIS_CAU_CA7 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA7_OFFSET)
-#define KINETIS_CAU_CA8 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA8_OFFSET)
+#ifndef KINETIS_K64
+# define KINETIS_CAU_CA6 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA6_OFFSET)
+# define KINETIS_CAU_CA7 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA7_OFFSET)
+# define KINETIS_CAU_CA8 (KINETIS_MMCAU_BASE+KINETIS_CAU_CA8_OFFSET)
+#endif
/* Register Bit Definitions *********************************************************/
@@ -135,4 +139,4 @@
************************************************************************************/
#endif /* KINETIS_NMMCAU && KINETIS_NMMCAU > 0 */
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MMCAU_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MMCAU_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_mpu.h b/arch/arm/src/kinetis/chip/kinetis_mpu.h
new file mode 100644
index 0000000000000000000000000000000000000000..1faa605d75bc91be58b7425930549c7facd947d6
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_mpu.h
@@ -0,0 +1,75 @@
+/********************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_mpu.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MPU_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MPU_H
+
+/********************************************************************************************
+ * Included Files
+ ********************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/* This file is just a wrapper around pin muxing header files for the Kinetis family selected
+ * by the logic in chip.h.
+ */
+
+#if defined(KINETIS_K20) || defined(KINETIS_K40) || defined(KINETIS_K60)
+# include "chip/kinetis_k20k40k60mpu.h"
+#elif defined(KINETIS_K64)
+# include "chip/kinetis_k64mpu.h"
+#else
+# error "No MPU definitions for this Kinetis part"
+#endif
+
+/********************************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Types
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Functions
+ ********************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_MPU_H */
diff --git a/arch/arm/src/kinetis/kinetis_osc.h b/arch/arm/src/kinetis/chip/kinetis_osc.h
similarity index 93%
rename from arch/arm/src/kinetis/kinetis_osc.h
rename to arch/arm/src/kinetis/chip/kinetis_osc.h
index 16efcf328266055cf0ac411838a8b948dd520f93..69a7b8a30c8cabb5d7fd8ea17946893363f1437e 100644
--- a/arch/arm/src/kinetis/kinetis_osc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_osc.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_osc.h
+ * arch/arm/src/kinetis/chip/kinetis_osc.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_OSC_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_OSC_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIHP_KINETIS_OSC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIHP_KINETIS_OSC_H
/********************************************************************************************
* Included Files
@@ -81,4 +81,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_OSC_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIHP_KINETIS_OSC_H */
diff --git a/arch/arm/src/kinetis/kinetis_pdb.h b/arch/arm/src/kinetis/chip/kinetis_pdb.h
similarity index 95%
rename from arch/arm/src/kinetis/kinetis_pdb.h
rename to arch/arm/src/kinetis/chip/kinetis_pdb.h
index 9cfab9b99f187b3dbe0440f2c486d32c84784ce5..d0238240dfabe07583762fbc2a77cc1d94fbb4bd 100644
--- a/arch/arm/src/kinetis/kinetis_pdb.h
+++ b/arch/arm/src/kinetis/chip/kinetis_pdb.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_pdb.h
+ * arch/arm/src/kinetis/chip/kinetis_pdb.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PDB_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_PDB_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PDB_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PDB_H
/********************************************************************************************
* Included Files
@@ -83,6 +83,10 @@
#define KINETIS_PDB_PO0EN_OFFSET 0x0190 /* Pulse-Out 0 Enable Register */
#define KINETIS_PDB_PO0DLY_OFFSET 0x0194 /* Pulse-Out 0 Delay Register */
+#ifdef KINETIS_K64
+# define KINETIS_PDB_PO1DLY_OFFSET 0x0198 /* Pulse-Out 1 Delay Register */
+# define KINETIS_PDB_PO2DLY_OFFSET 0x019c /* Pulse-Out 2 Delay Register */
+#endif
/* Register Addresses ***********************************************************************/
@@ -119,6 +123,10 @@
#define KINETIS_PDB0_PO0EN (KINETIS_PDB0_BASE+KINETIS_PDB_PO0EN_OFFSET)
#define KINETIS_PDB0_PO0DLY (KINETIS_PDB0_BASE+KINETIS_PDB_PO0DLY_OFFSET)
+#ifdef KINETIS_K64
+# define KINETIS_PDB0_PO1DLY (KINETIS_PDB0_BASE+KINETIS_PDB_PO1DLY_OFFSET)
+# define KINETIS_PDB0_PO2DLY (KINETIS_PDB0_BASE+KINETIS_PDB_PO2DLY_OFFSET)
+#endif
/* Register Bit Definitions *****************************************************************/
@@ -252,4 +260,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PDB_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PDB_H */
diff --git a/arch/arm/src/kinetis/kinetis_pinmux.h b/arch/arm/src/kinetis/chip/kinetis_pinmux.h
similarity index 87%
rename from arch/arm/src/kinetis/kinetis_pinmux.h
rename to arch/arm/src/kinetis/chip/kinetis_pinmux.h
index 589184ffdd2ceb507fa865da22fd9f0b37d54bb0..0a6aeb82532b8c506b5aa07c4434d36d2683748b 100644
--- a/arch/arm/src/kinetis/kinetis_pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_pinmux.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_pinmux.h
+ * arch/arm/src/kinetis/chip/kinetis_pinmux.h
*
- * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PINMUX_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_PINMUX_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PINMUX_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PINMUX_H
/********************************************************************************************
* Included Files
@@ -49,11 +49,13 @@
*/
#if defined(KINETIS_K20)
-# include "kinetis_k20pinmux.h"
+# include "chip/kinetis_k20pinmux.h"
#elif defined(KINETIS_K40)
-# include "kinetis_k40pinmux.h"
+# include "chip/kinetis_k40pinmux.h"
#elif defined(KINETIS_K60)
-# include "kinetis_k60pinmux.h"
+# include "chip/kinetis_k60pinmux.h"
+#elif defined(KINETIS_K64)
+# include "chip/kinetis_k64pinmux.h"
#else
# error "No pin multiplexing for this Kinetis part"
#endif
@@ -74,4 +76,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PINMUX_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PINMUX_H */
diff --git a/arch/arm/src/kinetis/kinetis_pit.h b/arch/arm/src/kinetis/chip/kinetis_pit.h
similarity index 96%
rename from arch/arm/src/kinetis/kinetis_pit.h
rename to arch/arm/src/kinetis/chip/kinetis_pit.h
index 808508f8fedd17be9e6af540338c248095be02fc..26cd6caea6dd16ed146060852473da3708811cb9 100644
--- a/arch/arm/src/kinetis/kinetis_pit.h
+++ b/arch/arm/src/kinetis/chip/kinetis_pit.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_pit.h
+ * arch/arm/src/kinetis/chip/kinetis_pit.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PIT_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_PIT_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PIT_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PIT_H
/************************************************************************************
* Included Files
@@ -121,4 +121,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PIT_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PIT_H */
diff --git a/arch/arm/src/kinetis/kinetis_pmc.h b/arch/arm/src/kinetis/chip/kinetis_pmc.h
similarity index 95%
rename from arch/arm/src/kinetis/kinetis_pmc.h
rename to arch/arm/src/kinetis/chip/kinetis_pmc.h
index 065847da3d5a6f5bc702e8f7f44b8b1d7273ccad..c0ffe575b3615a691239db95ba764631c63dd686 100644
--- a/arch/arm/src/kinetis/kinetis_pmc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_pmc.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_pmc.h
+ * arch/arm/src/kinetis/chip/kinetis_pmc.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PMC_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_PMC_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PMC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PMC_H
/************************************************************************************
* Included Files
@@ -108,4 +108,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PMC_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PMC_H */
diff --git a/arch/arm/src/kinetis/kinetis_port.h b/arch/arm/src/kinetis/chip/kinetis_port.h
similarity index 99%
rename from arch/arm/src/kinetis/kinetis_port.h
rename to arch/arm/src/kinetis/chip/kinetis_port.h
index 5a568537b01ed8845c61eaa891734226a191ca2d..36dfa4e0983aed0df88034a7acebace36d123ad2 100644
--- a/arch/arm/src/kinetis/kinetis_port.h
+++ b/arch/arm/src/kinetis/chip/kinetis_port.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_port.h
+ * arch/arm/src/kinetis/chip/kinetis_port.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_PORT_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_PORT_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PORT_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PORT_H
/************************************************************************************
* Included Files
@@ -426,4 +426,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_PORT_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_PORT_H */
diff --git a/arch/arm/src/kinetis/kinetis_rngb.h b/arch/arm/src/kinetis/chip/kinetis_rngb.h
similarity index 97%
rename from arch/arm/src/kinetis/kinetis_rngb.h
rename to arch/arm/src/kinetis/chip/kinetis_rngb.h
index a4f677555030cd5be5f25fd5898407986aeeb40e..1e005c08ae30a1b2a95b7991a7b42bf38ff1da8a 100644
--- a/arch/arm/src/kinetis/kinetis_rngb.h
+++ b/arch/arm/src/kinetis/chip/kinetis_rngb.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_rngb.h
+ * arch/arm/src/kinetis/chip/kinetis_rngb.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_RNGB_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_RNGB_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_RNGB_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_RNGB_H
/************************************************************************************
* Included Files
@@ -158,4 +158,4 @@
************************************************************************************/
#endif /* KINETIS_NRNG && KINETIS_NRNG > 0 */
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_RNGB_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_RNGB_H */
diff --git a/arch/arm/src/kinetis/kinetis_rtc.h b/arch/arm/src/kinetis/chip/kinetis_rtc.h
similarity index 95%
rename from arch/arm/src/kinetis/kinetis_rtc.h
rename to arch/arm/src/kinetis/chip/kinetis_rtc.h
index 69c097a7c950627992f577b40e61cede1480ccf4..d00c02a6974d9ecd76e138a23677aaad98fd3f0c 100644
--- a/arch/arm/src/kinetis/kinetis_rtc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_rtc.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_rtc.h
+ * arch/arm/src/kinetis/chip/kinetis_rtc.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_RTC_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_RTC_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_RTC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_RTC_H
/************************************************************************************
* Included Files
@@ -59,7 +59,7 @@
#define KINETIS_RTC_CR_OFFSET 0x0010 /* RTC Control Register */
#define KINETIS_RTC_SR_OFFSET 0x0014 /* RTC Status Register */
#define KINETIS_RTC_LR_OFFSET 0x0018 /* RTC Lock Register */
-#ifdef KINETIS_K40
+#if defined(KINETIS_K40) || defined(KINETIS_K64)
# define KINETIS_RTC_IER_OFFSET 0x001c /* RTC Interrupt Enable Register (K40) */
#endif
#ifdef KINETIS_K60
@@ -77,7 +77,7 @@
#define KINETIS_RTC_CR (KINETIS_RTC_BASE+KINETIS_RTC_CR_OFFSET)
#define KINETIS_RTC_SR (KINETIS_RTC_BASE+KINETIS_RTC_SR_OFFSET)
#define KINETIS_RTC_LR (KINETIS_RTC_BASE+KINETIS_RTC_LR_OFFSET)
-#ifdef KINETIS_K40
+#if defined(KINETIS_K40) || defined(KINETIS_K64)
# define KINETIS_RTC_IER (KINETIS_RTC_BASE+KINETIS_RTC_IER_OFFSET)
#endif
#ifdef KINETIS_K60
@@ -141,7 +141,7 @@
/* Bits 7-31: Reserved */
/* RTC Interrupt Enable Register (32-bits, K40) */
-#ifdef KINETIS_K40
+#if defined(KINETIS_K40) || defined(KINETIS_K64)
# define RTC_IER_TIIE (1 << 0) /* Bit 0: Time Invalid Interrupt Enable */
# define RTC_IER_TOIE (1 << 1) /* Bit 1: Time Overflow Interrupt Enable */
# define RTC_IER_TAIE (1 << 2) /* Bit 2: Time Alarm Interrupt Enable */
@@ -167,7 +167,7 @@
#define RTC_WAR_CRW (1 << 4) /* Bit 4: Control Register Write */
#define RTC_WAR_SRW (1 << 5) /* Bit 5: Status Register Write */
#define RTC_WAR_LRW (1 << 6) /* Bit 6: Lock Register Write */
-#ifdef KINETIS_K40
+#if defined(KINETIS_K40) || defined(KINETIS_K64)
# define RTC_WAR_IERW (1 << 7) /* Bit 7: Interrupt Enable Register Write */
#endif
#ifdef KINETIS_K60
@@ -183,7 +183,7 @@
#define RTC_RAR_CRR (1 << 4) /* Bit 4: Control Register Read */
#define RTC_RAR_SRR (1 << 5) /* Bit 5: Status Register Read */
#define RTC_RAR_LRR (1 << 6) /* Bit 6: Lock Register Read */
-#ifdef KINETIS_K40
+#if defined(KINETIS_K40) || defined(KINETIS_K64)
# define RTC_RAR_IERR (1 << 7) /* Bit 7: Interrupt Enable Register Read */
#endif
#ifdef KINETIS_K60
@@ -204,4 +204,4 @@
************************************************************************************/
#endif /* KINETIS_NRTC && KINETIS_NRTC > 0 */
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_RTC_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_RTC_H */
diff --git a/arch/arm/src/kinetis/kinetis_sdhc.h b/arch/arm/src/kinetis/chip/kinetis_sdhc.h
similarity index 99%
rename from arch/arm/src/kinetis/kinetis_sdhc.h
rename to arch/arm/src/kinetis/chip/kinetis_sdhc.h
index 5d122315a9d2efa426865fd396748ac3e0372434..b57b85c94e70e83d72f12e2e6101ca42c3c83c35 100644
--- a/arch/arm/src/kinetis/kinetis_sdhc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_sdhc.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_sdhc.h
+ * arch/arm/src/kinetis/chip/kinetis_sdhc.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_SDHC_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_SDHC_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SDHC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SDHC_H
/************************************************************************************
* Included Files
@@ -385,4 +385,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_SDHC_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SDHC_H */
diff --git a/arch/arm/src/kinetis/kinetis_sim.h b/arch/arm/src/kinetis/chip/kinetis_sim.h
similarity index 95%
rename from arch/arm/src/kinetis/kinetis_sim.h
rename to arch/arm/src/kinetis/chip/kinetis_sim.h
index aad17e923e80c2bc7513fba4ff707c3825e2d5a3..ae56504ff085ac1be8929e0275125f04b19a29c4 100644
--- a/arch/arm/src/kinetis/kinetis_sim.h
+++ b/arch/arm/src/kinetis/chip/kinetis_sim.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_sim.h
+ * arch/arm/src/kinetis/chip/kinetis_sim.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_SIM_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_SIM_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SIM_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SIM_H
/************************************************************************************
* Included Files
@@ -207,7 +207,7 @@
/* Bits 0-23: Reserved */
#define SIM_SOPT6_RSTFLTSEL_SHIFT (24) /* Bits 24-28: Reset pin filter select */
#define SIM_SOPT6_RSTFLTSEL_MASK (31 << SIM_SOPT6_RSTFLTSEL_SHIFT)
-# define SIM_SOPT6_RSTFLTSEL(n) (((n)-1) << SIM_SOPT6_RSTFLTSEL_SHIFT) /* Bux clock filter count n, n=1..32 */
+# define SIM_SOPT6_RSTFLTSEL(n) ((uint32_t)((n)-1) << SIM_SOPT6_RSTFLTSEL_SHIFT) /* n=1..32 */
#define SIM_SOPT6_RSTFLTEN_SHIFT (29) /* Bits 29-31: Reset pin filter enable */
#define SIM_SOPT6_RSTFLTEN_MASK (7 << SIM_SOPT6_RSTFLTEN_SHIFT)
#define SIM_SOPT6_RSTFLTEN_DISABLED (0 << SIM_SOPT6_RSTFLTEN_SHIFT) /* All filtering disabled */
@@ -385,7 +385,7 @@
/* Bits 0-15: Reserved */
#define SIM_CLKDIV1_OUTDIV4_SHIFT (16) /* Bits 16-19: Clock 4 output divider value */
#define SIM_CLKDIV1_OUTDIV4_MASK (15 << SIM_CLKDIV1_OUTDIV4_SHIFT)
-# define SIM_CLKDIV1_OUTDIV4(n) (((n)-1) << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by n, n=1..16 */
+# define SIM_CLKDIV1_OUTDIV4(n) ((uint32_t)((n)-1) << SIM_CLKDIV1_OUTDIV4_SHIFT) /* n=1..16 */
# define SIM_CLKDIV1_OUTDIV4_1 (0 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 1 */
# define SIM_CLKDIV1_OUTDIV4_2 (1 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 2 */
# define SIM_CLKDIV1_OUTDIV4_3 (2 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 3 */
@@ -404,7 +404,7 @@
# define SIM_CLKDIV1_OUTDIV4_16 (15 << SIM_CLKDIV1_OUTDIV4_SHIFT) /* Divide by 16 */
#define SIM_CLKDIV1_OUTDIV3_SHIFT (20) /* Bits 20-23: Clock 3 output divider value */
#define SIM_CLKDIV1_OUTDIV3_MASK (15 << SIM_CLKDIV1_OUTDIV3_SHIFT)
-# define SIM_CLKDIV1_OUTDIV3(n) (((n)-1) << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by n, n=1..16 */
+# define SIM_CLKDIV1_OUTDIV3(n) ((uint32_t)((n)-1) << SIM_CLKDIV1_OUTDIV3_SHIFT) /* n=1..16 */
# define SIM_CLKDIV1_OUTDIV3_1 (0 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 1 */
# define SIM_CLKDIV1_OUTDIV3_2 (1 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 2 */
# define SIM_CLKDIV1_OUTDIV3_3 (2 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 3 */
@@ -423,7 +423,7 @@
# define SIM_CLKDIV1_OUTDIV3_16 (15 << SIM_CLKDIV1_OUTDIV3_SHIFT) /* Divide by 16 */
#define SIM_CLKDIV1_OUTDIV2_SHIFT (24) /* Bits 24-27: Clock 2 output divider value */
#define SIM_CLKDIV1_OUTDIV2_MASK (15 << SIM_CLKDIV1_OUTDIV2_SHIFT)
-# define SIM_CLKDIV1_OUTDIV2(n) (((n)-1) << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by n, n=1..16 */
+# define SIM_CLKDIV1_OUTDIV2(n) ((uint32_t)((n)-1) << SIM_CLKDIV1_OUTDIV2_SHIFT) /* n=1..16 */
# define SIM_CLKDIV1_OUTDIV2_1 (0 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 1 */
# define SIM_CLKDIV1_OUTDIV2_2 (1 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 2 */
# define SIM_CLKDIV1_OUTDIV2_3 (2 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 3 */
@@ -442,7 +442,7 @@
# define SIM_CLKDIV1_OUTDIV2_16 (15 << SIM_CLKDIV1_OUTDIV2_SHIFT) /* Divide by 16 */
#define SIM_CLKDIV1_OUTDIV1_SHIFT (28) /* Bits 28-31: Clock 1 output divider value */
#define SIM_CLKDIV1_OUTDIV1_MASK (15 << SIM_CLKDIV1_OUTDIV1_SHIFT)
-# define SIM_CLKDIV1_OUTDIV1(n) (((n)-1) << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by n, n=1..16 */
+# define SIM_CLKDIV1_OUTDIV1(n) ((uint32_t)((n)-1) << SIM_CLKDIV1_OUTDIV1_SHIFT) /* n=1..16 */
# define SIM_CLKDIV1_OUTDIV1_1 (0 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 1 */
# define SIM_CLKDIV1_OUTDIV1_2 (1 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 2 */
# define SIM_CLKDIV1_OUTDIV1_3 (2 << SIM_CLKDIV1_OUTDIV1_SHIFT) /* Divide by 3 */
@@ -489,29 +489,29 @@
# define SIM_FCFG1_EESIZE_32B (9 << SIM_FCFG1_EESIZE_SHIFT) /* 32 Bytes */
# define SIM_FCFG1_EESIZE_NONE (15 << SIM_FCFG1_EESIZE_SHIFT) /* 0 Bytes */
/* Bits 20-23: Reserved */
-#ifdef KINETIS_K40
-#define SIM_FCFG1_PFSIZE_SHIFT (24) /* Bits 24-27: Program flash size (K40) */
-#define SIM_FCFG1_PFSIZE_MASK (15 << SIM_FCFG1_PFSIZE_SHIFT)
-# define SIM_FCFG1_PFSIZE_128KB (7 << SIM_FCFG1_PFSIZE_SHIFT) /* 128KB program flash, 4KB protection region */
-# define SIM_FCFG1_PFSIZE_256KB (9 << SIM_FCFG1_PFSIZE_SHIFT) /* 256KB program flash, 8KB protection region */
-# define SIM_FCFG1_PFSIZE_512KB (11 << SIM_FCFG1_PFSIZE_SHIFT) /* 512KB program flash, 16KB protection region */
-# define SIM_FCFG1_PFSIZE_512KB2 (15 << SIM_FCFG1_PFSIZE_SHIFT) /* 512KB program flash, 16KB protection region */
-#define SIM_FCFG1_NVMSIZE_SHIFT (28) /* Bits 28-31: FlexNVM size (K40)*/
-#define SIM_FCFG1_NVMSIZE_MASK (15 << SIM_FCFG1_NVMSIZE_SHIFT)
-# define SIM_FCFG1_NVMSIZE_NONE (0 << SIM_FCFG1_NVMSIZE_SHIFT) /* 0KB FlexNVM */
-# define SIM_FCFG1_NVMSIZE_128KB (7 << SIM_FCFG1_NVMSIZE_SHIFT) /* 128KB FlexNVM, 16KB protection region */
-# define SIM_FCFG1_NVMSIZE_256KB (9 << SIM_FCFG1_NVMSIZE_SHIFT) /* 256KB FlexNVM, 32KB protection region */
-# define SIM_FCFG1_NVMSIZE_256KB2 (15 << SIM_FCFG1_NVMSIZE_SHIFT) /* 256KB FlexNVM, 32KB protection region */
+#if defined(KINETIS_K40) || defined(KINETIS_K64)
+# define SIM_FCFG1_PFSIZE_SHIFT (24) /* Bits 24-27: Program flash size (K40) */
+# define SIM_FCFG1_PFSIZE_MASK (15 << SIM_FCFG1_PFSIZE_SHIFT)
+# define SIM_FCFG1_PFSIZE_128KB (7 << SIM_FCFG1_PFSIZE_SHIFT) /* 128KB program flash, 4KB protection region */
+# define SIM_FCFG1_PFSIZE_256KB (9 << SIM_FCFG1_PFSIZE_SHIFT) /* 256KB program flash, 8KB protection region */
+# define SIM_FCFG1_PFSIZE_512KB (11 << SIM_FCFG1_PFSIZE_SHIFT) /* 512KB program flash, 16KB protection region */
+# define SIM_FCFG1_PFSIZE_512KB2 (15 << SIM_FCFG1_PFSIZE_SHIFT) /* 512KB program flash, 16KB protection region */
+# define SIM_FCFG1_NVMSIZE_SHIFT (28) /* Bits 28-31: FlexNVM size (K40)*/
+# define SIM_FCFG1_NVMSIZE_MASK (15 << SIM_FCFG1_NVMSIZE_SHIFT)
+# define SIM_FCFG1_NVMSIZE_NONE (0 << SIM_FCFG1_NVMSIZE_SHIFT) /* 0KB FlexNVM */
+# define SIM_FCFG1_NVMSIZE_128KB (7 << SIM_FCFG1_NVMSIZE_SHIFT) /* 128KB FlexNVM, 16KB protection region */
+# define SIM_FCFG1_NVMSIZE_256KB (9 << SIM_FCFG1_NVMSIZE_SHIFT) /* 256KB FlexNVM, 32KB protection region */
+# define SIM_FCFG1_NVMSIZE_256KB2 (15 << SIM_FCFG1_NVMSIZE_SHIFT) /* 256KB FlexNVM, 32KB protection region */
#endif
#ifdef KINETIS_K60
-#define SIM_FCFG1_FSIZE_SHIFT (24) /* Bits 24-31: Flash size (K60)*/
-#define SIM_FCFG1_FSIZE_MASK (0xff << SIM_FCFG1_FSIZE_SHIFT)
-# define SIM_FCFG1_FSIZE_32KB (2 << SIM_FCFG1_FSIZE_SHIFT) /* 32KB program flash, 1KB protection region */
-# define SIM_FCFG1_FSIZE_64KB (4 << SIM_FCFG1_FSIZE_SHIFT) /* 64KB program flash, 2KB protection region */
-# define SIM_FCFG1_FSIZE_128KB (6 << SIM_FCFG1_FSIZE_SHIFT) /* 128KB program flash, 4KB protection region */
-# define SIM_FCFG1_FSIZE_256KB (8 << SIM_FCFG1_FSIZE_SHIFT) /* 256KB program flash, 8KB protection region */
-# define SIM_FCFG1_FSIZE_512KB (12 << SIM_FCFG1_FSIZE_SHIFT) /* 512KB program flash, 16KB protection region */
+# define SIM_FCFG1_FSIZE_SHIFT (24) /* Bits 24-31: Flash size (K60)*/
+# define SIM_FCFG1_FSIZE_MASK (0xff << SIM_FCFG1_FSIZE_SHIFT)
+# define SIM_FCFG1_FSIZE_32KB (2 << SIM_FCFG1_FSIZE_SHIFT) /* 32KB program flash, 1KB protection region */
+# define SIM_FCFG1_FSIZE_64KB (4 << SIM_FCFG1_FSIZE_SHIFT) /* 64KB program flash, 2KB protection region */
+# define SIM_FCFG1_FSIZE_128KB (6 << SIM_FCFG1_FSIZE_SHIFT) /* 128KB program flash, 4KB protection region */
+# define SIM_FCFG1_FSIZE_256KB (8 << SIM_FCFG1_FSIZE_SHIFT) /* 256KB program flash, 8KB protection region */
+# define SIM_FCFG1_FSIZE_512KB (12 << SIM_FCFG1_FSIZE_SHIFT) /* 512KB program flash, 16KB protection region */
#endif
/* Flash Configuration Register 2 */
@@ -542,4 +542,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_SIM_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SIM_H */
diff --git a/arch/arm/src/kinetis/kinetis_slcd.h b/arch/arm/src/kinetis/chip/kinetis_slcd.h
similarity index 99%
rename from arch/arm/src/kinetis/kinetis_slcd.h
rename to arch/arm/src/kinetis/chip/kinetis_slcd.h
index d56ee5c41eac0e547aeb67874a94d8b76bf95d34..d4a68f07f5a977efaa980bde2dfd00e3edd72b7c 100644
--- a/arch/arm/src/kinetis/kinetis_slcd.h
+++ b/arch/arm/src/kinetis/chip/kinetis_slcd.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_slcd.h
+ * arch/arm/src/kinetis/chip/kinetis_slcd.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_SLCD_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_SLCD_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SLCD_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SLCD_H
/************************************************************************************
* Included Files
@@ -417,4 +417,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_SLCD_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SLCD_H */
diff --git a/arch/arm/src/kinetis/kinetis_smc.h b/arch/arm/src/kinetis/chip/kinetis_smc.h
similarity index 96%
rename from arch/arm/src/kinetis/kinetis_smc.h
rename to arch/arm/src/kinetis/chip/kinetis_smc.h
index 213ea80775972d3f6537b77ec3b36e492b1a0e2d..19a9d9d14b81dbe4c45ce8188adf3bc19c3d4ea1 100644
--- a/arch/arm/src/kinetis/kinetis_smc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_smc.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_smc.h
+ * arch/arm/src/kinetis/chip/kinetis_smc.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_SMC_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_SMC_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SMC_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SMC_H
/************************************************************************************
* Included Files
@@ -119,4 +119,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_SMC_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_SMC_H */
diff --git a/arch/arm/src/kinetis/kinetis_tsi.h b/arch/arm/src/kinetis/chip/kinetis_tsi.h
similarity index 98%
rename from arch/arm/src/kinetis/kinetis_tsi.h
rename to arch/arm/src/kinetis/chip/kinetis_tsi.h
index ea52c0fd1db765848316645b2d9a5b9be5c1e56d..6881150160fe0ef2e41ae4b47b7942dfa3f5937b 100644
--- a/arch/arm/src/kinetis/kinetis_tsi.h
+++ b/arch/arm/src/kinetis/chip/kinetis_tsi.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_tsi.h
+ * arch/arm/src/kinetis/chip/kinetis_tsi.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_TSI_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_TSI_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_TSI_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_TSI_H
/************************************************************************************
* Included Files
@@ -308,4 +308,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_TSI_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_TSI_H */
diff --git a/arch/arm/src/kinetis/kinetis_uart.h b/arch/arm/src/kinetis/chip/kinetis_uart.h
similarity index 99%
rename from arch/arm/src/kinetis/kinetis_uart.h
rename to arch/arm/src/kinetis/chip/kinetis_uart.h
index fbdf7a3192a86cb4536100ef092b38beed3256a8..537332ee78644febc3f678add0b43675fffa0b85 100644
--- a/arch/arm/src/kinetis/kinetis_uart.h
+++ b/arch/arm/src/kinetis/chip/kinetis_uart.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_uart.h
+ * arch/arm/src/kinetis/chip/kinetis_uart.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_UART_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_UART_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_UART_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_UART_H
/************************************************************************************
* Included Files
@@ -42,7 +42,7 @@
#include
-#include "kinetis_memorymap.h"
+#include "chip/kinetis_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -508,4 +508,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_UART_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_UART_H */
diff --git a/arch/arm/src/kinetis/kinetis_usbdcd.h b/arch/arm/src/kinetis/chip/kinetis_usbdcd.h
similarity index 87%
rename from arch/arm/src/kinetis/kinetis_usbdcd.h
rename to arch/arm/src/kinetis/chip/kinetis_usbdcd.h
index fad76d1500e8771666c3dc123a676dd905d72712..6c4297ff7afec566aa555d6dcc8c875db18bedbe 100644
--- a/arch/arm/src/kinetis/kinetis_usbdcd.h
+++ b/arch/arm/src/kinetis/chip/kinetis_usbdcd.h
@@ -1,7 +1,7 @@
/************************************************************************************
- * arch/arm/src/kinetis/kinetis_usbdcd.h
+ * arch/arm/src/kinetis/chip/kinetis_usbdcd.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_USBDCD_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_USBDCD_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_USBDCD_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_USBDCD_H
/************************************************************************************
* Included Files
@@ -50,12 +50,17 @@
/* Register Offsets *****************************************************************/
-#define KINETIS_USBDCD_CONTROL_OFFSET 0x0000 /* Control Register */
-#define KINETIS_USBDCD_CLOCK_OFFSET 0x0004 /* Clock Register */
-#define KINETIS_USBDCD_STATUS_OFFSET 0x0008 /* Status Register */
-#define KINETIS_USBDCD_TIMER0_OFFSET 0x0010 /* TIMER0 Register */
-#define KINETIS_USBDCD_TIMER1_OFFSET 0x0014 /* TIMER1 Register */
-#define KINETIS_USBDCD_TIMER2_OFFSET 0x0018 /* TIMER2 Register */
+#define KINETIS_USBDCD_CONTROL_OFFSET 0x0000 /* Control Register */
+#define KINETIS_USBDCD_CLOCK_OFFSET 0x0004 /* Clock Register */
+#define KINETIS_USBDCD_STATUS_OFFSET 0x0008 /* Status Register */
+#define KINETIS_USBDCD_TIMER0_OFFSET 0x0010 /* TIMER0 Register */
+#define KINETIS_USBDCD_TIMER1_OFFSET 0x0014 /* TIMER1 Register */
+#ifdef KINETIS_K64
+# define KINETIS_USBDCD_TIMER2_BC11_OFFSET 0x0018 /* TIMER2_BC11 Register */
+# define KINETIS_USBDCD_TIMER2_BC12_OFFSET 0x001c /* TIMER2_BC12 Register */
+#else
+# define KINETIS_USBDCD_TIMER2_OFFSET 0x0018 /* TIMER2 Register */
+#endif
/* Register Addresses ***************************************************************/
@@ -64,7 +69,12 @@
#define KINETIS_USBDCD_STATUS (KINETIS_USBDCD_BASE+KINETIS_USBDCD_STATUS_OFFSET)
#define KINETIS_USBDCD_TIMER0 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER0_OFFSET)
#define KINETIS_USBDCD_TIMER1 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER1_OFFSET)
-#define KINETIS_USBDCD_TIMER2 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER2_OFFSET)
+#ifdef KINETIS_K64
+# define KINETIS_USBDCD_TIMER2_BC11 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER2_BC11_OFFSET)
+# define KINETIS_USBDCD_TIMER2_BC12 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER2_BC12_OFFSET)
+#else
+# define KINETIS_USBDCD_TIMER2 (KINETIS_USBDCD_BASE+KINETIS_USBDCD_TIMER2_OFFSET)
+#endif
/* Register Bit Definitions *********************************************************/
@@ -138,4 +148,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_USBDCD_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_USBDCD_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_usbotg.h b/arch/arm/src/kinetis/chip/kinetis_usbotg.h
new file mode 100644
index 0000000000000000000000000000000000000000..16cecc22610fb3c0a9a75adbf2c89d7bbe6f25f6
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_usbotg.h
@@ -0,0 +1,377 @@
+/********************************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_usbotg.h
+ *
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_USBOTG_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_USBOTG_H
+
+/********************************************************************************************
+ * Included Files
+ ********************************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/********************************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************************/
+
+/* Register Offsets *************************************************************************/
+
+#define KINETIS_USB_PERID_OFFSET 0x0000 /* Peripheral ID Register */
+#define KINETIS_USB_IDCOMP_OFFSET 0x0004 /* Peripheral ID Complement Register */
+#define KINETIS_USB_REV_OFFSET 0x0008 /* Peripheral Revision Register */
+#define KINETIS_USB_ADDINFO_OFFSET 0x000c /* Peripheral Additional Info Register */
+#define KINETIS_USB_OTGISTAT_OFFSET 0x0010 /* OTG Interrupt Status Register */
+#define KINETIS_USB_OTGICR_OFFSET 0x0014 /* OTG Interrupt Control Register */
+#define KINETIS_USB_OTGSTAT_OFFSET 0x0018 /* OTG Status Register */
+#define KINETIS_USB_OTGCTL_OFFSET 0x001c /* OTG Control Register */
+#define KINETIS_USB_ISTAT_OFFSET 0x0080 /* Interrupt Status Register */
+#define KINETIS_USB_INTEN_OFFSET 0x0084 /* Interrupt Enable Register */
+#define KINETIS_USB_ERRSTAT_OFFSET 0x0088 /* Error Interrupt Status Register */
+#define KINETIS_USB_ERREN_OFFSET 0x008c /* Error Interrupt Enable Register */
+#define KINETIS_USB_STAT_OFFSET 0x0090 /* Status Register */
+#define KINETIS_USB_CTL_OFFSET 0x0094 /* Control Register */
+#define KINETIS_USB_ADDR_OFFSET 0x0098 /* Address Register */
+#define KINETIS_USB_BDTPAGE1_OFFSET 0x009c /* BDT Page Register 1 */
+#define KINETIS_USB_FRMNUML_OFFSET 0x00a0 /* Frame Number Register Low */
+#define KINETIS_USB_FRMNUMH_OFFSET 0x00a4 /* Frame Number Register High */
+#define KINETIS_USB_TOKEN_OFFSET 0x00a8 /* Token Register */
+#define KINETIS_USB_SOFTHLD_OFFSET 0x00ac /* SOF Threshold Register */
+#define KINETIS_USB_BDTPAGE2_OFFSET 0x00b0 /* BDT Page Register 2 */
+#define KINETIS_USB_BDTPAGE3_OFFSET 0x00b4 /* BDT Page Register 3 */
+
+#define KINETIS_USB_ENDPT_OFFSET(n) (0x00c0+((n)<<2)) /* Endpoint n Control Register */
+#define KINETIS_USB_ENDPT0_OFFSET 0x00c0 /* Endpoint 0 Control Register */
+#define KINETIS_USB_ENDPT1_OFFSET 0x00c4 /* Endpoint 1 Control Register */
+#define KINETIS_USB_ENDPT2_OFFSET 0x00c8 /* Endpoint 2 Control Register */
+#define KINETIS_USB_ENDPT3_OFFSET 0x00cc /* Endpoint 3 Control Register */
+#define KINETIS_USB_ENDPT4_OFFSET 0x00d0 /* Endpoint 4 Control Register */
+#define KINETIS_USB_ENDPT5_OFFSET 0x00d4 /* Endpoint 5 Control Register */
+#define KINETIS_USB_ENDPT6_OFFSET 0x00d8 /* Endpoint 6 Control Register */
+#define KINETIS_USB_ENDPT7_OFFSET 0x00dc /* Endpoint 7 Control Register */
+#define KINETIS_USB_ENDPT8_OFFSET 0x00e0 /* Endpoint 8 Control Register */
+#define KINETIS_USB_ENDPT9_OFFSET 0x00e4 /* Endpoint 9 Control Register */
+#define KINETIS_USB_ENDPT10_OFFSET 0x00e8 /* Endpoint 10 Control Register */
+#define KINETIS_USB_ENDPT11_OFFSET 0x00ec /* Endpoint 11 Control Register */
+#define KINETIS_USB_ENDPT12_OFFSET 0x00f0 /* Endpoint 12 Control Register */
+#define KINETIS_USB_ENDPT13_OFFSET 0x00f4 /* Endpoint 13 Control Register */
+#define KINETIS_USB_ENDPT14_OFFSET 0x00f8 /* Endpoint 14 Control Register */
+#define KINETIS_USB_ENDPT15_OFFSET 0x00fc /* Endpoint 15 Control Register */
+
+#define KINETIS_USB_USBCTRL_OFFSET 0x0100 /* USB Control Register */
+#define KINETIS_USB_OBSERVE_OFFSET 0x0104 /* USB OTG Observe Register */
+#define KINETIS_USB_CONTROL_OFFSET 0x0108 /* USB OTG Control Register */
+#define KINETIS_USB_USBTRC0_OFFSET 0x010c /* USB Transceiver Control Register 0 */
+
+#ifdef KINETIS_K64
+# define KINETIS_USB_USBFRMADJUST_OFFSET 0x114 /* Frame Adjust Register */
+# define KINETIS_USB_USB0_CLK_RECOVER_CTRL_OFFSET 0x140 /* USB Clock recovery control */
+# define KINETIS_USB_USB0_CLK_RECOVER_IRC_EN_OFFSET 0x144 /* IRC48M oscillator enable register */
+# define KINETIS_USB_USB0_CLK_RECOVER_INT_STATUS_OFFSET 0x15c /* Clock recovery sperated interrupt status */
+#endif
+
+/* Register Addresses ***********************************************************************/
+
+#define KINETIS_USB0_PERID (KINETIS_USB0_BASE+KINETIS_USB_PERID_OFFSET)
+#define KINETIS_USB0_IDCOMP (KINETIS_USB0_BASE+KINETIS_USB_IDCOMP_OFFSET)
+#define KINETIS_USB0_REV (KINETIS_USB0_BASE+KINETIS_USB_REV_OFFSET)
+#define KINETIS_USB0_ADDINFO (KINETIS_USB0_BASE+KINETIS_USB_ADDINFO_OFFSET)
+#define KINETIS_USB0_OTGISTAT (KINETIS_USB0_BASE+KINETIS_USB_OTGISTAT_OFFSET)
+#define KINETIS_USB0_OTGICR (KINETIS_USB0_BASE+KINETIS_USB_OTGICR_OFFSET)
+#define KINETIS_USB0_OTGSTAT (KINETIS_USB0_BASE+KINETIS_USB_OTGSTAT_OFFSET)
+#define KINETIS_USB0_OTGCTL (KINETIS_USB0_BASE+KINETIS_USB_OTGCTL_OFFSET)
+#define KINETIS_USB0_ISTAT (KINETIS_USB0_BASE+KINETIS_USB_ISTAT_OFFSET)
+#define KINETIS_USB0_INTEN (KINETIS_USB0_BASE+KINETIS_USB_INTEN_OFFSET)
+#define KINETIS_USB0_ERRSTAT (KINETIS_USB0_BASE+KINETIS_USB_ERRSTAT_OFFSET)
+#define KINETIS_USB0_ERREN (KINETIS_USB0_BASE+KINETIS_USB_ERREN_OFFSET)
+#define KINETIS_USB0_STAT (KINETIS_USB0_BASE+KINETIS_USB_STAT_OFFSET)
+#define KINETIS_USB0_CTL (KINETIS_USB0_BASE+KINETIS_USB_CTL_OFFSET)
+#define KINETIS_USB0_ADDR (KINETIS_USB0_BASE+KINETIS_USB_ADDR_OFFSET)
+#define KINETIS_USB0_BDTPAGE1 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE1_OFFSET)
+#define KINETIS_USB0_FRMNUML (KINETIS_USB0_BASE+KINETIS_USB_FRMNUML_OFFSET)
+#define KINETIS_USB0_FRMNUMH (KINETIS_USB0_BASE+KINETIS_USB_FRMNUMH_OFFSET)
+#define KINETIS_USB0_TOKEN (KINETIS_USB0_BASE+KINETIS_USB_TOKEN_OFFSET)
+#define KINETIS_USB0_SOFTHLD (KINETIS_USB0_BASE+KINETIS_USB_SOFTHLD_OFFSET)
+#define KINETIS_USB0_BDTPAGE2 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE2_OFFSET)
+#define KINETIS_USB0_BDTPAGE3 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE3_OFFSET)
+
+#define KINETIS_USB0_ENDPT(n) (KINETIS_USB0_BASE+KINETIS_USB_ENDPT_OFFSET(n))
+#define KINETIS_USB0_ENDPT0 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT0_OFFSET)
+#define KINETIS_USB0_ENDPT1 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT1_OFFSET)
+#define KINETIS_USB0_ENDPT2 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT2_OFFSET)
+#define KINETIS_USB0_ENDPT3 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT3_OFFSET)
+#define KINETIS_USB0_ENDPT4 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT4_OFFSET)
+#define KINETIS_USB0_ENDPT5 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT5_OFFSET)
+#define KINETIS_USB0_ENDPT6 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT6_OFFSET)
+#define KINETIS_USB0_ENDPT7 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT7_OFFSET)
+#define KINETIS_USB0_ENDPT8 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT8_OFFSET)
+#define KINETIS_USB0_ENDPT9 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT9_OFFSET)
+#define KINETIS_USB0_ENDPT10 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT10_OFFSET)
+#define KINETIS_USB0_ENDPT11 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT11_OFFSET)
+#define KINETIS_USB0_ENDPT12 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT12_OFFSET)
+#define KINETIS_USB0_ENDPT13 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT13_OFFSET)
+#define KINETIS_USB0_ENDPT14 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT14_OFFSET)
+#define KINETIS_USB0_ENDPT15 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT15_OFFSET)
+
+#define KINETIS_USB0_USBCTRL (KINETIS_USB0_BASE+KINETIS_USB_USBCTRL_OFFSET)
+#define KINETIS_USB0_OBSERVE (KINETIS_USB0_BASE+KINETIS_USB_OBSERVE_OFFSET)
+#define KINETIS_USB0_CONTROL (KINETIS_USB0_BASE+KINETIS_USB_CONTROL_OFFSET)
+#define KINETIS_USB0_USBTRC0 (KINETIS_USB0_BASE+KINETIS_USB_USBTRC0_OFFSET)
+
+#ifdef KINETIS_K64
+# define KINETIS_USB_USBFRMADJUST \
+ (KINETIS_USB0_BASE+KINETIS_USB_USBFRMADJUST_OFFSET)
+# define KINETIS_USB_USB0_CLK_RECOVER_CTRL \
+ (KINETIS_USB0_BASE+KINETIS_USB_USB0_CLK_RECOVER_CTRL_OFFSET)
+# define KINETIS_USB_USB0_CLK_RECOVER_IRC_EN \
+ (KINETIS_USB0_BASE+KINETIS_USB_USB0_CLK_RECOVER_IRC_EN_OFFSET)
+# define KINETIS_USB_USB0_CLK_RECOVER_INT_STATUS \
+ (KINETIS_USB0_BASE+KINETIS_USB_USB0_CLK_RECOVER_INT_STATUS_OFFSET)
+#endif
+
+/* Register Bit Definitions *****************************************************************/
+
+/* Peripheral ID Register (8-bit) */
+ /* Bits 6-7: Reserved */
+#define USB_PERID_MASK (0x3f) /* Bits 0-5: Peripheral identification bits */
+
+/* Peripheral ID Complement Register (8-bit) */
+#define USB_IDCOMP_
+ /* Bits 6-7: Reserved */
+#define USB_IDCOMP_MASK (0x3f) /* Bits 0-5: Ones complement of peripheral identification bits */
+
+/* Peripheral Revision Register (8-bit revision number) */
+
+/* Peripheral Additional Info Register (8-bit) */
+
+#define USB_ADDINFO_IEHOST (1 << 0) /* Bit 0: This bit is set if host mode is enabled */
+ /* Bits 1-2: Reserved */
+#define USB_ADDINFO_IRQNUM_SHIFT (3) /* Bits 3-7: Assigned Interrupt Request Number */
+#define USB_ADDINFO_IRQNUM_MASK (31 << USB_ADDINFO_IRQNUM_SHIFT)
+
+/* OTG Interrupt Status Register(8-bit) */
+
+#define USB_OTGISTAT_AVBUSCHG (1 << 0) /* Bit 0: Change in VBUS is detected on an A device */
+ /* Bit 1: Reserved */
+#define USB_OTGISTAT_B_SESS_CHG (1 << 2) /* Bit 2: Change in VBUS is detected on a B device */
+#define USB_OTGISTAT_SESSVLDCHG (1 << 3) /* Bit 3: Change in VBUS is detected */
+ /* Bit 4: Reserved */
+#define USB_OTGISTAT_LINE_STATE_CHG (1 << 5) /* Bit 5: Change USB line state */
+#define USB_OTGISTAT_ONEMSEC (1 << 6) /* Bit 6: Set when the 1 millisecond timer expires */
+#define USB_OTGISTAT_IDCHG (1 << 7) /* Bit 7: Change in ID Signal from the USB connector */
+
+/* OTG Interrupt Control Register (8-bit) */
+
+#define USB_OTGICR_AVBUSEN (1 << 0) /* Bit 0: A VBUS Valid interrupt enable */
+ /* Bit 1: Reserved */
+#define USB_OTGICR_BSESSEN (1 << 2) /* Bit 2: B Session END interrupt enable */
+#define USB_OTGICR_SESSVLDEN (1 << 3) /* Bit 3: Session valid interrupt enable */
+ /* Bit 4: Reserved */
+#define USB_OTGICR_LINESTATEEN (1 << 5) /* Bit 5: Line State change interrupt enable */
+#define USB_OTGICR_ONEMSECEN (1 << 6) /* Bit 6: 1 millisecond interrupt enable */
+#define USB_OTGICR_IDEN (1 << 7) /* Bit 7: ID interrupt enable */
+
+/* OTG Status Register (8-bit) */
+
+#define USB_OTGSTAT_AVBUSVLD (1 << 0) /* Bit 0: A VBUS Valid */
+ /* Bit 1: Reserved */
+#define USB_OTGSTAT_BSESSEND (1 << 2) /* Bit 2: B Session END */
+#define USB_OTGSTAT_SESS_VLD (1 << 3) /* Bit 3: Session valid */
+ /* Bit 4: Reserved */
+#define USB_OTGSTAT_LINESTATESTABLE (1 << 5) /* Bit 5: OTGISTAT LINE_STATE_CHG bit stable */
+#define USB_OTGSTAT_ONEMSECEN (1 << 6) /* Bit 6: Reserved for the 1msec count */
+#define USB_OTGSTAT_ID (1 << 7) /* Bit 7: Current state of the ID pin on the USB connector */
+
+/* OTG Control Register (8-bit) */
+ /* Bits 0-1: Reserved */
+#define USB_OTGCTL_OTGEN (1 << 2) /* Bit 2: On-The-Go pullup/pulldown resistor enable */
+ /* Bit 3: Reserved */
+#define USB_OTGCTL_DMLOW (1 << 4) /* Bit 4: D- Data Line pull-down resistor enable */
+#define USB_OTGCTL_DPLOW (1 << 5) /* Bit 5: D+ Data Line pull-down resistor enable */
+ /* Bit 6: Reserved */
+#define USB_OTGCTL_DPHIGH (1 << 7) /* Bit 7: D+ Data Line pullup resistor enable */
+
+/* Interrupt Status Register Interrupt Enable Register (8-bit) */
+
+#define USB_INT_USBRST (1 << 0) /* Bit 0: USB Module has decoded a valid USB reset */
+#define USB_INT_ERROR (1 << 1) /* Bit 1: Any of the error conditions within the ERRSTAT register */
+#define USB_INT_SOFTOK (1 << 2) /* Bit 2: USB Module received a Start Of Frame (SOF) token */
+#define USB_INT_TOKDNE (1 << 3) /* Bit 3: Current token being processed has completed */
+#define USB_INT_SLEEP (1 << 4) /* Bit 4: Constant idle on the USB bus for 3 milliseconds */
+#define USB_INT_RESUME (1 << 5) /* Bit 5: Signal remote wake-up signaling */
+#define USB_INT_ATTACH (1 << 6) /* Bit 6: Attach Interrupt */
+#define USB_INT_STALL (1 << 7) /* Bit 7: Stall Interrupt */
+
+#define USB_INT_ALL 0xFF
+
+/* Error Interrupt Status Register and Error Interrupt Enable Register (8-bit) */
+
+#define USB_ERRSTAT_PIDERR (1 << 0) /* Bit 0: This bit is set when the PID check field fails */
+#define USB_ERRSTAT_CRC5EOF (1 << 1) /* Bit 1: Host data CRC error or End of frame errors */
+#define USB_ERRSTAT_CRC16 (1 << 2) /* Bit 2: Data packet is rejected due to a CRC16 error */
+#define USB_ERRSTAT_DFN8 (1 << 3) /* Bit 3: Data field received was not 8 bits in length */
+#define USB_ERRSTAT_BTOERR (1 << 4) /* Bit 4: Bus turnaround timeout error occurred */
+#define USB_ERRSTAT_DMAERR (1 << 5) /* Bit 5: DMA error */
+ /* Bit 6: Reserved */
+#define USB_ERRSTAT_BTSERR (1 << 7) /* Bit 7: Bit stuff error is detected */
+
+#define USB_EINT_ALL 0xBF
+
+/* Status Register (8-bit) */
+
+ /* Bits 0-1: Reserved */
+#define USB_STAT_ODD (1 << 2) /* Bit 2: Last Buffer Descriptor was in the odd bank of the BDT */
+#define USB_STAT_TX (1 << 3) /* Bit 3: Transmit Indicator */
+#define USB_STAT_ENDP_SHIFT (4) /* Bits 4-7: Endpoint address that received or transmitted the token */
+#define USB_STAT_ENDP_MASK (15 << USB_STAT_ENDP_SHIFT)
+
+/* Control Register (8-bit) */
+
+#define USB_CTL_USBENSOFEN (1 << 0) /* Bit 0: USB Enable */
+#define USB_CTL_ODDRST (1 << 1) /* Bit 1: Resets all the BDT ODD ping/pong bits to 0 */
+#define USB_CTL_RESUME (1 << 2) /* Bit 2: Enables the USB Module to execute resume signaling */
+#define USB_CTL_HOSTMODEEN (1 << 3) /* Bit 3: Enables the USB Module to operate in Host mode */
+#define USB_CTL_RESET (1 << 4) /* Bit 4: Enables the USB Module to generate USB reset signaling */
+#define USB_CTL_TXSUSPENDTOKENBUSY (1 << 5) /* Bit 5: USB Module is busy executing a USB token */
+#define USB_CTL_SE0 (1 << 6) /* Bit 6: Live USB Single Ended Zero signal */
+#define USB_CTL_JSTATE (1 << 7) /* Bit 7: Live USB differential receiver JSTATE signal */
+
+/* Address Register (8-bit) */
+
+#define USB_ADDR_LSEN (1 << 7) /* Bit 7: Low Speed Enable bit */
+#define USB_ADDR_SHIFT (0) /* Bits 0-6: USB address */
+#define USB_ADDR_MASK (0x7f << USB_ADDR_SHIFT)
+
+/* BDT Page Register 1 (8-bit) */
+ /* Bit 0: Reserved */
+#define USB_BDTPAGE1_SHIFT (1) /* Bits 1-7: Address bits 9-15 of the BDT base address */
+#define USB_BDTPAGE1_MASK (0x7f << USB_BDTPAGE1_SHIFT)
+
+/* Frame Number Register Low (8-bit, bits 0-7 of the 11 bit frame number) */
+#define USB_FRMNUML_MASK 0xFF
+/* Frame Number Register High (8-bit) */
+ /* Bits 3-7: Reserved */
+#define USB_FRMNUMH_SHIFT (0) /* Bits 0-2: Bits 8-10 of the 11-bit frame number */
+#define USB_FRMNUMH_MASK (7 << USB_FRMNUMH_SHIFT)
+
+/* Token Register (8-bit) */
+
+#define USB_TOKEN_ENDPT_SHIFT (0) /* Bits 0-3: Endpoint address for the token command */
+#define USB_TOKEN_ENDPT_MASK (15 << USB_TOKEN_ENDPT_SHIFT)
+#define USB_TOKEN_PID_SHIFT (4) /* Bits 4-7: Token type executed by the USB Module */
+#define USB_TOKEN_PID_MASK (15 << USB_TOKEN_PID_SHIFT)
+# define USB_TOKEN_PID_OUT (1 << USB_TOKEN_PID_SHIFT) /* OUT Token */
+# define USB_TOKEN_PID_IN (9 << USB_TOKEN_PID_SHIFT) /* IN Token */
+# define USB_TOKEN_PID_SETUP (13 << USB_TOKEN_PID_SHIFT) /* SETUP Token */
+
+/* SOF Threshold Register (8-bit count value) */
+/* BDT Page Register 2/3 (16 bit address in two 8-bit registers) */
+
+/* Endpoint n Control Register (8-bit) */
+
+#define USB_ENDPT_EPHSHK (1 << 0) /* Bit 0: Enable handshaking during a transaction to the endpoint */
+#define USB_ENDPT_EPSTALL (1 << 1) /* Bit 1: Endpoint is stalled */
+#define USB_ENDPT_EPTXEN (1 << 2) /* Bit 2: Enable the endpoint for TX transfers */
+#define USB_ENDPT_EPRXEN (1 << 3) /* Bit 3: Enable the endpoint for RX transfers */
+#define USB_ENDPT_EPCTLDIS (1 << 4) /* Bit 4: Disable control (SETUP) transfers */
+ /* Bit 5: Reserved */
+#define USB_ENDPT_RETRYDIS (1 << 6) /* Bit 6: Disable host retry NAK'ed transactions (host EP0) */
+#define USB_ENDPT_HOSTWOHUB (1 << 7) /* Bit 7: Allows the host to communicate to a low speed device (host EP0) */
+
+/* USB Control Register (8-bit) */
+ /* Bits 0-5: Reserved */
+#define USB_USBCTRL_PDE (1 << 6) /* Bit 6: Enables the weak pulldowns on the USB transceiver */
+#define USB_USBCTRL_SUSP (1 << 7) /* Bit 7: Places the USB transceiver into the suspend state */
+
+/* USB OTG Observe Register (8-bit) */
+ /* Bits 0-3: Reserved */
+#define USB_OBSERVE_DMPD (1 << 4) /* Bit 4: D- Pull Down signal output from the USB OTG module */
+ /* Bit 5: Reserved */
+#define USB_OBSERVE_DPPD (1 << 6) /* Bit 6: D+ Pull Down signal output from the USB OTG module */
+#define USB_OBSERVE_DPPU (1 << 7) /* Bit 7: D+ Pull Up signal output from the USB OTG module */
+
+/* USB OTG Control Register (8-bit) */
+ /* Bits 0-3: Reserved */
+#define USB_CONTROL_DPPULLUPNONOTG (1 << 4) /* Bit 4: Controls of the DP PULLUP in the USB OTG module */
+ /* Bits 5-7: Reserved */
+/* USB Transceiver Control Register 0 (8-bit) */
+
+#define USB_USBTRC0_USBRESET (1 << 7) /* Bit 7: USB reset */
+ /* Bit 6: Reserved */
+#define USB_USBTRC0_USBRESMEN (1 << 5) /* Bit 5: Asynchronous Resume Interrupt Enable */
+ /* Bits 2-4: Reserved */
+#define USB_USBTRC0_SYNC_DET (1 << 1) /* Bit 1: Synchronous USB Interrupt Detect */
+#define USB_USBTRC0_RESUME_INT (1 << 0) /* Bit 0: USB Asynchronous Interrupt */
+
+/* Buffer Descriptor Table (BDT) ****************************************************/
+/* Offset 0: On write (software->hardware) */
+
+#define USB_BDT_STATUS_MASK 0xfc /* Bits 2-7: Status bits */
+#define USB_BDT_BSTALL (1 << 2) /* Bit 2: Buffer Stall Enable bit */
+#define USB_BDT_DTS (1 << 3) /* Bit 3: Data Toggle Synchronization Enable bit */
+#define USB_BDT_NINC (1 << 4) /* Bit 4: DMA Address Increment Disable bit */
+#define USB_BDT_KEEP (1 << 5) /* Bit 5: BD Keep Enable bit */
+#define USB_BDT_DATA01 (1 << 6) /* Bit 6: Data Toggle Packet bit */
+#define USB_BDT_UOWN (1 << 7) /* Bit 7: USB Own bit */
+#define USB_BDT_BYTECOUNT_SHIFT (16) /* Bits 16-25: Byte Count bits */
+#define USB_BDT_BYTECOUNT_MASK (0x3ff << USB_BDT_BYTECOUNT_SHIFT)
+
+#define USB_BDT_DATA0 0 /* DATA0 packet expected next */
+#define USB_BDT_DATA1 USB_BDT_DATA01 /* DATA1 packet expected next */
+#define USB_BDT_COWN 0 /* CPU owns the descriptor */
+
+/* Offset 0: On read (hardware->software) */
+
+#define USB_BDT_PID_SHIFT (2) /* Bits 2-5: Packet Identifier bits */
+#define USB_BDT_PID_MASK (15 << USB_BDT_PID_SHIFT)
+ /* Bit 7: USB Own bit (same) */
+ /* Bits 16-25: Byte Count bits (same) */
+
+/* Offset 4: BUFFER_ADDRESS, 32-bit Buffer Address bits */
+
+#define USB_BDT_BYTES_SIZE 8 /* Eight bytes per BDT */
+#define USB_BDT_WORD_SIZE 2 /* Two 32-bit words per BDT */
+#define USB_NBDTS_PER_EP 4 /* Number of BDTS per endpoint: IN/OUT and EVEN/ODD */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/********************************************************************************************
+ * Public Functions
+ ********************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_USBOTG_H */
diff --git a/arch/arm/src/kinetis/kinetis_vrefv1.h b/arch/arm/src/kinetis/chip/kinetis_vrefv1.h
similarity index 94%
rename from arch/arm/src/kinetis/kinetis_vrefv1.h
rename to arch/arm/src/kinetis/chip/kinetis_vrefv1.h
index ed9a1ff95c5dc51779b89864f9ac29f5f73f371c..29c871dd22d10fb2066d2ea564a93be9eadc036d 100644
--- a/arch/arm/src/kinetis/kinetis_vrefv1.h
+++ b/arch/arm/src/kinetis/chip/kinetis_vrefv1.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_vrefv1.h
+ * arch/arm/src/kinetis/chip/kinetis_vrefv1.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_VREFV1_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_VREFV1_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_VREFV1_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_VREFV1_H
/********************************************************************************************
* Included Files
@@ -89,4 +89,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_VREFV1_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_VREFV1_H */
diff --git a/arch/arm/src/kinetis/kinetis_wdog.h b/arch/arm/src/kinetis/chip/kinetis_wdog.h
similarity index 95%
rename from arch/arm/src/kinetis/kinetis_wdog.h
rename to arch/arm/src/kinetis/chip/kinetis_wdog.h
index 326c2cf628fe360fc904dc2f51ebe09008fd24ed..6f50386049900167f4930e4ab19dc3775a51e696 100644
--- a/arch/arm/src/kinetis/kinetis_wdog.h
+++ b/arch/arm/src/kinetis/chip/kinetis_wdog.h
@@ -1,7 +1,7 @@
/********************************************************************************************
- * arch/arm/src/kinetis/kinetis_wdog.h
+ * arch/arm/src/kinetis/chip/kinetis_wdog.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_WDOG_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_WDOG_H
+#ifndef __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_WDOG_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_WDOG_H
/********************************************************************************************
* Included Files
@@ -90,7 +90,9 @@
#define WDOG_STCTRLH_DBGEN (1 << 5) /* Bit 5: Enables or disables WDOG in Debug mode */
#define WDOG_STCTRLH_STOPEN (1 << 6) /* Bit 6: Enables or disables WDOG in stop mode */
#define WDOG_STCTRLH_WAITEN (1 << 7) /* Bit 7: Enables or disables WDOG in wait mode */
-#define WDOG_STCTRLH_STNDBYEN (1 << 8) /* Bit 8: Enables or disables WDOG in Standby mode */
+#ifndef KINETIS_K64
+# define WDOG_STCTRLH_STNDBYEN (1 << 8) /* Bit 8: Enables or disables WDOG in Standby mode */
+#endif
/* Bit 9: Reserved */
#define WDOG_STCTRLH_TESTWDOG (1 << 10) /* Bit 10: Selects functional test mode */
#define WDOG_STCTRLH_TESTSEL (1 << 11) /* Bit 11: Selects the test to be run */
@@ -132,4 +134,4 @@
* Public Functions
********************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_WDOG_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_WDOG_H */
diff --git a/arch/arm/src/kinetis/kinetis.h b/arch/arm/src/kinetis/kinetis.h
index ae02ce7e4f81aae52892db227f2874b25d47dd0b..fccd4b90af7bfa964d59d3169636b9d92ba82d05 100644
--- a/arch/arm/src/kinetis/kinetis.h
+++ b/arch/arm/src/kinetis/kinetis.h
@@ -52,7 +52,7 @@
#include "up_internal.h"
#include "kinetis_config.h"
#include "chip.h"
-#include "kinetis_port.h"
+#include "chip/kinetis_port.h"
/************************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/kinetis/kinetis_clockconfig.c b/arch/arm/src/kinetis/kinetis_clockconfig.c
index 7221b9dc6e76416e6edc83b1ef9b1ddac09e7f34..2f703ea96e7fc502409a4b5e1f63c152995f991d 100644
--- a/arch/arm/src/kinetis/kinetis_clockconfig.c
+++ b/arch/arm/src/kinetis/kinetis_clockconfig.c
@@ -44,11 +44,11 @@
#include "up_arch.h"
#include "kinetis.h"
-#include "kinetis_mcg.h"
-#include "kinetis_sim.h"
-#include "kinetis_fmc.h"
-#include "kinetis_llwu.h"
-#include "kinetis_pinmux.h"
+#include "chip/kinetis_mcg.h"
+#include "chip/kinetis_sim.h"
+#include "chip/kinetis_fmc.h"
+#include "chip/kinetis_llwu.h"
+#include "chip/kinetis_pinmux.h"
/****************************************************************************
* Pre-processor Definitions
@@ -373,6 +373,3 @@ kinesis_setdividers(uint32_t div1, uint32_t div2, uint32_t div3, uint32_t div4)
putreg32(regval, KINETIS_FMC_PFAPR);
}
-
-
-
diff --git a/arch/arm/src/kinetis/kinetis_config.h b/arch/arm/src/kinetis/kinetis_config.h
index ce1c6efedf79b6d7348ef4a04fb77b12d3cc1d15..1ce2e7ee5e3e6b80a4a27aec8b5d92e861e44791 100644
--- a/arch/arm/src/kinetis/kinetis_config.h
+++ b/arch/arm/src/kinetis/kinetis_config.h
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H
-#define __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H
+#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_CONFIG_H
+#define __ARCH_ARM_SRC_KINETIS_KINETIS_CONFIG_H
/************************************************************************************
* Included Files
@@ -232,4 +232,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H */
+#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_CONFIG_H */
diff --git a/arch/arm/src/kinetis/kinetis_enet.c b/arch/arm/src/kinetis/kinetis_enet.c
index aa4b3cf10165271bcfb3acb4dd3e1817f8692d4f..6c30bac4158f956c690b4ce0ab62dd69044be41b 100644
--- a/arch/arm/src/kinetis/kinetis_enet.c
+++ b/arch/arm/src/kinetis/kinetis_enet.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * drivers/net/kinetis_enet.c
+ * arch/arm/src/kinetis/kinetis_enet.c
*
* Copyright (C) 2011-2012, 2014-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -57,6 +57,10 @@
#include
#include
+#ifdef CONFIG_NET_NOINTS
+# include
+#endif
+
#ifdef CONFIG_NET_PKT
# include
#endif
@@ -65,10 +69,10 @@
#include "chip.h"
#include "kinetis.h"
#include "kinetis_config.h"
-#include "kinetis_pinmux.h"
-#include "kinetis_sim.h"
-#include "kinetis_mpu.h"
-#include "kinetis_enet.h"
+#include "chip/kinetis_pinmux.h"
+#include "chip/kinetis_sim.h"
+#include "chip/kinetis_mpu.h"
+#include "chip/kinetis_enet.h"
#if defined(KINETIS_NENET) && KINETIS_NENET > 0
@@ -76,29 +80,40 @@
* Pre-processor Definitions
****************************************************************************/
-/* CONFIG_ENET_NETHIFS determines the number of physical interfaces
+/* If processing is not done at the interrupt level, then high priority
+ * work queue support is required.
+ */
+
+#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK)
+# error High priority work queue support is required
+#endif
+
+/* CONFIG_KINETIS_ENETNETHIFS determines the number of physical interfaces
* that will be supported.
*/
-#if CONFIG_ENET_NETHIFS != 1
-# error "CONFIG_ENET_NETHIFS must be one for now"
+#if CONFIG_KINETIS_ENETNETHIFS != 1
+# error "CONFIG_KINETIS_ENETNETHIFS must be one for now"
#endif
-#if CONFIG_ENET_NTXBUFFERS < 1
+#if CONFIG_KINETIS_ENETNTXBUFFERS < 1
# error "Need at least one TX buffer"
#endif
-#if CONFIG_ENET_NRXBUFFERS < 1
+#if CONFIG_KINETIS_ENETNRXBUFFERS < 1
# error "Need at least one RX buffer"
#endif
-#define NENET_NBUFFERS (CONFIG_ENET_NTXBUFFERS+CONFIG_ENET_NRXBUFFERS)
+#define NENET_NBUFFERS \
+ (CONFIG_KINETIS_ENETNTXBUFFERS+CONFIG_KINETIS_ENETNRXBUFFERS)
#ifndef CONFIG_NET_MULTIBUFFER
# error "CONFIG_NET_MULTIBUFFER is required in the configuration"
#endif
-/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */
+/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
+ * second.
+ */
#define KINETIS_WDDELAY (1*CLK_TCK)
@@ -108,14 +123,47 @@
#define MII_MAXPOLLS (0x1ffff)
#define LINK_WAITUS (500*1000)
-/* PHY hardware specifics. This was copied from the FreeScale code examples.
- * this is a vendor specific register and bit settings. I really should
- * do the research and find out what this really is.
+/* PHY definitions.
+ *
+ * The selected PHY must be selected from the drivers/net/Kconfig PHY menu.
+ * A description of the PHY must be provided here. That description must
+ * include:
+ *
+ * 1. BOARD_PHY_NAME: A PHY name string (for debug output),
+ * 2. BOARD_PHYID1 and BOARD_PHYID2: The PHYID1 and PHYID2 values (from
+ * include/nuttx/net/mii.h)
+ * 3. BOARD_PHY_STATUS: The address of the status register to use when
+ * querying link status (from include/nuttx/net/mii.h)
+ * 4. BOARD_PHY_ISDUPLEX: A macro that can convert the status register
+ * value into a boolean: true=duplex mode, false=half-duplex mode
+ * 5. BOARD_PHY_10BASET: A macro that can convert the status register
+ * value into a boolean: true=10Base-T, false=Not 10Base-T
+ * 6. BOARD_PHY_100BASET: A macro that can convert the status register
+ * value into a boolean: true=100Base-T, false=Not 100Base-T
+ *
+ * The Tower SER board uses a KSZ8041 PHY.
+ * The Freedom K64F board uses a KSZ8081 PHY
*/
-#define PHY_STATUS (0x1f)
-#define PHY_DUPLEX_STATUS (4 << 2)
-#define PHY_SPEED_STATUS (1 << 2)
+#if defined(CONFIG_ETH0_PHY_KSZ8041)
+# define BOARD_PHY_NAME "KSZ8041"
+# define BOARD_PHYID1 MII_PHYID1_KSZ8041
+# define BOARD_PHYID2 MII_PHYID2_KSZ8041
+# define BOARD_PHY_STATUS MII_KSZ8041_PHYCTRL2
+# define BOARD_PHY_ISDUPLEX(s) (((s) & (4 << MII_PHYCTRL2_MODE_SHIFT)) != 0)
+# define BOARD_PHY_10BASET(s) (((s) & (1 << MII_PHYCTRL2_MODE_SHIFT)) != 0)
+# define BOARD_PHY_100BASET(s) (((s) & (2 << MII_PHYCTRL2_MODE_SHIFT)) != 0)
+#elif defined(CONFIG_ETH0_PHY_KSZ8081)
+# define BOARD_PHY_NAME "KSZ8081"
+# define BOARD_PHYID1 MII_PHYID1_KSZ8081
+# define BOARD_PHYID2 MII_PHYID2_KSZ8081
+# define BOARD_PHY_STATUS MII_KSZ8081_PHYCTRL2
+# define BOARD_PHY_ISDUPLEX(s) (((s) & (4 << MII_PHYCTRL2_MODE_SHIFT)) != 0)
+# define BOARD_PHY_10BASET(s) (((s) & (1 << MII_PHYCTRL2_MODE_SHIFT)) != 0)
+# define BOARD_PHY_100BASET(s) (((s) & (2 << MII_PHYCTRL2_MODE_SHIFT)) != 0)
+#else
+# error "Unrecognized or missing PHY selection"
+#endif
/* Estimate the hold time to use based on the peripheral (bus) clock:
*
@@ -160,8 +208,12 @@ struct kinetis_driver_s
uint8_t txtail; /* The oldest busy TX descriptor */
uint8_t txhead; /* The next TX descriptor to use */
uint8_t rxtail; /* The next RX descriptor to use */
+ uint8_t phyaddr; /* Selected PHY address */
WDOG_ID txpoll; /* TX poll timer */
WDOG_ID txtimeout; /* TX timeout timer */
+#ifdef CONFIG_NET_NOINTS
+ struct work_s work; /* For deferring work to the work queue */
+#endif
struct enet_desc_s *txdesc; /* A pointer to the list of TX descriptor */
struct enet_desc_s *rxdesc; /* A pointer to the list of RX descriptors */
@@ -188,7 +240,7 @@ struct kinetis_driver_s
* Private Data
****************************************************************************/
-static struct kinetis_driver_s g_enet[CONFIG_ENET_NETHIFS];
+static struct kinetis_driver_s g_enet[CONFIG_KINETIS_ENETNETHIFS];
/****************************************************************************
* Private Function Prototypes
@@ -218,22 +270,43 @@ static int kinetis_txpoll(struct net_driver_s *dev);
static void kinetis_receive(FAR struct kinetis_driver_s *priv);
static void kinetis_txdone(FAR struct kinetis_driver_s *priv);
+
+static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv);
+#ifdef CONFIG_NET_NOINTS
+static void kinetis_interrupt_work(FAR void *arg);
+#endif
static int kinetis_interrupt(int irq, FAR void *context);
/* Watchdog timer expirations */
-static void kinetis_polltimer(int argc, uint32_t arg, ...);
-static void kinetis_txtimeout(int argc, uint32_t arg, ...);
+static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv);
+#ifdef CONFIG_NET_NOINTS
+static void kinetis_txtimeout_work(FAR void *arg);
+#endif
+static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...);
+
+static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv);
+#ifdef CONFIG_NET_NOINTS
+static void kinetis_poll_work(FAR void *arg);
+#endif
+static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...);
/* NuttX callback functions */
static int kinetis_ifup(struct net_driver_s *dev);
static int kinetis_ifdown(struct net_driver_s *dev);
+
+static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv);
+#ifdef CONFIG_NET_NOINTS
+static void kinetis_txavail_work(FAR void *arg);
+#endif
static int kinetis_txavail(struct net_driver_s *dev);
+
#ifdef CONFIG_NET_IGMP
static int kinetis_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
static int kinetis_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
#endif
+
#ifdef CONFIG_NETDEV_PHY_IOCTL
static int kinetis_ioctl(struct net_driver_s *dev, int cmd, long arg);
#endif
@@ -241,7 +314,11 @@ static int kinetis_ioctl(struct net_driver_s *dev, int cmd, long arg);
/* PHY/MII support */
static inline void kinetis_initmii(struct kinetis_driver_s *priv);
-static inline void kinetis_initphy(struct kinetis_driver_s *priv);
+static int kinetis_writemii(struct kinetis_driver_s *priv, uint8_t phyaddr,
+ uint8_t regaddr, uint16_t data);
+static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr,
+ uint8_t regaddr, uint16_t *data);
+static inline int kinetis_initphy(struct kinetis_driver_s *priv);
/* Initialization */
@@ -323,7 +400,7 @@ static bool kinetics_txringfull(FAR struct kinetis_driver_s *priv)
*/
txnext = priv->txhead + 1;
- if (txnext >= CONFIG_ENET_NTXBUFFERS)
+ if (txnext >= CONFIG_KINETIS_ENETNTXBUFFERS)
{
txnext = 0;
}
@@ -375,7 +452,7 @@ static int kinetis_transmit(FAR struct kinetis_driver_s *priv)
txdesc = &priv->txdesc[priv->txhead];
priv->txhead++;
- if (priv->txhead >= CONFIG_ENET_NTXBUFFERS)
+ if (priv->txhead >= CONFIG_KINETIS_ENETNTXBUFFERS)
{
priv->txhead = 0;
}
@@ -392,7 +469,7 @@ static int kinetis_transmit(FAR struct kinetis_driver_s *priv)
*/
txdesc->length = kinesis_swap16(priv->dev.d_len);
-#ifdef CONFIG_ENET_ENHANCEDBD
+#ifdef CONFIG_KINETIS_ENETENHANCEDBD
txdesc->bdu = 0x00000000;
txdesc->status2 = TXDESC_INT | TXDESC_TS; /* | TXDESC_IINS | TXDESC_PINS; */
#endif
@@ -426,8 +503,8 @@ static int kinetis_transmit(FAR struct kinetis_driver_s *priv)
/* Setup the TX timeout watchdog (perhaps restarting the timer) */
- (void)wd_start(priv->txtimeout, KINETIS_TXTIMEOUT, kinetis_txtimeout, 1,
- (uint32_t)priv);
+ (void)wd_start(priv->txtimeout, KINETIS_TXTIMEOUT, kinetis_txtimeout_expiry, 1,
+ (wdparm_t)priv);
return OK;
}
@@ -668,7 +745,7 @@ static void kinetis_receive(FAR struct kinetis_driver_s *priv)
/* Update the index to the next descriptor */
priv->rxtail++;
- if (priv->rxtail >= CONFIG_ENET_NRXBUFFERS)
+ if (priv->rxtail >= CONFIG_KINETIS_ENETNRXBUFFERS)
{
priv->rxtail = 0;
}
@@ -708,7 +785,7 @@ static void kinetis_txdone(FAR struct kinetis_driver_s *priv)
/* Yes.. bump up the tail pointer, making space for a new TX descriptor */
priv->txtail++;
- if (priv->txtail >= CONFIG_ENET_NTXBUFFERS)
+ if (priv->txtail >= CONFIG_KINETIS_ENETNTXBUFFERS)
{
priv->txtail = 0;
}
@@ -739,28 +816,25 @@ static void kinetis_txdone(FAR struct kinetis_driver_s *priv)
}
/****************************************************************************
- * Function: kinetis_interrupt
+ * Function: kinetis_interrupt_process
*
* Description:
- * Three interrupt sources will vector this this function:
- * 1. Ethernet MAC transmit interrupt handler
- * 2. Ethernet MAC receive interrupt handler
- * 3.
+ * Interrupt processing. This may be performed either within the interrupt
+ * handler or on the worker thread, depending upon the configuration
*
* Parameters:
- * irq - Number of the IRQ that generated the interrupt
- * context - Interrupt register state save info (architecture-specific)
+ * priv - Reference to the driver state structure
*
* Returned Value:
- * OK on success
+ * None
*
* Assumptions:
+ * The network is locked.
*
****************************************************************************/
-static int kinetis_interrupt(int irq, FAR void *context)
+static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv)
{
- register FAR struct kinetis_driver_s *priv = &g_enet[0];
uint32_t pending;
/* Get the set of unmasked, pending interrupt. */
@@ -810,33 +884,130 @@ static int kinetis_interrupt(int irq, FAR void *context)
putreg32(ENET_RDAR, KINETIS_ENET_RDAR);
}
-
- return OK;
}
/****************************************************************************
- * Function: kinetis_txtimeout
+ * Function: kinetis_interrupt_work
*
* Description:
- * Our TX watchdog timed out. Called from the timer interrupt handler.
- * The last TX never completed. Reset the hardware and start again.
+ * Perform interrupt related work from the worker thread
*
* Parameters:
- * argc - The number of available arguments
- * arg - The first argument
+ * arg - The argument passed when work_queue() was called.
*
* Returned Value:
- * None
+ * OK on success
*
* Assumptions:
- * Global interrupts are disabled by the watchdog logic.
+ * The network is locked.
*
****************************************************************************/
-static void kinetis_txtimeout(int argc, uint32_t arg, ...)
+#ifdef CONFIG_NET_NOINTS
+static void kinetis_interrupt_work(FAR void *arg)
{
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
+ net_lock_t state;
+
+ /* Process pending Ethernet interrupts */
+
+ state = net_lock();
+ kinetis_interrupt_process(priv);
+ net_unlock(state);
+ /* Re-enable Ethernet interrupts */
+
+#if 0
+ up_enable_irq(KINETIS_IRQ_EMACTMR);
+#endif
+ up_enable_irq(KINETIS_IRQ_EMACTX);
+ up_enable_irq(KINETIS_IRQ_EMACRX);
+ up_enable_irq(KINETIS_IRQ_EMACMISC);
+}
+#endif
+
+/****************************************************************************
+ * Function: kinetis_interrupt
+ *
+ * Description:
+ * Three interrupt sources will vector this this function:
+ * 1. Ethernet MAC transmit interrupt handler
+ * 2. Ethernet MAC receive interrupt handler
+ * 3.
+ *
+ * Parameters:
+ * irq - Number of the IRQ that generated the interrupt
+ * context - Interrupt register state save info (architecture-specific)
+ *
+ * Returned Value:
+ * OK on success
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int kinetis_interrupt(int irq, FAR void *context)
+{
+ register FAR struct kinetis_driver_s *priv = &g_enet[0];
+
+#ifdef CONFIG_NET_NOINTS
+ /* Disable further Ethernet interrupts. Because Ethernet interrupts are
+ * also disabled if the TX timeout event occurs, there can be no race
+ * condition here.
+ */
+
+ up_disable_irq(KINETIS_IRQ_EMACTMR);
+ up_disable_irq(KINETIS_IRQ_EMACTX);
+ up_disable_irq(KINETIS_IRQ_EMACRX);
+ up_disable_irq(KINETIS_IRQ_EMACMISC);
+
+ /* TODO: Determine if a TX transfer just completed */
+
+ {
+ /* If a TX transfer just completed, then cancel the TX timeout so
+ * there will be do race condition between any subsequent timeout
+ * expiration and the deferred interrupt processing.
+ */
+
+ wd_cancel(priv->txtimeout);
+ }
+
+ /* Cancel any pending poll work */
+
+ work_cancel(HPWORK, &priv->work);
+
+ /* Schedule to perform the interrupt processing on the worker thread. */
+
+ work_queue(HPWORK, &priv->work, kinetis_interrupt_work, priv, 0);
+
+#else
+ /* Process the interrupt now */
+
+ kinetis_interrupt_process(priv);
+#endif
+
+ return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_txtimeout_process
+ *
+ * Description:
+ * Process a TX timeout. Called from the either the watchdog timer
+ * expiration logic or from the worker thread, depending upon the
+ * configuration. The timeout means that the last TX never completed.
+ * Reset the hardware and start again.
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv)
+{
/* Increment statistics and dump debug info */
NETDEV_TXTIMEOUTS(&priv->dev);
@@ -854,10 +1025,42 @@ static void kinetis_txtimeout(int argc, uint32_t arg, ...)
}
/****************************************************************************
- * Function: kinetis_polltimer
+ * Function: kinetis_txtimeout_work
*
* Description:
- * Periodic timer handler. Called from the timer interrupt handler.
+ * Perform TX timeout related work from the worker thread
+ *
+ * Parameters:
+ * arg - The argument passed when work_queue() as called.
+ *
+ * Returned Value:
+ * OK on success
+ *
+ * Assumptions:
+ * The network is locked.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_NOINTS
+static void kinetis_txtimeout_work(FAR void *arg)
+{
+ FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
+ net_lock_t state;
+
+ /* Process pending Ethernet interrupts */
+
+ state = net_lock();
+ kinetis_txtimeout_process(priv);
+ net_unlock(state);
+}
+#endif
+
+/****************************************************************************
+ * Function: kinetis_txtimeout_expiry
+ *
+ * Description:
+ * Our TX watchdog timed out. Called from the timer interrupt handler.
+ * The last TX never completed. Reset the hardware and start again.
*
* Parameters:
* argc - The number of available arguments
@@ -871,10 +1074,56 @@ static void kinetis_txtimeout(int argc, uint32_t arg, ...)
*
****************************************************************************/
-static void kinetis_polltimer(int argc, uint32_t arg, ...)
+static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...)
{
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
+#ifdef CONFIG_NET_NOINTS
+ /* Disable further Ethernet interrupts. This will prevent some race
+ * conditions with interrupt work. There is still a potential race
+ * condition with interrupt work that is already queued and in progress.
+ */
+
+ up_disable_irq(KINETIS_IRQ_EMACTMR);
+ up_disable_irq(KINETIS_IRQ_EMACTX);
+ up_disable_irq(KINETIS_IRQ_EMACRX);
+ up_disable_irq(KINETIS_IRQ_EMACMISC);
+
+ /* Cancel any pending poll or interrupt work. This will have no effect
+ * on work that has already been started.
+ */
+
+ work_cancel(HPWORK, &priv->work);
+
+ /* Schedule to perform the TX timeout processing on the worker thread. */
+
+ work_queue(HPWORK, &priv->work, kinetis_txtimeout_work, priv, 0);
+#else
+ /* Process the timeout now */
+
+ kinetis_txtimeout_process(priv);
+#endif
+}
+
+/****************************************************************************
+ * Function: kinetis_poll_process
+ *
+ * Description:
+ * Perform the periodic poll. This may be called either from watchdog
+ * timer logic or from the worker thread, depending upon the configuration.
+ *
+ * Parameters:
+ * priv - Reference to the driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv)
+{
/* Check if there is there is a transmission in progress. We cannot perform
* the TX poll if he are unable to accept another packet for transmission.
*/
@@ -891,7 +1140,89 @@ static void kinetis_polltimer(int argc, uint32_t arg, ...)
/* Setup the watchdog poll timer again in any case */
- (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer, 1, arg);
+ (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
+ 1, (wdparm_t)priv);
+}
+
+/****************************************************************************
+ * Function: kinetis_poll_work
+ *
+ * Description:
+ * Perform periodic polling from the worker thread
+ *
+ * Parameters:
+ * arg - The argument passed when work_queue() as called.
+ *
+ * Returned Value:
+ * OK on success
+ *
+ * Assumptions:
+ * The network is locked.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_NOINTS
+static void kinetis_poll_work(FAR void *arg)
+{
+ FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
+ net_lock_t state;
+
+ /* Perform the poll */
+
+ state = net_lock();
+ kinetis_poll_process(priv);
+ net_unlock(state);
+}
+#endif
+
+/****************************************************************************
+ * Function: kinetis_polltimer_expiry
+ *
+ * Description:
+ * Periodic timer handler. Called from the timer interrupt handler.
+ *
+ * Parameters:
+ * argc - The number of available arguments
+ * arg - The first argument
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...)
+{
+ FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
+
+#ifdef CONFIG_NET_NOINTS
+ /* Is our single work structure available? It may not be if there are
+ * pending interrupt actions.
+ */
+
+ if (work_available(&priv->work))
+ {
+ /* Schedule to perform the interrupt processing on the worker thread. */
+
+ work_queue(HPWORK, &priv->work, kinetis_poll_work, priv, 0);
+ }
+ else
+ {
+ /* No.. Just re-start the watchdog poll timer, missing one polling
+ * cycle.
+ */
+
+ (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
+ 1, (wdparm_t)arg);
+ }
+
+#else
+ /* Process the interrupt now */
+
+ kinetis_poll_process(priv);
+#endif
}
/****************************************************************************
@@ -917,6 +1248,7 @@ static int kinetis_ifup(struct net_driver_s *dev)
(FAR struct kinetis_driver_s *)dev->d_private;
uint8_t *mac = dev->d_mac.ether_addr_octet;
uint32_t regval;
+ int ret;
ninfo("Bringing up: %d.%d.%d.%d\n",
dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
@@ -949,7 +1281,12 @@ static int kinetis_ifup(struct net_driver_s *dev)
/* Configure the PHY */
- kinetis_initphy(priv);
+ ret = kinetis_initphy(priv);
+ if (ret < 0)
+ {
+ nerr("ERROR: Failed to configure the PHY: %d\n", ret);
+ return ret;
+ }
/* Handle promiscuous mode */
@@ -961,7 +1298,7 @@ static int kinetis_ifup(struct net_driver_s *dev)
/* Select legacy of enhanced buffer descriptor format */
-#ifdef CONFIG_ENET_ENHANCEDBD
+#ifdef CONFIG_KINETIS_ENETENHANCEDBD
putreg32(ENET_ECR_EN1588, KINETIS_ENET_ECR);
#else
putreg32(0, KINETIS_ENET_ECR);
@@ -995,8 +1332,8 @@ static int kinetis_ifup(struct net_driver_s *dev)
/* Set and activate a timer process */
- (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer, 1,
- (uint32_t)priv);
+ (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry, 1,
+ (wdparm_t)priv);
/* Clear all pending ENET interrupt */
@@ -1072,15 +1409,13 @@ static int kinetis_ifdown(struct net_driver_s *dev)
}
/****************************************************************************
- * Function: kinetis_txavail
+ * Function: kinetis_txavail_process
*
* Description:
- * Driver callback invoked when new TX data is available. This is a
- * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
- * latency.
+ * Perform an out-of-cycle poll.
*
* Parameters:
- * dev - Reference to the NuttX driver state structure
+ * dev - Reference to the NuttX driver state structure
*
* Returned Value:
* None
@@ -1090,20 +1425,13 @@ static int kinetis_ifdown(struct net_driver_s *dev)
*
****************************************************************************/
-static int kinetis_txavail(struct net_driver_s *dev)
+static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv)
{
- FAR struct kinetis_driver_s *priv =
- (FAR struct kinetis_driver_s *)dev->d_private;
- irqstate_t flags;
-
- /* Disable interrupts because this function may be called from interrupt
- * level processing.
- */
-
- flags = enter_critical_section();
+ net_lock_t state;
/* Ignore the notification if the interface is not yet up */
+ state = net_lock();
if (priv->bifup)
{
/* Check if there is room in the hardware to hold another outgoing
@@ -1120,7 +1448,80 @@ static int kinetis_txavail(struct net_driver_s *dev)
}
}
- leave_critical_section(flags);
+ net_unlock(state);
+}
+
+/****************************************************************************
+ * Function: kinetis_txavail_work
+ *
+ * Description:
+ * Perform an out-of-cycle poll on the worker thread.
+ *
+ * Parameters:
+ * arg - Reference to the NuttX driver state structure (cast to void*)
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Called on the higher priority worker thread.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_NOINTS
+static void kinetis_txavail_work(FAR void *arg)
+{
+ FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
+
+ /* Perform the poll */
+
+ kinetis_txavail_process(priv);
+}
+#endif
+
+/****************************************************************************
+ * Function: kinetis_txavail
+ *
+ * Description:
+ * Driver callback invoked when new TX data is available. This is a
+ * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
+ * latency.
+ *
+ * Parameters:
+ * dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Called in normal user mode
+ *
+ ****************************************************************************/
+
+static int kinetis_txavail(struct net_driver_s *dev)
+{
+ FAR struct kinetis_driver_s *priv =
+ (FAR struct kinetis_driver_s *)dev->d_private;
+
+#ifdef CONFIG_NET_NOINTS
+ /* Is our single work structure available? It may not be if there are
+ * pending interrupt actions and we will have to ignore the Tx
+ * availability action.
+ */
+
+ if (work_available(&priv->work))
+ {
+ /* Schedule to serialize the poll on the worker thread. */
+
+ work_queue(HPWORK, &priv->work, kinetis_txavail_work, priv, 0);
+ }
+
+#else
+ /* Perform the out-of-cycle poll now */
+
+ kinetis_txavail_process(priv);
+#endif
+
return OK;
}
@@ -1216,7 +1617,7 @@ static int kinetis_ioctl(struct net_driver_s *dev, int cmd, long arg)
{
struct mii_ioctl_data_s *req =
(struct mii_ioctl_data_s *)((uintptr_t)arg);
- req->phy_id = CONFIG_ENET_PHYADDR;
+ req->phy_id = priv->phyaddr;
ret = OK;
}
break;
@@ -1381,6 +1782,7 @@ static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr,
if (timeout >= MII_MAXPOLLS)
{
+ nerr("ERROR: Timed out waiting for transfer to complete\n");
return -ETIMEDOUT;
}
@@ -1404,33 +1806,95 @@ static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr,
* priv - Reference to the private ENET driver state structure
*
* Returned Value:
- * None
+ * Zero (OK) returned on success; a negated errno value is returned on any
+ * failure;
*
* Assumptions:
*
****************************************************************************/
-static inline void kinetis_initphy(struct kinetis_driver_s *priv)
+static inline int kinetis_initphy(struct kinetis_driver_s *priv)
{
uint32_t rcr;
uint32_t tcr;
uint16_t phydata;
+ uint8_t phyaddr;
+ int retries;
+ int ret;
/* Loop (potentially infinitely?) until we successfully communicate with
* the PHY.
*/
- do
+ for (phyaddr = 0; phyaddr < 32; phyaddr++)
{
- usleep(LINK_WAITUS);
- phydata = 0xffff;
- kinetis_readmii(priv, CONFIG_ENET_PHYADDR, MII_PHYID1, &phydata);
+ ninfo("%s: Try phyaddr: %u\n", BOARD_PHY_NAME, phyaddr);
+
+ /* Try to read PHYID1 few times using this address */
+
+ retries = 0;
+ do
+ {
+ usleep(LINK_WAITUS);
+ ninfo("%s: Read PHYID1, retries=%d\n", BOARD_PHY_NAME, retries + 1);
+ phydata = 0xffff;
+ ret = kinetis_readmii(priv, phyaddr, MII_PHYID1, &phydata);
+ }
+ while (ret >= 0 && phydata == 0xffff && ++retries < 3);
+
+ /* If we successfully read anything then break out, using this PHY address */
+
+ if (retries < 3)
+ {
+ break;
+ }
+ }
+
+ if (phyaddr >= 32)
+ {
+ nerr("ERROR: Failed to read %s PHYID1 at any address\n");
+ return -ENOENT;
+ }
+
+ ninfo("%s: Using PHY address %u\n", BOARD_PHY_NAME, phyaddr);
+ priv->phyaddr = phyaddr;
+
+ /* Verify PHYID1. Compare OUI bits 3-18 */
+
+ ninfo("%s: PHYID1: %04x\n", BOARD_PHY_NAME, phydata);
+ if (phydata != BOARD_PHYID1)
+ {
+ nerr("ERROR: PHYID1=%04x incorrect for %s. Expected %04x\n",
+ phydata, BOARD_PHY_NAME, BOARD_PHYID1);
+ return -ENXIO;
+ }
+
+ /* Read PHYID2 */
+
+ ret = kinetis_readmii(priv, phyaddr, MII_PHYID2, &phydata);
+ if (ret < 0)
+ {
+ nerr("ERROR: Failed to read %s PHYID2: %d\n", BOARD_PHY_NAME, ret);
+ return ret;
+ }
+
+ ninfo("%s: PHYID2: %04x\n", BOARD_PHY_NAME, phydata);
+
+ /* Verify PHYID2: Compare OUI bits 19-24 and the 6-bit model number
+ * (ignoring the 4-bit revision number).
+ */
+
+ if ((phydata & 0xfff0) != (BOARD_PHYID2 & 0xfff0))
+ {
+ nerr("ERROR: PHYID2=%04x incorrect for %s. Expected %04x\n",
+ (phydata & 0xfff0), BOARD_PHY_NAME, (BOARD_PHYID2 & 0xfff0));
+ return -ENXIO;
}
- while (phydata == 0xffff);
/* Start auto negotiation */
- kinetis_writemii(priv, CONFIG_ENET_PHYADDR, MII_MCR,
+ ninfo("%s: Start autonegotiation...\n", BOARD_PHY_NAME);
+ kinetis_writemii(priv, phyaddr, MII_MCR,
(MII_MCR_ANRESTART | MII_MCR_ANENABLE));
/* Wait (potentially forever) for auto negotiation to complete */
@@ -1438,21 +1902,38 @@ static inline void kinetis_initphy(struct kinetis_driver_s *priv)
do
{
usleep(LINK_WAITUS);
- kinetis_readmii(priv, CONFIG_ENET_PHYADDR, MII_MSR, &phydata);
-
+ ret = kinetis_readmii(priv, phyaddr, MII_MSR, &phydata);
+ if (ret < 0)
+ {
+ nerr("ERROR: Failed to read %s MII_MSR: %d\n",
+ BOARD_PHY_NAME, ret);
+ return ret;
+ }
}
while ((phydata & MII_MSR_ANEGCOMPLETE) == 0);
+ ninfo("%s: Autonegotiation complete\n", BOARD_PHY_NAME);
+ ninfo("%s: MII_MSR: %04x\n", BOARD_PHY_NAME, phydata);
+
/* When we get here we have a link - Find the negotiated speed and duplex. */
phydata = 0;
- kinetis_readmii(priv, CONFIG_ENET_PHYADDR, PHY_STATUS, &phydata);
+ ret = kinetis_readmii(priv, phyaddr, BOARD_PHY_STATUS, &phydata);
+ if (ret < 0)
+ {
+ nerr("ERROR: Failed to read %s BOARD_PHY_STATUS{%02x]: %d\n",
+ BOARD_PHY_NAME, BOARD_PHY_STATUS, ret);
+ return ret;
+ }
+
- /* Set up the transmit and receive contrel registers based on the
+ ninfo("%s: BOARD_PHY_STATUS: %04x\n", BOARD_PHY_NAME, phydata);
+
+ /* Set up the transmit and receive control registers based on the
* configuration and the auto negotiation results.
*/
-#ifdef CONFIG_ENET_USEMII
+#ifdef CONFIG_KINETIS_ENETUSEMII
rcr = ENET_RCR_MII_MODE | ENET_RCR_CRCFWD |
CONFIG_NET_ETH_MTU << ENET_RCR_MAX_FL_SHIFT |
ENET_RCR_MII_MODE;
@@ -1468,28 +1949,46 @@ static inline void kinetis_initphy(struct kinetis_driver_s *priv)
/* Setup half or full duplex */
- if ((phydata & PHY_DUPLEX_STATUS) != 0)
+ if (BOARD_PHY_ISDUPLEX(phydata))
{
/* Full duplex */
+ ninfo("%s: Full duplex\n", BOARD_PHY_NAME);
tcr |= ENET_TCR_FDEN;
}
else
{
/* Half duplex */
+ ninfo("%s: Half duplex\n", BOARD_PHY_NAME);
rcr |= ENET_RCR_DRT;
}
- if ((phydata & PHY_SPEED_STATUS) != 0)
+ if (BOARD_PHY_10BASET(phydata))
{
- /* 10Mbps */
+ /* 10 Mbps */
+ ninfo("%s: 10 Base-T\n", BOARD_PHY_NAME);
rcr |= ENET_RCR_RMII_10T;
}
+ else if (!BOARD_PHY_100BASET(phydata))
+ {
+ /* 100 Mbps */
+
+ ninfo("%s: 100 Base-T\n", BOARD_PHY_NAME);
+ }
+ else
+ {
+ /* This might happen if autonegotiation did not complete(?) */
+
+ nerr("ERROR: Neither 10- nor 100-BaseT reported: PHY STATUS=%04x\n",
+ phydata);
+ return -EIO;
+ }
putreg32(rcr, KINETIS_ENET_RCR);
putreg32(tcr, KINETIS_ENET_TCR);
+ return OK;
}
/****************************************************************************
@@ -1520,7 +2019,7 @@ static void kinetis_initbuffers(struct kinetis_driver_s *priv)
/* Get an aligned RX descriptor (array) address */
- addr += CONFIG_ENET_NTXBUFFERS * sizeof(struct enet_desc_s);
+ addr += CONFIG_KINETIS_ENETNTXBUFFERS * sizeof(struct enet_desc_s);
priv->rxdesc = (struct enet_desc_s *)addr;
/* Get the beginning of the first aligned buffer */
@@ -1529,12 +2028,12 @@ static void kinetis_initbuffers(struct kinetis_driver_s *priv)
/* Then fill in the TX descriptors */
- for (i = 0; i < CONFIG_ENET_NTXBUFFERS; i++)
+ for (i = 0; i < CONFIG_KINETIS_ENETNTXBUFFERS; i++)
{
priv->txdesc[i].status1 = 0;
priv->txdesc[i].length = 0;
priv->txdesc[i].data = (uint8_t *)kinesis_swap32((uint32_t)addr);
-#ifdef CONFIG_ENET_ENHANCEDBD
+#ifdef CONFIG_KINETIS_ENETENHANCEDBD
priv->txdesc[i].status2 = TXDESC_IINS | TXDESC_PINS;
#endif
addr += KINETIS_BUF_SIZE;
@@ -1542,12 +2041,12 @@ static void kinetis_initbuffers(struct kinetis_driver_s *priv)
/* Then fill in the RX descriptors */
- for (i = 0; i < CONFIG_ENET_NRXBUFFERS; i++)
+ for (i = 0; i < CONFIG_KINETIS_ENETNRXBUFFERS; i++)
{
priv->rxdesc[i].status1 = RXDESC_E;
priv->rxdesc[i].length = 0;
priv->rxdesc[i].data = (uint8_t *)kinesis_swap32((uint32_t)addr);
-#ifdef CONFIG_ENET_ENHANCEDBD
+#ifdef CONFIG_KINETIS_ENETENHANCEDBD
priv->rxdesc[i].bdu = 0;
priv->rxdesc[i].status2 = RXDESC_INT;
#endif
@@ -1556,8 +2055,8 @@ static void kinetis_initbuffers(struct kinetis_driver_s *priv)
/* Set the wrap bit in the last descriptors to form a ring */
- priv->txdesc[CONFIG_ENET_NTXBUFFERS-1].status1 |= TXDESC_W;
- priv->rxdesc[CONFIG_ENET_NRXBUFFERS-1].status1 |= RXDESC_W;
+ priv->txdesc[CONFIG_KINETIS_ENETNTXBUFFERS-1].status1 |= TXDESC_W;
+ priv->rxdesc[CONFIG_KINETIS_ENETNRXBUFFERS-1].status1 |= RXDESC_W;
/* We start with RX descriptor 0 and with no TX descriptors in use */
@@ -1631,7 +2130,7 @@ int kinetis_netinitialize(int intf)
/* Get the interface structure associated with this interface number. */
- DEBUGASSERT(intf < CONFIG_ENET_NETHIFS);
+ DEBUGASSERT(intf < CONFIG_KINETIS_ENETNETHIFS);
priv = &g_enet[intf];
/* Enable the ENET clock */
@@ -1646,9 +2145,9 @@ int kinetis_netinitialize(int intf)
putreg32(0, KINETIS_MPU_CESR);
+#ifdef CONFIG_KINETIS_ENETUSEMII
/* Configure all ENET/MII pins */
-#ifdef CONFIG_ENET_USEMII
kinetis_pinconfig(PIN_MII0_MDIO);
kinetis_pinconfig(PIN_MII0_MDC);
kinetis_pinconfig(PIN_MII0_RXDV);
@@ -1668,6 +2167,8 @@ int kinetis_netinitialize(int intf)
kinetis_pinconfig(PIN_MII0_CRS);
kinetis_pinconfig(PIN_MII0_COL);
#else
+ /* Use RMII subset */
+
kinetis_pinconfig(PIN_RMII0_MDIO);
kinetis_pinconfig(PIN_RMII0_MDC);
kinetis_pinconfig(PIN_RMII0_CRS_DV);
@@ -1773,7 +2274,7 @@ int kinetis_netinitialize(int intf)
*
****************************************************************************/
-#if CONFIG_ENET_NETHIFS == 1
+#if CONFIG_KINETIS_ENETNETHIFS == 1
void up_netinitialize(void)
{
(void)kinetis_netinitialize(0);
diff --git a/arch/arm/src/kinetis/kinetis_ftfl.h b/arch/arm/src/kinetis/kinetis_ftfl.h
deleted file mode 100644
index 92e53b650d03d2cfbaf6ba3b3cd9427304069d8d..0000000000000000000000000000000000000000
--- a/arch/arm/src/kinetis/kinetis_ftfl.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/************************************************************************************
- * arch/arm/src/kinetis/kinetis_ftfl.h
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt
- *
- * 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 __ARCH_ARM_SRC_KINETIS_KINETIS_FTFL_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_FTFL_H
-
-/************************************************************************************
- * Included Files
- ************************************************************************************/
-
-#include
-
-#include "chip.h"
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/* Register Offsets *****************************************************************/
-
-#define KINETIS_FTFL_FSTAT_OFFSET 0x0000 /* Flash Status Register */
-#define KINETIS_FTFL_FCNFG_OFFSET 0x0001 /* Flash Configuration Register */
-#define KINETIS_FTFL_FSEC_OFFSET 0x0002 /* Flash Security Register */
-#define KINETIS_FTFL_FOPT_OFFSET 0x0003 /* Flash Option Register */
-
-#define KINETIS_FTFL_FCCOB3_OFFSET 0x0004 /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB2_OFFSET 0x0005 /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB1_OFFSET 0x0006 /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB0_OFFSET 0x0007 /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB7_OFFSET 0x0008 /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB6_OFFSET 0x0009 /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB5_OFFSET 0x000a /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB4_OFFSET 0x000b /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOBB_OFFSET 0x000c /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOBA_OFFSET 0x000d /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB9_OFFSET 0x000e /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FCCOB8_OFFSET 0x000f /* Flash Common Command Object Registers */
-#define KINETIS_FTFL_FPROT3_OFFSET 0x0010 /* Program Flash Protection Registers */
-#define KINETIS_FTFL_FPROT2_OFFSET 0x0011 /* Program Flash Protection Registers */
-#define KINETIS_FTFL_FPROT1_OFFSET 0x0012 /* Program Flash Protection Registers */
-#define KINETIS_FTFL_FPROT0_OFFSET 0x0013 /* Program Flash Protection Registers */
-#define KINETIS_FTFL_FEPROT_OFFSET 0x0016 /* EEPROM Protection Register */
-#define KINETIS_FTFL_FDPROT_OFFSET 0x0017 /* Data Flash Protection Register */
-
-/* Register Addresses ***************************************************************/
-
-#define KINETIS_FTFL_FSTAT (KINETIS_FTFL_BASE+KINETIS_FTFL_FSTAT_OFFSET)
-#define KINETIS_FTFL_FCNFG (KINETIS_FTFL_BASE+KINETIS_FTFL_FCNFG_OFFSET)
-#define KINETIS_FTFL_FSEC (KINETIS_FTFL_BASE+KINETIS_FTFL_FSEC_OFFSET)
-#define KINETIS_FTFL_FOPT (KINETIS_FTFL_BASE+KINETIS_FTFL_FOPT_OFFSET)
-#define KINETIS_FTFL_FCCOB3 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB3_OFFSET)
-#define KINETIS_FTFL_FCCOB2 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB2_OFFSET)
-#define KINETIS_FTFL_FCCOB1 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB1_OFFSET)
-#define KINETIS_FTFL_FCCOB0 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB0_OFFSET)
-#define KINETIS_FTFL_FCCOB7 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB7_OFFSET)
-#define KINETIS_FTFL_FCCOB6 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB6_OFFSET)
-#define KINETIS_FTFL_FCCOB5 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB5_OFFSET)
-#define KINETIS_FTFL_FCCOB4 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB4_OFFSET)
-#define KINETIS_FTFL_FCCOBB (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOBB_OFFSET)
-#define KINETIS_FTFL_FCCOBA (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOBA_OFFSET)
-#define KINETIS_FTFL_FCCOB9 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB9_OFFSET)
-#define KINETIS_FTFL_FCCOB8 (KINETIS_FTFL_BASE+KINETIS_FTFL_FCCOB8_OFFSET)
-#define KINETIS_FTFL_FPROT3 (KINETIS_FTFL_BASE+KINETIS_FTFL_FPROT3_OFFSET)
-#define KINETIS_FTFL_FPROT2 (KINETIS_FTFL_BASE+KINETIS_FTFL_FPROT2_OFFSET)
-#define KINETIS_FTFL_FPROT1 (KINETIS_FTFL_BASE+KINETIS_FTFL_FPROT1_OFFSET)
-#define KINETIS_FTFL_FPROT0 (KINETIS_FTFL_BASE+KINETIS_FTFL_FPROT0_OFFSET)
-#define KINETIS_FTFL_FEPROT (KINETIS_FTFL_BASE+KINETIS_FTFL_FEPROT_OFFSET)
-#define KINETIS_FTFL_FDPROT (KINETIS_FTFL_BASE+KINETIS_FTFL_FDPROT_OFFSET)
-
-/* Register Bit Definitions *********************************************************/
-
-/* Flash Status Register */
-
-#define FTFL_FSTAT_MGSTAT0 (1 << 0) /* Bit 0: Memory Controller Command Completion Status Flag */
- /* Bits 1-3: Reserved */
-#define FTFL_FSTAT_FPVIOL (1 << 4) /* Bit 4: Flash Protection Violation Flag */
-#define FTFL_FSTAT_ACCERR (1 << 5) /* Bit 5: Flash Access Error Flag */
-#define FTFL_FSTAT_RDCOLERR (1 << 6) /* Bit 6: FTFL Read Collision Error Flag */
-#define FTFL_FSTAT_CCIF (1 << 7) /* Bit 7: Command Complete Interrupt Flag */
-
-/* Flash Configuration Register */
-
-#define FTFL_FCNFG_EEERDY (1 << 0) /* Bit 0: FEEPROM backup data copied to FlexRAM */
-#define FTFL_FCNFG_RAMRDY (1 << 1) /* Bit 1: RAM Ready */
-#define FTFL_FCNFG_PFLSH (1 << 2) /* Bit 2: FTFL configuration */
-#define FTFL_FCNFG_SWAP (1 << 3) /* Bit 3: Swap */
-#define FTFL_FCNFG_ERSSUSP (1 << 4) /* Bit 4: Erase Suspend */
-#define FTFL_FCNFG_ERSAREQ (1 << 5) /* Bit 5: Erase All Request */
-#define FTFL_FCNFG_RDCOLLIE (1 << 6) /* Bit 6: Read Collision Error Interrupt Enable */
-#define FTFL_FCNFG_CCIE (1 << 7) /* Bit 7: Command Complete Interrupt Enable */
-
-/* Flash Security Register */
-
-#define FTFL_FSEC_SEC_SHIFT (0) /* Bits 0-1: Flash Security */
-#define FTFL_FSEC_SEC_MASK (3 << FTFL_FSEC_SEC_SHIFT)
-# define FTFL_FSEC_SEC_SECURE (0 << FTFL_FSEC_SEC_SHIFT) /* 00,01,11: status is secure */
-# define FTFL_FSEC_SEC_UNSECURE (2 << FTFL_FSEC_SEC_SHIFT) /* 10: status is insecure */
-#define FTFL_FSEC_FSLACC_SHIFT (2) /* Bits 2-3: Freescale Failure Analysis Access Code */
-#define FTFL_FSEC_FSLACC_MASK (3 << FTFL_FSEC_FSLACC_SHIFT)
-# define FTFL_FSEC_FSLACC_GRANTED (0 << FTFL_FSEC_FSLACC_SHIFT) /* 00 or 11: Access granted */
-# define FTFL_FSEC_FSLACC_DENIED (1 << FTFL_FSEC_FSLACC_SHIFT) /* 01 or 10: Access denied */
-#define FTFL_FSEC_MEEN_SHIFT (4) /* Bits 4-5: Mass Erase Enable Bits */
-#define FTFL_FSEC_MEEN_MASK (3 << FTFL_FSEC_MEEN_SHIFT)
-# define FTFL_FSEC_MEEN_ENABLED (0 << FTFL_FSEC_MEEN_SHIFT) /* All values are enabled */
-#define FTFL_FSEC_KEYEN_SHIFT (6) /* Bits 6-7: Backdoor Key Security Enable */
-#define FTFL_FSEC_KEYEN_MASK (3 << FTFL_FSEC_KEYEN_SHIFT)
-# define FTFL_FSEC_KEYEN_DISABLED (1 << FTFL_FSEC_KEYEN_SHIFT) /* All values are disabled */
-
-/* Flash Option Register (32-bits, see Chip Configuration details) */
-/* Flash Common Command Object Registers (8-bit flash command data) */
-/* Program Flash Protection Registers (8-bit flash protection data) */
-/* EEPROM Protection Register (8-bit eeprom protection data) */
-/* Data Flash Protection Register (8-bit data flash protection data) */
-
-/************************************************************************************
- * Public Types
- ************************************************************************************/
-
-/************************************************************************************
- * Public Data
- ************************************************************************************/
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_FTFL_H */
diff --git a/arch/arm/src/kinetis/kinetis_lowputc.c b/arch/arm/src/kinetis/kinetis_lowputc.c
index bd3b27a8769bd97d4945ad5d32e2d6e3637bfd52..ec85713c9331564ff3c7a2c6baed916ef561faff 100644
--- a/arch/arm/src/kinetis/kinetis_lowputc.c
+++ b/arch/arm/src/kinetis/kinetis_lowputc.c
@@ -49,9 +49,9 @@
#include "kinetis_config.h"
#include "kinetis.h"
-#include "kinetis_uart.h"
-#include "kinetis_sim.h"
-#include "kinetis_pinmux.h"
+#include "chip/kinetis_uart.h"
+#include "chip/kinetis_sim.h"
+#include "chip/kinetis_pinmux.h"
/****************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/kinetis/kinetis_memorymap.h b/arch/arm/src/kinetis/kinetis_memorymap.h
deleted file mode 100644
index 1e7d2820de451ebfd117c086c31a2de30e2ba3ff..0000000000000000000000000000000000000000
--- a/arch/arm/src/kinetis/kinetis_memorymap.h
+++ /dev/null
@@ -1,461 +0,0 @@
-/************************************************************************************
- * arch/arm/src/kinetis/kinetis_memorymap.h
- *
- * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt
- *
- * 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 __ARCH_ARM_SRC_KINETIS_KINETIS_MEMORYMAP_H
-#define __ARCH_ARM_SRC_KINETIS_KINETIS_MEMORYMAP_H
-
-/************************************************************************************
- * Included Files
- ************************************************************************************/
-
-#include
-
-#include "chip.h"
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/* Memory Map ***********************************************************************/
-/* K20 Family
- *
- * The memory map for the following parts is defined in Freescale document
- * K20P64M72SF1RM
- */
-
-#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7)
-
-# define KINETIS_FLASH_BASE 0x00000000 /* –0x0fffffff Program flash and read-
- * only data (Includes exception
- * vectors in first 1024 bytes) */
-# if !defined(KINETIS_FLEXMEM_SIZE)
-# define KINETIS_FLEXNVM_BASE 0x10000000 /* –0x13ffffff FlexNVM */
-# define KINETIS_FLEXRAM_BASE 0x14000000 /* –0x17ffffff FlexRAM */
-# endif
- /* 0x18000000 * –0x1bffffff Reserved */
-# define KINETIS_SRAML_BASE 0x1c000000 /* –0x1fffffff SRAM_L: Lower SRAM
- * (ICODE/DCODE) */
-# define KINETIS_SRAMU_BASE 0x20000000 /* –0x200fffff SRAM_U: Upper SRAM bitband
- * region */
- /* 0x20100000 * –0x21ffffff Reserved */
-# define KINETIS_SALIAS_BASE 0x22000000 /* –0x23ffffff Aliased to SRAM_U bitband */
- /* 0x24000000 * –0x3fffffff Reserved */
-# define KINETIS_BRIDGE0_BASE 0x40000000 /* –0x4007ffff Bitband region for peripheral
- * bridge 0 (AIPS-Lite0) */
-# define KINETIS_BRIDGE1_BASE 0x40080000 /* –0x400fffff Bitband region for peripheral
- * bridge 1 (AIPS-Lite1) */
-# define KINETIS_GPIOBB_BASE 0x400ff000 /* –0x400fffff Bitband region for general
- * purpose input/output (GPIO) */
- /* 0x40100000 * –0x41ffffff Reserved */
-# define KINETIS_PALIAS_BASE 0x42000000 /* –0x43ffffff Aliased to peripheral bridge
- * (AIPS-Lite) and general purpose
- * input/output (GPIO) bitband */
- /* 0x44000000 * –0xdfffffff Reserved */
-# define KINETIS_PERIPH_BASE 0xe0000000 /* –0xe00fffff Private peripherals */
- /* 0xe0100000 * –0xffffffff Reserved */
-
-/* Peripheral Bridge 0 Memory Map ***************************************************/
-
-# define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */
-# define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */
-# define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */
-# define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */
-# define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */
-# define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */
-# define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */
-# define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */
-# define KINETIS_SPI0_BASE 0x4002c000 /* SPI 0 */
-# define KINETIS_SPI1_BASE 0x4002d000 /* SPI 1 */
-# define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */
-# define KINETIS_CRC_BASE 0x40032000 /* CRC */
-# define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */
-# define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */
-# define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */
-# define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer 0 */
-# define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer 1 */
-# define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */
-# define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */
-# define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */
-# define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */
-# define KINETIS_SYSR_BASE 0x40041000 /* System register file */
-# define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */
-# define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */
-# define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */
-# define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12))
-# define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */
-# define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */
-# define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */
-# define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */
-# define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */
-# define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */
-# define KINETIS_EWM_BASE 0x40061000 /* External watchdog */
-# define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */
-# define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */
-# define KINETIS_OSC_BASE 0x40065000 /* System oscillator (OSC) */
-# define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */
-# define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */
-# define KINETIS_UART0_BASE 0x4006a000 /* UART0 */
-# define KINETIS_UART1_BASE 0x4006b000 /* UART1 */
-# define KINETIS_UART2_BASE 0x4006c000 /* UART2 */
-# define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */
-# define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */
-# define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */
-# define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */
-# define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */
-# define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */
-
-/* Peripheral Bridge 1 Memory Map ***************************************************/
-
-# define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */
-# define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */
-# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
-# define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */
-
-# define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general
- * purpose input/output module that shares the
- * crossbar switch slave port with the AIPS-Lite
- * is accessed at this address. */
-# define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6))
-# define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */
-# define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */
-# define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */
-# define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */
-# define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */
-
-/* Private Peripheral Bus (PPB) Memory Map ******************************************/
-
-# define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */
-# define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */
-# define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */
-# define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */
-# define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */
-# define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */
-# define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */
-
-/* Memory Map ***********************************************************************/
-/* K40 Family
- *
- * The memory map for the following parts is defined in Freescale document
- * K40P144M100SF2RM
- */
-
-#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100)
-
-# define KINETIS_FLASH_BASE 0x00000000 /* –0x0fffffff Program flash and read-
- * only data (Includes exception
- * vectors in first 1024 bytes) */
-# if !defined(KINETIS_FLEXMEM_SIZE)
-# define KINETIS_FLEXNVM_BASE 0x10000000 /* –0x13ffffff FlexNVM */
-# define KINETIS_FLEXRAM_BASE 0x14000000 /* –0x17ffffff FlexRAM */
-# endif
-# define KINETIS_SRAML_BASE 0x18000000 /* –0x1fffffff SRAM_L: Lower SRAM
- * (ICODE/DCODE) */
-# define KINETIS_SRAMU_BASE 0x20000000 /* –0x200fffff SRAM_U: Upper SRAM bitband
- * region */
- /* 0x20100000 * –0x21ffffff Reserved */
-# define KINETIS_SALIAS_BASE 0x22000000 /* –0x23ffffff Aliased to SRAM_U bitband */
- /* 0x24000000 * –0x3fffffff Reserved */
-# define KINETIS_BRIDGE0_BASE 0x40000000 /* –0x4007ffff Bitband region for peripheral
- * bridge 0 (AIPS-Lite0) */
-# define KINETIS_BRIDGE1_BASE 0x40080000 /* –0x400fffff Bitband region for peripheral
- * bridge 1 (AIPS-Lite1) */
-# define KINETIS_GPIOBB_BASE 0x400ff000 /* –0x400fffff Bitband region for general
- * purpose input/output (GPIO) */
- /* 0x40100000 * –0x41ffffff Reserved */
-# define KINETIS_PALIAS_BASE 0x42000000 /* –0x43ffffff Aliased to peripheral bridge
- * (AIPS-Lite) and general purpose
- * input/output (GPIO) bitband */
- /* 0x44000000 * –0x5fffffff Reserved */
-# define KINETIS_FLEXBUS_WBBASE 0x60000000 /* –0x7fffffff FlexBus (External Memory -
- * Write-back) */
-# define KINETIS_FLEXBUS_WTBASE 0x80000000 /* –0x9fffffff FlexBus (External Memory -
- * Write-through) */
-# define KINETIS_FLEXBUS_NXBASE 0xa0000000 /* –0xdfffffff FlexBus (External Memory -
- * Non-executable) */
-# define KINETIS_PERIPH_BASE 0xe0000000 /* –0xe00fffff Private peripherals */
- /* 0xe0100000 * –0xffffffff Reserved */
-
-/* Peripheral Bridge 0 Memory Map ***************************************************/
-
-# define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */
-# define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */
-# define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */
-# define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */
-# define KINETIS_FLEXBUSC_BASE 0x4000c000 /* FlexBus controller */
-# define KINETIS_MPU_BASE 0x4000d000 /* MPU */
-# define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */
-# define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */
-# define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */
-# define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */
-# define KINETIS_SPI0_BASE 0x4002c000 /* SPI 0 */
-# define KINETIS_SPI1_BASE 0x4002d000 /* SPI 1 */
-# define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */
-# define KINETIS_CRC_BASE 0x40032000 /* CRC */
-# define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */
-# define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */
-# define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */
-# define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer 0 */
-# define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer 1 */
-# define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */
-# define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */
-# define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */
-# define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */
-# define KINETIS_SYSR_BASE 0x40041000 /* System register file */
-# define KINETIS_DRYICE_BASE 0x40042000 /* DryIce */
-# define KINETIS_DRYICESS_BASE 0x40043000 /* DryIce secure storage */
-# define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */
-# define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */
-# define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */
-# define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12))
-# define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */
-# define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */
-# define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */
-# define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */
-# define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */
-# define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */
-# define KINETIS_EWM_BASE 0x40061000 /* External watchdog */
-# define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */
-# define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */
-# define KINETIS_OSC_BASE 0x40065000 /* System oscillator (OSC) */
-# define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */
-# define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */
-# define KINETIS_UART0_BASE 0x4006a000 /* UART0 */
-# define KINETIS_UART1_BASE 0x4006b000 /* UART1 */
-# define KINETIS_UART2_BASE 0x4006c000 /* UART2 */
-# define KINETIS_UART3_BASE 0x4006d000 /* UART3 */
-# define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */
-# define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */
-# define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */
-# define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */
-# define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */
-# define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */
-
-/* Peripheral Bridge 1 Memory Map ***************************************************/
-
-# define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */
-# define KINETIS_CAN1_BASE 0x400a4000 /* FlexCAN 1 */
-# define KINETIS_SPI2_BASE 0x400ac000 /* SPI 2 */
-# define KINETIS_SDHC_BASE 0x400b1000 /* SDHC */
-# define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */
-# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
-# define KINETIS_SLCD_BASE 0x400be000 /* Segment LCD */
-# define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */
-# define KINETIS_DAC1_BASE 0x400cd000 /* 12-bit digital-to-analog converter (DAC) 1 */
-# define KINETIS_UART4_BASE 0x400ea000 /* UART4 */
-# define KINETIS_UART5_BASE 0x400eb000 /* UART5 */
-# define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general
- * purpose input/output module that shares the
- * crossbar switch slave port with the AIPS-Lite
- * is accessed at this address. */
-# define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6))
-# define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */
-# define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */
-# define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */
-# define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */
-# define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */
-
-/* Private Peripheral Bus (PPB) Memory Map ******************************************/
-
-# define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */
-# define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */
-# define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */
-# define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */
-# define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */
-# define KINETIS_ETM_BASE 0xe0041000 /* Embedded Trace Macrocell (ETM) */
-# define KINETIS_ETB_BASE 0xe0042000 /* Embedded Trace Buffer (ETB) */
-# define KINETIS_TFUN_BASE 0xe0043000 /* Embedded Trace Funnel */
-# define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */
-# define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */
-
-/* Memory Map ***********************************************************************/
-/* K60 Family
- *
- * The memory map for the following parts is defined in Freescale document
- * K60P144M100SF2RM
- */
-
-#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \
- defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK60N512VLL100)
-
-# define KINETIS_FLASH_BASE 0x00000000 /* –0x0fffffff Program flash and read-
- * only data (Includes exception
- * vectors in first 1024 bytes) */
-# if !defined(KINETIS_FLEXMEM_SIZE)
-# define KINETIS_FLEXNVM_BASE 0x10000000 /* –0x13ffffff FlexNVM */
-# define KINETIS_FLEXRAM_BASE 0x14000000 /* –0x17ffffff FlexRAM */
-# endif
-# define KINETIS_SRAML_BASE 0x18000000 /* –0x1fffffff SRAM_L: Lower SRAM
- * (ICODE/DCODE) */
-# define KINETIS_SRAMU_BASE 0x20000000 /* –0x200fffff SRAM_U: Upper SRAM bitband
- * region */
- /* 0x20100000 * –0x21ffffff Reserved */
-# define KINETIS_SALIAS_BASE 0x22000000 /* –0x23ffffff Aliased to SRAM_U bitband */
- /* 0x24000000 * –0x3fffffff Reserved */
-# define KINETIS_BRIDGE0_BASE 0x40000000 /* –0x4007ffff Bitband region for peripheral
- * bridge 0 (AIPS-Lite0) */
-# define KINETIS_BRIDGE1_BASE 0x40080000 /* –0x400fffff Bitband region for peripheral
- * bridge 1 (AIPS-Lite1) */
-# define KINETIS_GPIOBB_BASE 0x400ff000 /* –0x400fffff Bitband region for general
- * purpose input/output (GPIO) */
- /* 0x40100000 * –0x41ffffff Reserved */
-# define KINETIS_PALIAS_BASE 0x42000000 /* –0x43ffffff Aliased to peripheral bridge
- * (AIPS-Lite) and general purpose
- * input/output (GPIO) bitband */
- /* 0x44000000 * –0x5fffffff Reserved */
-# define KINETIS_FLEXBUS_BASE 0x60000000 /* –0x7fffffff FlexBus */
-# define KINETIS_PERIPH_BASE 0xe0000000 /* –0xe00fffff Private peripherals */
- /* 0xe0100000 * –0xffffffff Reserved */
-
-/* Peripheral Bridge 0 Memory Map ***************************************************/
-
-# define KINETIS_AIPS0_BASE 0x40000000 /* Peripheral bridge 0 (AIPS-Lite 0) */
-# define KINETIS_XBAR_BASE 0x40004000 /* Crossbar switch */
-# define KINETIS_DMAC_BASE 0x40008000 /* DMA controller */
-# define KINETIS_DMADESC_BASE 0x40009000 /* DMA controller transfer control descriptors */
-# define KINETIS_FLEXBUSC_BASE 0x4000c000 /* FlexBus controller */
-# define KINETIS_MPU_BASE 0x4000d000 /* MPU */
-# define KINETIS_FMC_BASE 0x4001f000 /* Flash memory controller */
-# define KINETIS_FTFL_BASE 0x40020000 /* Flash memory */
-# define KINETIS_DMAMUX0_BASE 0x40021000 /* DMA channel mutiplexer 0 */
-# define KINETIS_CAN0_BASE 0x40024000 /* FlexCAN 0 */
-# define KINETIS_SPI0_BASE 0x4002c000 /* DSPI 0 */
-# define KINETIS_SPI1_BASE 0x4002d000 /* DSPI 1 */
-# define KINETIS_I2S0_BASE 0x4002f000 /* I2S 0 */
-# define KINETIS_CRC_BASE 0x40032000 /* CRC */
-# define KINETIS_USBDCD_BASE 0x40035000 /* USB DCD */
-# define KINETIS_PDB0_BASE 0x40036000 /* Programmable delay block */
-# define KINETIS_PIT_BASE 0x40037000 /* Periodic interrupt timers (PIT) */
-# define KINETIS_FTM0_BASE 0x40038000 /* FlexTimer (FTM) 0 */
-# define KINETIS_FTM1_BASE 0x40039000 /* FlexTimer (FTM) 1 */
-# define KINETIS_ADC0_BASE 0x4003b000 /* Analog-to-digital converter (ADC) 0 */
-# define KINETIS_RTC_BASE 0x4003d000 /* Real time clock */
-# define KINETIS_VBATR_BASE 0x4003e000 /* VBAT register file */
-# define KINETIS_LPTMR_BASE 0x40040000 /* Low power timer */
-# define KINETIS_SYSR_BASE 0x40041000 /* System register file */
-# define KINETIS_DRYICE_BASE 0x40042000 /* DryIce */
-# define KINETIS_DRYICESS_BASE 0x40043000 /* DryIce secure storage */
-# define KINETIS_TSI0_BASE 0x40045000 /* Touch sense interface */
-# define KINETIS_SIMLP_BASE 0x40047000 /* SIM low-power logic */
-# define KINETIS_SIM_BASE 0x40048000 /* System integration module (SIM) */
-# define KINETIS_PORT_BASE(n) (0x40049000 + ((n) << 12))
-# define KINETIS_PORTA_BASE 0x40049000 /* Port A multiplexing control */
-# define KINETIS_PORTB_BASE 0x4004a000 /* Port B multiplexing control */
-# define KINETIS_PORTC_BASE 0x4004b000 /* Port C multiplexing control */
-# define KINETIS_PORTD_BASE 0x4004c000 /* Port D multiplexing control */
-# define KINETIS_PORTE_BASE 0x4004d000 /* Port E multiplexing control */
-# define KINETIS_WDOG_BASE 0x40052000 /* Software watchdog */
-# define KINETIS_EWM_BASE 0x40061000 /* External watchdog */
-# define KINETIS_CMT_BASE 0x40062000 /* Carrier modulator timer (CMT) */
-# define KINETIS_MCG_BASE 0x40064000 /* Multi-purpose Clock Generator (MCG) */
-# define KINETIS_OSC_BASE 0x40065000 /* System oscillator (XOSC) */
-# define KINETIS_I2C0_BASE 0x40066000 /* I2C 0 */
-# define KINETIS_I2C1_BASE 0x40067000 /* I2C 1 */
-# define KINETIS_UART0_BASE 0x4006a000 /* UART0 */
-# define KINETIS_UART1_BASE 0x4006b000 /* UART1 */
-# define KINETIS_UART2_BASE 0x4006c000 /* UART2 */
-# define KINETIS_UART3_BASE 0x4006d000 /* UART3 */
-# define KINETIS_USB0_BASE 0x40072000 /* USB OTG FS/LS */
-# define KINETIS_CMP_BASE 0x40073000 /* Analog comparator (CMP) / 6-bit digital-to-analog converter (DAC) */
-# define KINETIS_VREF_BASE 0x40074000 /* Voltage reference (VREF) */
-# define KINETIS_LLWU_BASE 0x4007c000 /* Low-leakage wakeup unit (LLWU) */
-# define KINETIS_PMC_BASE 0x4007d000 /* Power management controller (PMC) */
-# define KINETIS_SMC_BASE 0x4007e000 /* System Mode controller (SMC) */
-
-/* Peripheral Bridge 1 Memory Map ***************************************************/
-
-# define KINETIS_AIPS1_BASE 0x40080000 /* Peripheral bridge 1 (AIPS-Lite 1) */
-# define KINETIS_RNGB_BASE 0x400a0000 /* Random number generator (RNGB) */
-# define KINETIS_CAN1_BASE 0x400a4000 /* FlexCAN 1 */
-# define KINETIS_SPI2_BASE 0x400ac000 /* DSPI 2 */
-# define KINETIS_SDHC_BASE 0x400b1000 /* SDHC */
-# define KINETIS_FTM2_BASE 0x400b8000 /* FlexTimer 2 */
-# define KINETIS_ADC1_BASE 0x400bb000 /* Analog-to-digital converter (ADC) 1 */
-# define KINETIS_EMAC_BASE 0x400c0000 /* Ethernet MAC and IEEE 1588 timers */
-# define KINETIS_DAC0_BASE 0x400cc000 /* 12-bit digital-to-analog converter (DAC) 0 */
-# define KINETIS_DAC1_BASE 0x400cd000 /* 12-bit digital-to-analog converter (DAC) 1 */
-# define KINETIS_UART4_BASE 0x400ea000 /* UART4 */
-# define KINETIS_UART5_BASE 0x400eb000 /* UART5 */
-# define KINETIS_XBARSS_BASE 0x400ff000 /* Not an AIPS-Lite slot. The 32-bit general
- * purpose input/output module that shares the
- * crossbar switch slave port with the AIPS-Lite
- * is accessed at this address. */
-# define KINETIS_GPIO_BASE(n) (0x400ff000 + ((n) << 6))
-# define KINETIS_GPIOA_BASE 0x400ff000 /* GPIO PORTA registers */
-# define KINETIS_GPIOB_BASE 0x400ff040 /* GPIO PORTB registers */
-# define KINETIS_GPIOC_BASE 0x400ff080 /* GPIO PORTC registers */
-# define KINETIS_GPIOD_BASE 0x400ff0c0 /* GPIO PORTD registers */
-# define KINETIS_GPIOE_BASE 0x400ff100 /* GPIO PORTE registers */
-
-/* Private Peripheral Bus (PPB) Memory Map ******************************************/
-
-# define KINETIS_ITM_BASE 0xe0000000 /* Instrumentation Trace Macrocell (ITM) */
-# define KINETIS_DWT_BASE 0xe0001000 /* Data Watchpoint and Trace (DWT) */
-# define KINETIS_FPB_BASE 0xe0002000 /* Flash Patch and Breakpoint (FPB) */
-# define KINETIS_SCS_BASE 0xe000e000 /* System Control Space (SCS) (for NVIC) */
-# define KINETIS_TPIU_BASE 0xe0040000 /* Trace Port Interface Unit (TPIU) */
-# define KINETIS_ETM_BASE 0xe0041000 /* Embedded Trace Macrocell (ETM) */
-# define KINETIS_ETB_BASE 0xe0042000 /* Embedded Trace Buffer (ETB) */
-# define KINETIS_TFUN_BASE 0xe0043000 /* Embedded Trace Funnel */
-# define KINETIS_MCM_BASE 0xe0080000 /* Miscellaneous Control Module (including ETB Almost Full) */
-# define KINETIS_MMCAU_BASE 0xe0081000 /* Memory Mapped Cryptographic Acceleration Unit (MMCAU) */
-# define KINETIS_ROMTAB_BASE 0xe00ff000 /* ROM Table - allows auto-detection of debug components */
-
-#else
- /* The memory map for other parts is defined in other documents and may or may not
- * be the same as above (the family members are all very similar) This error just
- * means that you have to look at the document and determine for yourself if the
- * memory map is the same.
- */
-
-# error "No memory map for this Kinetis part"
-#endif
-
-/************************************************************************************
- * Public Types
- ************************************************************************************/
-
-/************************************************************************************
- * Public Data
- ************************************************************************************/
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_MEMORYMAP_H */
diff --git a/arch/arm/src/kinetis/kinetis_mpuinit.h b/arch/arm/src/kinetis/kinetis_mpuinit.h
index f3cf95370efc9addeb53f17871c50b370aa1239f..3327176841b742c3c652ceb7539e3ce3d5bf84fb 100644
--- a/arch/arm/src/kinetis/kinetis_mpuinit.h
+++ b/arch/arm/src/kinetis/kinetis_mpuinit.h
@@ -42,18 +42,6 @@
#include
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/************************************************************************************
- * Public Types
- ************************************************************************************/
-
-/************************************************************************************
- * Public Data
- ************************************************************************************/
-
/************************************************************************************
* Public Functions
************************************************************************************/
diff --git a/arch/arm/src/kinetis/kinetis_pin.c b/arch/arm/src/kinetis/kinetis_pin.c
index 851d0c9d9cf885a9eab330d5d06502dc10535183..8a2e3294321a6ce237c2dd19be73404fa4751d50 100644
--- a/arch/arm/src/kinetis/kinetis_pin.c
+++ b/arch/arm/src/kinetis/kinetis_pin.c
@@ -48,22 +48,9 @@
#include "up_arch.h"
#include "up_internal.h"
-#include "kinetis_memorymap.h"
#include "kinetis.h"
-#include "kinetis_port.h"
-#include "kinetis_gpio.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
+#include "chip/kinetis_port.h"
+#include "chip/kinetis_gpio.h"
/****************************************************************************
* Public Functions
diff --git a/arch/arm/src/kinetis/kinetis_pindump.c b/arch/arm/src/kinetis/kinetis_pindump.c
index 579c01bb4d2c9d1752e29d6002664b4d9e910500..a660c87307c014bcb1ae255116d7124a1f63fa2c 100644
--- a/arch/arm/src/kinetis/kinetis_pindump.c
+++ b/arch/arm/src/kinetis/kinetis_pindump.c
@@ -46,8 +46,8 @@
#include "up_arch.h"
#include "kinetis.h"
-#include "kinetis_gpio.h"
-#include "kinetis_port.h"
+#include "chip/kinetis_gpio.h"
+#include "chip/kinetis_port.h"
#ifdef CONFIG_DEBUG_GPIO_INFO
diff --git a/arch/arm/src/kinetis/kinetis_pingpio.c b/arch/arm/src/kinetis/kinetis_pingpio.c
index 3663a92399f8c58e6523394970d5285912889ba0..b8879208164ef1bb05e36ac126e6e3624df41681 100644
--- a/arch/arm/src/kinetis/kinetis_pingpio.c
+++ b/arch/arm/src/kinetis/kinetis_pingpio.c
@@ -48,21 +48,8 @@
#include "up_arch.h"
#include "up_internal.h"
-#include "kinetis_memorymap.h"
#include "kinetis.h"
-#include "kinetis_gpio.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
+#include "chip/kinetis_gpio.h"
/****************************************************************************
* Public Functions
diff --git a/arch/arm/src/kinetis/kinetis_pinirq.c b/arch/arm/src/kinetis/kinetis_pinirq.c
index 0ec0d64176b30e8882154adc9fb6a4261745ab07..919d51e67c9498bdb905e187599557191ad2c82d 100644
--- a/arch/arm/src/kinetis/kinetis_pinirq.c
+++ b/arch/arm/src/kinetis/kinetis_pinirq.c
@@ -50,7 +50,7 @@
#include "up_internal.h"
#include "kinetis.h"
-#include "kinetis_port.h"
+#include "chip/kinetis_port.h"
#ifdef CONFIG_GPIO_IRQ
diff --git a/arch/arm/src/kinetis/kinetis_pwm.c b/arch/arm/src/kinetis/kinetis_pwm.c
index 0730bf8dd835beb841ae70c14eea92e4f0ced95f..19de382634eea0319f02b553c71921a5985a679f 100644
--- a/arch/arm/src/kinetis/kinetis_pwm.c
+++ b/arch/arm/src/kinetis/kinetis_pwm.c
@@ -58,10 +58,10 @@
#include "chip.h"
#include "kinetis.h"
-#include "kinetis_pwm.h"
-#include "kinetis_gpio.h"
-#include "kinetis_ftm.h"
-#include "kinetis_sim.h"
+#include "chip/kinetis_pwm.h"
+#include "chip/kinetis_gpio.h"
+#include "chip/kinetis_ftm.h"
+#include "chip/kinetis_sim.h"
/* This module then only compiles if there is at least one enabled timer
* intended for use with the PWM upper half driver.
diff --git a/arch/arm/src/kinetis/kinetis_pwm.h b/arch/arm/src/kinetis/kinetis_pwm.h
index 09508d4bfea7a1433bb7865600a1d924c4fa4e63..8e6070279634ecff1ec4494debeed76e4a989e2f 100644
--- a/arch/arm/src/kinetis/kinetis_pwm.h
+++ b/arch/arm/src/kinetis/kinetis_pwm.h
@@ -73,7 +73,7 @@
defined(CONFIG_KINETIS_FTM2_PWM)
#include
-#include "kinetis_pinmux.h"
+#include "chip/kinetis_pinmux.h"
/* For each timer that is enabled for PWM usage, we need the following additional
* configuration settings:
diff --git a/arch/arm/src/kinetis/kinetis_sdhc.c b/arch/arm/src/kinetis/kinetis_sdhc.c
index aff35be9b4d8fc82346d9c92666c3b7ff8fce837..afc85f5989255db19d3fd3d22273eef1f5e792ce 100644
--- a/arch/arm/src/kinetis/kinetis_sdhc.c
+++ b/arch/arm/src/kinetis/kinetis_sdhc.c
@@ -61,9 +61,9 @@
#include "up_arch.h"
#include "kinetis.h"
-#include "kinetis_pinmux.h"
-#include "kinetis_sim.h"
-#include "kinetis_sdhc.h"
+#include "chip/kinetis_pinmux.h"
+#include "chip/kinetis_sim.h"
+#include "chip/kinetis_sdhc.h"
#ifdef CONFIG_KINETIS_SDHC
diff --git a/arch/arm/src/kinetis/kinetis_serial.c b/arch/arm/src/kinetis/kinetis_serial.c
index d47235ba90b8055f2217be0b0b18b3293e3a2b3b..53fd7e2b4ab32418dd048d393a7ca5dd1c1771c7 100644
--- a/arch/arm/src/kinetis/kinetis_serial.c
+++ b/arch/arm/src/kinetis/kinetis_serial.c
@@ -59,7 +59,7 @@
#include "kinetis_config.h"
#include "chip.h"
-#include "kinetis_uart.h"
+#include "chip/kinetis_uart.h"
#include "kinetis.h"
/****************************************************************************
diff --git a/arch/arm/src/kinetis/kinetis_start.c b/arch/arm/src/kinetis/kinetis_start.c
index 8de2524ef5600670e156c6369017d490dac20016..21885d926823fdaaaf592fff9639b81b11fd6ef3 100644
--- a/arch/arm/src/kinetis/kinetis_start.c
+++ b/arch/arm/src/kinetis/kinetis_start.c
@@ -51,7 +51,7 @@
#include "up_internal.h"
#include "kinetis.h"
-#include "kinetis_smc.h"
+#include "chip/kinetis_smc.h"
#include "kinetis_userspace.h"
/****************************************************************************
diff --git a/arch/arm/src/kinetis/kinetis_usbdev.c b/arch/arm/src/kinetis/kinetis_usbdev.c
index 8deedb7603c99ecbd06bf8bd25c39ff9ea4abf85..d8d9512cabf2255d4e510f20b4bf03779a1eae91 100644
--- a/arch/arm/src/kinetis/kinetis_usbdev.c
+++ b/arch/arm/src/kinetis/kinetis_usbdev.c
@@ -67,8 +67,8 @@
#include "up_arch.h"
#include "kinetis.h"
#include "kinetis_usbotg.h"
-#include "kinetis_sim.h"
-#include "kinetis_fmc.h"
+#include "chip/kinetis_sim.h"
+#include "chip/kinetis_fmc.h"
#if defined(CONFIG_USBDEV) && defined(CONFIG_KINETIS_USBOTG)
diff --git a/arch/arm/src/kinetis/kinetis_usbotg.h b/arch/arm/src/kinetis/kinetis_usbotg.h
index de53d512933301f567c5089c9276d7480d544b7d..655c7ccee9c622e1aaa6a4cb4528f52c43b7c054 100644
--- a/arch/arm/src/kinetis/kinetis_usbotg.h
+++ b/arch/arm/src/kinetis/kinetis_usbotg.h
@@ -42,311 +42,7 @@
#include
-#include "chip.h"
-
-/********************************************************************************************
- * Pre-processor Definitions
- ********************************************************************************************/
-
-/* Register Offsets *************************************************************************/
-
-#define KINETIS_USB_PERID_OFFSET 0x0000 /* Peripheral ID Register */
-#define KINETIS_USB_IDCOMP_OFFSET 0x0004 /* Peripheral ID Complement Register */
-#define KINETIS_USB_REV_OFFSET 0x0008 /* Peripheral Revision Register */
-#define KINETIS_USB_ADDINFO_OFFSET 0x000c /* Peripheral Additional Info Register */
-#define KINETIS_USB_OTGISTAT_OFFSET 0x0010 /* OTG Interrupt Status Register */
-#define KINETIS_USB_OTGICR_OFFSET 0x0014 /* OTG Interrupt Control Register */
-#define KINETIS_USB_OTGSTAT_OFFSET 0x0018 /* OTG Status Register */
-#define KINETIS_USB_OTGCTL_OFFSET 0x001c /* OTG Control Register */
-#define KINETIS_USB_ISTAT_OFFSET 0x0080 /* Interrupt Status Register */
-#define KINETIS_USB_INTEN_OFFSET 0x0084 /* Interrupt Enable Register */
-#define KINETIS_USB_ERRSTAT_OFFSET 0x0088 /* Error Interrupt Status Register */
-#define KINETIS_USB_ERREN_OFFSET 0x008c /* Error Interrupt Enable Register */
-#define KINETIS_USB_STAT_OFFSET 0x0090 /* Status Register */
-#define KINETIS_USB_CTL_OFFSET 0x0094 /* Control Register */
-#define KINETIS_USB_ADDR_OFFSET 0x0098 /* Address Register */
-#define KINETIS_USB_BDTPAGE1_OFFSET 0x009c /* BDT Page Register 1 */
-#define KINETIS_USB_FRMNUML_OFFSET 0x00a0 /* Frame Number Register Low */
-#define KINETIS_USB_FRMNUMH_OFFSET 0x00a4 /* Frame Number Register High */
-#define KINETIS_USB_TOKEN_OFFSET 0x00a8 /* Token Register */
-#define KINETIS_USB_SOFTHLD_OFFSET 0x00ac /* SOF Threshold Register */
-#define KINETIS_USB_BDTPAGE2_OFFSET 0x00b0 /* BDT Page Register 2 */
-#define KINETIS_USB_BDTPAGE3_OFFSET 0x00b4 /* BDT Page Register 3 */
-
-#define KINETIS_USB_ENDPT_OFFSET(n) (0x00c0+((n)<<2)) /* Endpoint n Control Register */
-#define KINETIS_USB_ENDPT0_OFFSET 0x00c0 /* Endpoint 0 Control Register */
-#define KINETIS_USB_ENDPT1_OFFSET 0x00c4 /* Endpoint 1 Control Register */
-#define KINETIS_USB_ENDPT2_OFFSET 0x00c8 /* Endpoint 2 Control Register */
-#define KINETIS_USB_ENDPT3_OFFSET 0x00cc /* Endpoint 3 Control Register */
-#define KINETIS_USB_ENDPT4_OFFSET 0x00d0 /* Endpoint 4 Control Register */
-#define KINETIS_USB_ENDPT5_OFFSET 0x00d4 /* Endpoint 5 Control Register */
-#define KINETIS_USB_ENDPT6_OFFSET 0x00d8 /* Endpoint 6 Control Register */
-#define KINETIS_USB_ENDPT7_OFFSET 0x00dc /* Endpoint 7 Control Register */
-#define KINETIS_USB_ENDPT8_OFFSET 0x00e0 /* Endpoint 8 Control Register */
-#define KINETIS_USB_ENDPT9_OFFSET 0x00e4 /* Endpoint 9 Control Register */
-#define KINETIS_USB_ENDPT10_OFFSET 0x00e8 /* Endpoint 10 Control Register */
-#define KINETIS_USB_ENDPT11_OFFSET 0x00ec /* Endpoint 11 Control Register */
-#define KINETIS_USB_ENDPT12_OFFSET 0x00f0 /* Endpoint 12 Control Register */
-#define KINETIS_USB_ENDPT13_OFFSET 0x00f4 /* Endpoint 13 Control Register */
-#define KINETIS_USB_ENDPT14_OFFSET 0x00f8 /* Endpoint 14 Control Register */
-#define KINETIS_USB_ENDPT15_OFFSET 0x00fc /* Endpoint 15 Control Register */
-
-#define KINETIS_USB_USBCTRL_OFFSET 0x0100 /* USB Control Register */
-#define KINETIS_USB_OBSERVE_OFFSET 0x0104 /* USB OTG Observe Register */
-#define KINETIS_USB_CONTROL_OFFSET 0x0108 /* USB OTG Control Register */
-#define KINETIS_USB_USBTRC0_OFFSET 0x010c /* USB Transceiver Control Register 0 */
-
-/* Register Addresses ***********************************************************************/
-
-#define KINETIS_USB0_PERID (KINETIS_USB0_BASE+KINETIS_USB_PERID_OFFSET)
-#define KINETIS_USB0_IDCOMP (KINETIS_USB0_BASE+KINETIS_USB_IDCOMP_OFFSET)
-#define KINETIS_USB0_REV (KINETIS_USB0_BASE+KINETIS_USB_REV_OFFSET)
-#define KINETIS_USB0_ADDINFO (KINETIS_USB0_BASE+KINETIS_USB_ADDINFO_OFFSET)
-#define KINETIS_USB0_OTGISTAT (KINETIS_USB0_BASE+KINETIS_USB_OTGISTAT_OFFSET)
-#define KINETIS_USB0_OTGICR (KINETIS_USB0_BASE+KINETIS_USB_OTGICR_OFFSET)
-#define KINETIS_USB0_OTGSTAT (KINETIS_USB0_BASE+KINETIS_USB_OTGSTAT_OFFSET)
-#define KINETIS_USB0_OTGCTL (KINETIS_USB0_BASE+KINETIS_USB_OTGCTL_OFFSET)
-#define KINETIS_USB0_ISTAT (KINETIS_USB0_BASE+KINETIS_USB_ISTAT_OFFSET)
-#define KINETIS_USB0_INTEN (KINETIS_USB0_BASE+KINETIS_USB_INTEN_OFFSET)
-#define KINETIS_USB0_ERRSTAT (KINETIS_USB0_BASE+KINETIS_USB_ERRSTAT_OFFSET)
-#define KINETIS_USB0_ERREN (KINETIS_USB0_BASE+KINETIS_USB_ERREN_OFFSET)
-#define KINETIS_USB0_STAT (KINETIS_USB0_BASE+KINETIS_USB_STAT_OFFSET)
-#define KINETIS_USB0_CTL (KINETIS_USB0_BASE+KINETIS_USB_CTL_OFFSET)
-#define KINETIS_USB0_ADDR (KINETIS_USB0_BASE+KINETIS_USB_ADDR_OFFSET)
-#define KINETIS_USB0_BDTPAGE1 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE1_OFFSET)
-#define KINETIS_USB0_FRMNUML (KINETIS_USB0_BASE+KINETIS_USB_FRMNUML_OFFSET)
-#define KINETIS_USB0_FRMNUMH (KINETIS_USB0_BASE+KINETIS_USB_FRMNUMH_OFFSET)
-#define KINETIS_USB0_TOKEN (KINETIS_USB0_BASE+KINETIS_USB_TOKEN_OFFSET)
-#define KINETIS_USB0_SOFTHLD (KINETIS_USB0_BASE+KINETIS_USB_SOFTHLD_OFFSET)
-#define KINETIS_USB0_BDTPAGE2 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE2_OFFSET)
-#define KINETIS_USB0_BDTPAGE3 (KINETIS_USB0_BASE+KINETIS_USB_BDTPAGE3_OFFSET)
-
-#define KINETIS_USB0_ENDPT(n) (KINETIS_USB0_BASE+KINETIS_USB_ENDPT_OFFSET(n))
-#define KINETIS_USB0_ENDPT0 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT0_OFFSET)
-#define KINETIS_USB0_ENDPT1 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT1_OFFSET)
-#define KINETIS_USB0_ENDPT2 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT2_OFFSET)
-#define KINETIS_USB0_ENDPT3 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT3_OFFSET)
-#define KINETIS_USB0_ENDPT4 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT4_OFFSET)
-#define KINETIS_USB0_ENDPT5 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT5_OFFSET)
-#define KINETIS_USB0_ENDPT6 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT6_OFFSET)
-#define KINETIS_USB0_ENDPT7 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT7_OFFSET)
-#define KINETIS_USB0_ENDPT8 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT8_OFFSET)
-#define KINETIS_USB0_ENDPT9 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT9_OFFSET)
-#define KINETIS_USB0_ENDPT10 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT10_OFFSET)
-#define KINETIS_USB0_ENDPT11 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT11_OFFSET)
-#define KINETIS_USB0_ENDPT12 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT12_OFFSET)
-#define KINETIS_USB0_ENDPT13 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT13_OFFSET)
-#define KINETIS_USB0_ENDPT14 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT14_OFFSET)
-#define KINETIS_USB0_ENDPT15 (KINETIS_USB0_BASE+KINETIS_USB_ENDPT15_OFFSET)
-
-#define KINETIS_USB0_USBCTRL (KINETIS_USB0_BASE+KINETIS_USB_USBCTRL_OFFSET)
-#define KINETIS_USB0_OBSERVE (KINETIS_USB0_BASE+KINETIS_USB_OBSERVE_OFFSET)
-#define KINETIS_USB0_CONTROL (KINETIS_USB0_BASE+KINETIS_USB_CONTROL_OFFSET)
-#define KINETIS_USB0_USBTRC0 (KINETIS_USB0_BASE+KINETIS_USB_USBTRC0_OFFSET)
-
-/* Register Bit Definitions *****************************************************************/
-
-/* Peripheral ID Register (8-bit) */
- /* Bits 6-7: Reserved */
-#define USB_PERID_MASK (0x3f) /* Bits 0-5: Peripheral identification bits */
-
-/* Peripheral ID Complement Register (8-bit) */
-#define USB_IDCOMP_
- /* Bits 6-7: Reserved */
-#define USB_IDCOMP_MASK (0x3f) /* Bits 0-5: Ones complement of peripheral identification bits */
-
-/* Peripheral Revision Register (8-bit revision number) */
-
-/* Peripheral Additional Info Register (8-bit) */
-
-#define USB_ADDINFO_IEHOST (1 << 0) /* Bit 0: This bit is set if host mode is enabled */
- /* Bits 1-2: Reserved */
-#define USB_ADDINFO_IRQNUM_SHIFT (3) /* Bits 3-7: Assigned Interrupt Request Number */
-#define USB_ADDINFO_IRQNUM_MASK (31 << USB_ADDINFO_IRQNUM_SHIFT)
-
-/* OTG Interrupt Status Register(8-bit) */
-
-#define USB_OTGISTAT_AVBUSCHG (1 << 0) /* Bit 0: Change in VBUS is detected on an A device */
- /* Bit 1: Reserved */
-#define USB_OTGISTAT_B_SESS_CHG (1 << 2) /* Bit 2: Change in VBUS is detected on a B device */
-#define USB_OTGISTAT_SESSVLDCHG (1 << 3) /* Bit 3: Change in VBUS is detected */
- /* Bit 4: Reserved */
-#define USB_OTGISTAT_LINE_STATE_CHG (1 << 5) /* Bit 5: Change USB line state */
-#define USB_OTGISTAT_ONEMSEC (1 << 6) /* Bit 6: Set when the 1 millisecond timer expires */
-#define USB_OTGISTAT_IDCHG (1 << 7) /* Bit 7: Change in ID Signal from the USB connector */
-
-/* OTG Interrupt Control Register (8-bit) */
-
-#define USB_OTGICR_AVBUSEN (1 << 0) /* Bit 0: A VBUS Valid interrupt enable */
- /* Bit 1: Reserved */
-#define USB_OTGICR_BSESSEN (1 << 2) /* Bit 2: B Session END interrupt enable */
-#define USB_OTGICR_SESSVLDEN (1 << 3) /* Bit 3: Session valid interrupt enable */
- /* Bit 4: Reserved */
-#define USB_OTGICR_LINESTATEEN (1 << 5) /* Bit 5: Line State change interrupt enable */
-#define USB_OTGICR_ONEMSECEN (1 << 6) /* Bit 6: 1 millisecond interrupt enable */
-#define USB_OTGICR_IDEN (1 << 7) /* Bit 7: ID interrupt enable */
-
-/* OTG Status Register (8-bit) */
-
-#define USB_OTGSTAT_AVBUSVLD (1 << 0) /* Bit 0: A VBUS Valid */
- /* Bit 1: Reserved */
-#define USB_OTGSTAT_BSESSEND (1 << 2) /* Bit 2: B Session END */
-#define USB_OTGSTAT_SESS_VLD (1 << 3) /* Bit 3: Session valid */
- /* Bit 4: Reserved */
-#define USB_OTGSTAT_LINESTATESTABLE (1 << 5) /* Bit 5: OTGISTAT LINE_STATE_CHG bit stable */
-#define USB_OTGSTAT_ONEMSECEN (1 << 6) /* Bit 6: Reserved for the 1msec count */
-#define USB_OTGSTAT_ID (1 << 7) /* Bit 7: Current state of the ID pin on the USB connector */
-
-/* OTG Control Register (8-bit) */
- /* Bits 0-1: Reserved */
-#define USB_OTGCTL_OTGEN (1 << 2) /* Bit 2: On-The-Go pullup/pulldown resistor enable */
- /* Bit 3: Reserved */
-#define USB_OTGCTL_DMLOW (1 << 4) /* Bit 4: D- Data Line pull-down resistor enable */
-#define USB_OTGCTL_DPLOW (1 << 5) /* Bit 5: D+ Data Line pull-down resistor enable */
- /* Bit 6: Reserved */
-#define USB_OTGCTL_DPHIGH (1 << 7) /* Bit 7: D+ Data Line pullup resistor enable */
-
-/* Interrupt Status Register Interrupt Enable Register (8-bit) */
-
-#define USB_INT_USBRST (1 << 0) /* Bit 0: USB Module has decoded a valid USB reset */
-#define USB_INT_ERROR (1 << 1) /* Bit 1: Any of the error conditions within the ERRSTAT register */
-#define USB_INT_SOFTOK (1 << 2) /* Bit 2: USB Module received a Start Of Frame (SOF) token */
-#define USB_INT_TOKDNE (1 << 3) /* Bit 3: Current token being processed has completed */
-#define USB_INT_SLEEP (1 << 4) /* Bit 4: Constant idle on the USB bus for 3 milliseconds */
-#define USB_INT_RESUME (1 << 5) /* Bit 5: Signal remote wake-up signaling */
-#define USB_INT_ATTACH (1 << 6) /* Bit 6: Attach Interrupt */
-#define USB_INT_STALL (1 << 7) /* Bit 7: Stall Interrupt */
-
-#define USB_INT_ALL 0xFF
-
-/* Error Interrupt Status Register and Error Interrupt Enable Register (8-bit) */
-
-#define USB_ERRSTAT_PIDERR (1 << 0) /* Bit 0: This bit is set when the PID check field fails */
-#define USB_ERRSTAT_CRC5EOF (1 << 1) /* Bit 1: Host data CRC error or End of frame errors */
-#define USB_ERRSTAT_CRC16 (1 << 2) /* Bit 2: Data packet is rejected due to a CRC16 error */
-#define USB_ERRSTAT_DFN8 (1 << 3) /* Bit 3: Data field received was not 8 bits in length */
-#define USB_ERRSTAT_BTOERR (1 << 4) /* Bit 4: Bus turnaround timeout error occurred */
-#define USB_ERRSTAT_DMAERR (1 << 5) /* Bit 5: DMA error */
- /* Bit 6: Reserved */
-#define USB_ERRSTAT_BTSERR (1 << 7) /* Bit 7: Bit stuff error is detected */
-
-#define USB_EINT_ALL 0xBF
-
-/* Status Register (8-bit) */
-
- /* Bits 0-1: Reserved */
-#define USB_STAT_ODD (1 << 2) /* Bit 2: Last Buffer Descriptor was in the odd bank of the BDT */
-#define USB_STAT_TX (1 << 3) /* Bit 3: Transmit Indicator */
-#define USB_STAT_ENDP_SHIFT (4) /* Bits 4-7: Endpoint address that received or transmitted the token */
-#define USB_STAT_ENDP_MASK (15 << USB_STAT_ENDP_SHIFT)
-
-/* Control Register (8-bit) */
-
-#define USB_CTL_USBENSOFEN (1 << 0) /* Bit 0: USB Enable */
-#define USB_CTL_ODDRST (1 << 1) /* Bit 1: Resets all the BDT ODD ping/pong bits to 0 */
-#define USB_CTL_RESUME (1 << 2) /* Bit 2: Enables the USB Module to execute resume signaling */
-#define USB_CTL_HOSTMODEEN (1 << 3) /* Bit 3: Enables the USB Module to operate in Host mode */
-#define USB_CTL_RESET (1 << 4) /* Bit 4: Enables the USB Module to generate USB reset signaling */
-#define USB_CTL_TXSUSPENDTOKENBUSY (1 << 5) /* Bit 5: USB Module is busy executing a USB token */
-#define USB_CTL_SE0 (1 << 6) /* Bit 6: Live USB Single Ended Zero signal */
-#define USB_CTL_JSTATE (1 << 7) /* Bit 7: Live USB differential receiver JSTATE signal */
-
-/* Address Register (8-bit) */
-
-#define USB_ADDR_LSEN (1 << 7) /* Bit 7: Low Speed Enable bit */
-#define USB_ADDR_SHIFT (0) /* Bits 0-6: USB address */
-#define USB_ADDR_MASK (0x7f << USB_ADDR_SHIFT)
-
-/* BDT Page Register 1 (8-bit) */
- /* Bit 0: Reserved */
-#define USB_BDTPAGE1_SHIFT (1) /* Bits 1-7: Address bits 9-15 of the BDT base address */
-#define USB_BDTPAGE1_MASK (0x7f << USB_BDTPAGE1_SHIFT)
-
-/* Frame Number Register Low (8-bit, bits 0-7 of the 11 bit frame number) */
-#define USB_FRMNUML_MASK 0xFF
-/* Frame Number Register High (8-bit) */
- /* Bits 3-7: Reserved */
-#define USB_FRMNUMH_SHIFT (0) /* Bits 0-2: Bits 8-10 of the 11-bit frame number */
-#define USB_FRMNUMH_MASK (7 << USB_FRMNUMH_SHIFT)
-
-/* Token Register (8-bit) */
-
-#define USB_TOKEN_ENDPT_SHIFT (0) /* Bits 0-3: Endpoint address for the token command */
-#define USB_TOKEN_ENDPT_MASK (15 << USB_TOKEN_ENDPT_SHIFT)
-#define USB_TOKEN_PID_SHIFT (4) /* Bits 4-7: Token type executed by the USB Module */
-#define USB_TOKEN_PID_MASK (15 << USB_TOKEN_PID_SHIFT)
-# define USB_TOKEN_PID_OUT (1 << USB_TOKEN_PID_SHIFT) /* OUT Token */
-# define USB_TOKEN_PID_IN (9 << USB_TOKEN_PID_SHIFT) /* IN Token */
-# define USB_TOKEN_PID_SETUP (13 << USB_TOKEN_PID_SHIFT) /* SETUP Token */
-
-/* SOF Threshold Register (8-bit count value) */
-/* BDT Page Register 2/3 (16 bit address in two 8-bit registers) */
-
-/* Endpoint n Control Register (8-bit) */
-
-#define USB_ENDPT_EPHSHK (1 << 0) /* Bit 0: Enable handshaking during a transaction to the endpoint */
-#define USB_ENDPT_EPSTALL (1 << 1) /* Bit 1: Endpoint is stalled */
-#define USB_ENDPT_EPTXEN (1 << 2) /* Bit 2: Enable the endpoint for TX transfers */
-#define USB_ENDPT_EPRXEN (1 << 3) /* Bit 3: Enable the endpoint for RX transfers */
-#define USB_ENDPT_EPCTLDIS (1 << 4) /* Bit 4: Disable control (SETUP) transfers */
- /* Bit 5: Reserved */
-#define USB_ENDPT_RETRYDIS (1 << 6) /* Bit 6: Disable host retry NAK'ed transactions (host EP0) */
-#define USB_ENDPT_HOSTWOHUB (1 << 7) /* Bit 7: Allows the host to communicate to a low speed device (host EP0) */
-
-/* USB Control Register (8-bit) */
- /* Bits 0-5: Reserved */
-#define USB_USBCTRL_PDE (1 << 6) /* Bit 6: Enables the weak pulldowns on the USB transceiver */
-#define USB_USBCTRL_SUSP (1 << 7) /* Bit 7: Places the USB transceiver into the suspend state */
-
-/* USB OTG Observe Register (8-bit) */
- /* Bits 0-3: Reserved */
-#define USB_OBSERVE_DMPD (1 << 4) /* Bit 4: D- Pull Down signal output from the USB OTG module */
- /* Bit 5: Reserved */
-#define USB_OBSERVE_DPPD (1 << 6) /* Bit 6: D+ Pull Down signal output from the USB OTG module */
-#define USB_OBSERVE_DPPU (1 << 7) /* Bit 7: D+ Pull Up signal output from the USB OTG module */
-
-/* USB OTG Control Register (8-bit) */
- /* Bits 0-3: Reserved */
-#define USB_CONTROL_DPPULLUPNONOTG (1 << 4) /* Bit 4: Controls of the DP PULLUP in the USB OTG module */
- /* Bits 5-7: Reserved */
-/* USB Transceiver Control Register 0 (8-bit) */
-
-#define USB_USBTRC0_USBRESET (1 << 7) /* Bit 7: USB reset */
- /* Bit 6: Reserved */
-#define USB_USBTRC0_USBRESMEN (1 << 5) /* Bit 5: Asynchronous Resume Interrupt Enable */
- /* Bits 2-4: Reserved */
-#define USB_USBTRC0_SYNC_DET (1 << 1) /* Bit 1: Synchronous USB Interrupt Detect */
-#define USB_USBTRC0_RESUME_INT (1 << 0) /* Bit 0: USB Asynchronous Interrupt */
-
-/* Buffer Descriptor Table (BDT) ****************************************************/
-/* Offset 0: On write (software->hardware) */
-
-#define USB_BDT_STATUS_MASK 0xfc /* Bits 2-7: Status bits */
-#define USB_BDT_BSTALL (1 << 2) /* Bit 2: Buffer Stall Enable bit */
-#define USB_BDT_DTS (1 << 3) /* Bit 3: Data Toggle Synchronization Enable bit */
-#define USB_BDT_NINC (1 << 4) /* Bit 4: DMA Address Increment Disable bit */
-#define USB_BDT_KEEP (1 << 5) /* Bit 5: BD Keep Enable bit */
-#define USB_BDT_DATA01 (1 << 6) /* Bit 6: Data Toggle Packet bit */
-#define USB_BDT_UOWN (1 << 7) /* Bit 7: USB Own bit */
-#define USB_BDT_BYTECOUNT_SHIFT (16) /* Bits 16-25: Byte Count bits */
-#define USB_BDT_BYTECOUNT_MASK (0x3ff << USB_BDT_BYTECOUNT_SHIFT)
-
-#define USB_BDT_DATA0 0 /* DATA0 packet expected next */
-#define USB_BDT_DATA1 USB_BDT_DATA01 /* DATA1 packet expected next */
-#define USB_BDT_COWN 0 /* CPU owns the descriptor */
-
-/* Offset 0: On read (hardware->software) */
-
-#define USB_BDT_PID_SHIFT (2) /* Bits 2-5: Packet Identifier bits */
-#define USB_BDT_PID_MASK (15 << USB_BDT_PID_SHIFT)
- /* Bit 7: USB Own bit (same) */
- /* Bits 16-25: Byte Count bits (same) */
-
-/* Offset 4: BUFFER_ADDRESS, 32-bit Buffer Address bits */
-
-#define USB_BDT_BYTES_SIZE 8 /* Eight bytes per BDT */
-#define USB_BDT_WORD_SIZE 2 /* Two 32-bit words per BDT */
-#define USB_NBDTS_PER_EP 4 /* Number of BDTS per endpoint: IN/OUT and EVEN/ODD */
+#include "chip/kinetis_usbotg.h"
/************************************************************************************
* Public Types
diff --git a/arch/arm/src/kinetis/kinetis_vectors.S b/arch/arm/src/kinetis/kinetis_vectors.S
index 75c295ae033342bc25f0f64c80aa99beee7e3372..39f07fc000f041f11ddcaaf0293f876aa2b12faa 100644
--- a/arch/arm/src/kinetis/kinetis_vectors.S
+++ b/arch/arm/src/kinetis/kinetis_vectors.S
@@ -42,6 +42,7 @@
#include
+#include "chip.h"
#include "exc_return.h"
/************************************************************************************************
@@ -160,7 +161,7 @@ _vectors:
* K20P64M72SF1RM
*/
-#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7)
+#if defined(KINETIS_K20)
.word kinetis_dmach0 /* Vector 16: DMA channel 0 transfer complete */
.word kinetis_dmach1 /* Vector 17: DMA channel 1 transfer complete */
.word kinetis_dmach2 /* Vector 18: DMA channel 2 transfer complete */
@@ -263,9 +264,7 @@ _vectors:
* K40P144M100SF2RM
*/
-#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100)
+#elif defined(KINETIS_K40)
.word kinetis_dmach0 /* Vector 16: DMA channel 0 transfer complete */
.word kinetis_dmach1 /* Vector 17: DMA channel 1 transfer complete */
@@ -369,10 +368,7 @@ _vectors:
* K60P144M100SF2RM
*/
-#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \
- defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK60N512VLL100)
+#elif defined(KINETIS_K60)
.word kinetis_dmach0 /* Vector 16: DMA channel 0 transfer complete */
.word kinetis_dmach1 /* Vector 17: DMA channel 1 transfer complete */
@@ -478,6 +474,102 @@ _vectors:
.word kinetis_reserved /* Vector 117: Reserved */
.word kinetis_reserved /* Vector 118: Reserved */
.word kinetis_reserved /* Vector 119: Reserved */
+
+/* K64 Family ***********************************************************************************
+ *
+ * The memory map for the following parts is defined in Freescale document
+ * MK64FX512VLL12
+ */
+
+#elif defined(KINETIS_K64)
+
+ .word kinetis_dmach0 /* Vector 16: DMA channel 0 transfer complete */
+ .word kinetis_dmach1 /* Vector 17: DMA channel 1 transfer complete */
+ .word kinetis_dmach2 /* Vector 18: DMA channel 2 transfer complete */
+ .word kinetis_dmach3 /* Vector 19: DMA channel 3 transfer complete */
+ .word kinetis_dmach4 /* Vector 20: DMA channel 4 transfer complete */
+ .word kinetis_dmach5 /* Vector 21: DMA channel 5 transfer complete */
+ .word kinetis_dmach6 /* Vector 22: DMA channel 6 transfer complete */
+ .word kinetis_dmach7 /* Vector 23: DMA channel 7 transfer complete */
+ .word kinetis_dmach8 /* Vector 24: DMA channel 8 transfer complete */
+ .word kinetis_dmach9 /* Vector 25: DMA channel 9 transfer complete */
+ .word kinetis_dmach10 /* Vector 26: DMA channel 10 transfer complete */
+ .word kinetis_dmach11 /* Vector 27: DMA channel 11 transfer complete */
+ .word kinetis_dmach12 /* Vector 28: DMA channel 12 transfer complete */
+ .word kinetis_dmach13 /* Vector 29: DMA channel 13 transfer complete */
+ .word kinetis_dmach14 /* Vector 30: DMA channel 14 transfer complete */
+ .word kinetis_dmach15 /* Vector 31: DMA channel 15 transfer complete */
+ .word kinetis_dmaerr /* Vector 32: DMA error interrupt channels 0-15 */
+ .word kinetis_mcm /* Vector 33: MCM Normal interrupt */
+ .word kinetis_flashcc /* Vector 34: Flash memory command complete */
+ .word kinetis_flashrc /* Vector 35: Flash memory read collision */
+ .word kinetis_smclvd /* Vector 36: Mode Controller low-voltage detect, low-voltage warning */
+ .word kinetis_llwu /* Vector 37: LLWU Normal Low Leakage Wakeup */
+ .word kinetis_wdog /* Vector 38: Watchdog */
+ .word kinetis_rngb /* Vector 39: Random number generator */
+ .word kinetis_i2c0 /* Vector 40: I2C0 */
+ .word kinetis_i2c1 /* Vector 41: I2C1 */
+ .word kinetis_spi0 /* Vector 42: SPI0 all sources */
+ .word kinetis_spi1 /* Vector 43: SPI1 all sources */
+ .word kinetis_i2s0 /* Vector 44: Transmit */
+ .word kinetis_i2s1 /* Vector 45: Transmit */
+ .word kinetis_reserved /* Vector 46: Reserved */
+ .word kinetis_uart0s /* Vector 47: UART0 status */
+ .word kinetis_uart0e /* Vector 48: UART0 error */
+ .word kinetis_uart1s /* Vector 49: UART1 status */
+ .word kinetis_uart1e /* Vector 50: UART1 error */
+ .word kinetis_uart2s /* Vector 51: UART2 status */
+ .word kinetis_uart2e /* Vector 52: UART2 error */
+ .word kinetis_uart3s /* Vector 53: UART3 status */
+ .word kinetis_uart3e /* Vector 54: UART3 error */
+ .word kinetis_adc0 /* Vector 55: ADC0 */
+ .word kinetis_cmp0 /* Vector 56: CMP0 */
+ .word kinetis_cmp1 /* Vector 57: CMP1 */
+ .word kinetis_ftm0 /* Vector 58: FTM0 all sources */
+ .word kinetis_ftm1 /* Vector 59: FTM1 all sources */
+ .word kinetis_ftm2 /* Vector 60: FTM2 all sources */
+ .word kinetis_cmt /* Vector 61: CMT */
+ .word kinetis_rtc0 /* Vector 62: RTC alarm interrupt */
+ .word kinetis_rtc1 /* Vector 63: RTC seconds interrupt */
+ .word kinetis_pitch0 /* Vector 64: PIT channel 0 */
+ .word kinetis_pitch1 /* Vector 65: PIT channel 1 */
+ .word kinetis_pitch2 /* Vector 66: PIT channel 2 */
+ .word kinetis_pitch3 /* Vector 67: PIT channel 3 */
+ .word kinetis_pdb /* Vector 68: PDB */
+ .word kinetis_usbotg /* Vector 68: USB OTG */
+ .word kinetis_usbcd /* Vector 70: USB charger detect */
+ .word kinetis_reserved /* Vector 71: Reserved */
+ .word kinetis_dac0 /* Vector 72: DAC0 */
+ .word kinetis_mcg /* Vector 73: MCG */
+ .word kinetis_lpt /* Vector 74: Low power timer */
+ .word kinetis_porta /* Vector 75: Pin detect port A */
+ .word kinetis_portb /* Vector 76: Pin detect port B */
+ .word kinetis_portc /* Vector 77: Pin detect port C */
+ .word kinetis_portd /* Vector 78: Pin detect port D */
+ .word kinetis_porte /* Vector 79: Pin detect port E */
+ .word kinetis_software /* Vector 80: Software interrupt */
+ .word kinetis_spi2 /* Vector 81: SPI2 all sources */
+ .word kinetis_uart4s /* Vector 82: UART4 status */
+ .word kinetis_uart4e /* Vector 83: UART4 error */
+ .word kinetis_uart5s /* Vector 84: UART5 status */
+ .word kinetis_uart5e /* Vector 85: UART5 error */
+ .word kinetis_cmp2 /* Vector 86: CMP2 */
+ .word kinetis_ftm3 /* Vector 87: FTM3 all sources */
+ .word kinetis_dac1 /* Vector 88: DAC1 */
+ .word kinetis_adc1 /* Vector 89: ADC1 */
+ .word kinetis_i2c2 /* Vector 90: I2C2 */
+ .word kinetis_can0mb /* Vector 91: CAN0 ORed Message buffer (0-15) */
+ .word kinetis_can0bo /* Vector 92: CAN0 Bus Off */
+ .word kinetis_can0err /* Vector 93: CAN0 Error */
+ .word kinetis_can0tw /* Vector 94: CAN0 Transmit Warning */
+ .word kinetis_can0rw /* Vector 95: CAN0 Receive Warning */
+ .word kinetis_can0wu /* Vector 96: CAN0 Wake UP */
+ .word kinetis_sdhc /* Vector 97: SDHC */
+ .word kinetis_emactmr /* Vector 91: Ethernet MAC IEEE 1588 timer interrupt */
+ .word kinetis_emactx /* Vector 92: Ethernet MAC transmit interrupt */
+ .word kinetis_emacrx /* Vector 93: Ethernet MAC receive interrupt */
+ .word kinetis_emacmisc /* Vector 94: Ethernet MAC error and misc interrupt */
+
#else
# error "No vectors for this Kinetis part"
#endif
@@ -505,13 +597,13 @@ handlers:
HANDLER kinetis_systick, KINETIS_IRQ_SYSTICK /* Vector 15: System tick */
/* External Interrupts **************************************************************************/
-/* K40 Family ***********************************************************************************
+/* K20 Family ***********************************************************************************
*
* The interrupt vectors for the following parts is defined in Freescale document
* K20P64M72SF1RM
*/
-#if defined(CONFIG_ARCH_CHIP_MK20DX256VLH7)
+#if defined(KINETIS_K20)
HANDLER kinetis_dmach0, KINETIS_IRQ_DMACH0 /* Vector 16: DMA channel 0 transfer complete */
HANDLER kinetis_dmach1, KINETIS_IRQ_DMACH1 /* Vector 17: DMA channel 1 transfer complete */
@@ -585,9 +677,7 @@ handlers:
* K40P144M100SF2RM
*/
-#elif defined(CONFIG_ARCH_CHIP_MK40X128VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X128VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK40X256VLQ100) || defined(CONFIG_ARCH_CHIP_MK40X256VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK40N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK40N512VMD100)
+#elif defined(KINETIS_K40)
HANDLER kinetis_dmach0, KINETIS_IRQ_DMACH0 /* Vector 16: DMA channel 0 transfer complete */
HANDLER kinetis_dmach1, KINETIS_IRQ_DMACH1 /* Vector 17: DMA channel 1 transfer complete */
@@ -679,10 +769,7 @@ handlers:
* K60P144M100SF2RM
*/
-#elif defined(CONFIG_ARCH_CHIP_MK60N256VLQ100) || defined(CONFIG_ARCH_CHIP_MK60X256VLQ100) || \
- defined(CONFIG_ARCH_CHIP_MK60N512VLQ100) || defined(CONFIG_ARCH_CHIP_MK60N256VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK60X256VMD100) || defined(CONFIG_ARCH_CHIP_MK60N512VMD100) || \
- defined(CONFIG_ARCH_CHIP_MK60N512VLL100)
+#elif defined(KINETIS_K60)
HANDLER kinetis_dmach0, KINETIS_IRQ_DMACH0 /* Vector 16: DMA channel 0 transfer complete */
HANDLER kinetis_dmach1, KINETIS_IRQ_DMACH1 /* Vector 17: DMA channel 1 transfer complete */
@@ -771,6 +858,99 @@ handlers:
HANDLER kinetis_portd, KINETIS_IRQ_PORTD /* Vector 106: Pin detect port D */
HANDLER kinetis_porte, KINETIS_IRQ_PORTE /* Vector 107: Pin detect port E */
+/* K64 Family ***********************************************************************************
+ *
+ * The memory map for the following parts is defined in Freescale document
+ * MK64FX512VLL12
+ */
+
+#elif defined(KINETIS_K64)
+
+ HANDLER kinetis_dmach0, KINETIS_IRQ_DMACH0 /* Vector 16: DMA channel 0 transfer complete */
+ HANDLER kinetis_dmach1, KINETIS_IRQ_DMACH1 /* Vector 17: DMA channel 1 transfer complete */
+ HANDLER kinetis_dmach2, KINETIS_IRQ_DMACH2 /* Vector 18: DMA channel 2 transfer complete */
+ HANDLER kinetis_dmach3, KINETIS_IRQ_DMACH3 /* Vector 19: DMA channel 3 transfer complete */
+ HANDLER kinetis_dmach4, KINETIS_IRQ_DMACH4 /* Vector 20: DMA channel 4 transfer complete */
+ HANDLER kinetis_dmach5, KINETIS_IRQ_DMACH5 /* Vector 21: DMA channel 5 transfer complete */
+ HANDLER kinetis_dmach6, KINETIS_IRQ_DMACH6 /* Vector 22: DMA channel 6 transfer complete */
+ HANDLER kinetis_dmach7, KINETIS_IRQ_DMACH7 /* Vector 23: DMA channel 7 transfer complete */
+ HANDLER kinetis_dmach8, KINETIS_IRQ_DMACH8 /* Vector 24: DMA channel 8 transfer complete */
+ HANDLER kinetis_dmach9, KINETIS_IRQ_DMACH9 /* Vector 25: DMA channel 9 transfer complete */
+ HANDLER kinetis_dmach10, KINETIS_IRQ_DMACH10 /* Vector 26: DMA channel 10 transfer complete */
+ HANDLER kinetis_dmach11, KINETIS_IRQ_DMACH11 /* Vector 27: DMA channel 11 transfer complete */
+ HANDLER kinetis_dmach12, KINETIS_IRQ_DMACH12 /* Vector 28: DMA channel 12 transfer complete */
+ HANDLER kinetis_dmach13, KINETIS_IRQ_DMACH13 /* Vector 29: DMA channel 13 transfer complete */
+ HANDLER kinetis_dmach14, KINETIS_IRQ_DMACH14 /* Vector 30: DMA channel 14 transfer complete */
+ HANDLER kinetis_dmach15, KINETIS_IRQ_DMACH15 /* Vector 31: DMA channel 15 transfer complete */
+ HANDLER kinetis_dmaerr, KINETIS_IRQ_DMAERR /* Vector 32: DMA error interrupt channels 0-15 */
+ HANDLER kinetis_mcm, KINETIS_IRQ_MCM /* Vector 33: MCM Normal interrupt */
+ HANDLER kinetis_flashcc, KINETIS_IRQ_FLASHCC /* Vector 34: Flash memory command complete */
+ HANDLER kinetis_flashrc, KINETIS_IRQ_FLASHRC /* Vector 35: Flash memory read collision */
+ HANDLER kinetis_smclvd, KINETIS_IRQ_SMCLVD /* Vector 36: Mode Controller low-voltage detect, low-voltage warning */
+ HANDLER kinetis_llwu, KINETIS_IRQ_LLWU /* Vector 37: LLWU Normal Low Leakage Wakeup */
+ HANDLER kinetis_wdog, KINETIS_IRQ_WDOG /* Vector 38: Watchdog */
+ HANDLER kinetis_rngb, KINETIS_IRQ_RNGB /* Vector 39: Random number generator */
+ HANDLER kinetis_i2c0, KINETIS_IRQ_I2C0 /* Vector 40: I2C0 */
+ HANDLER kinetis_i2c1, KINETIS_IRQ_I2C1 /* Vector 41: I2C1 */
+ HANDLER kinetis_spi0, KINETIS_IRQ_SPI0 /* Vector 42: SPI0 all sources */
+ HANDLER kinetis_spi1, KINETIS_IRQ_SPI1 /* Vector 43: SPI1 all sources */
+ HANDLER kinetis_i2s0, KINETIS_IRQ_I2S0 /* Vector 44: Transmit */
+ HANDLER kinetis_i2s1, KINETIS_IRQ_I2S1 /* Vector 45: Transmit */
+ HANDLER kinetis_uart0s, KINETIS_IRQ_UART0S /* Vector 47: UART0 status */
+ HANDLER kinetis_uart0e, KINETIS_IRQ_UART0E /* Vector 48: UART0 error */
+ HANDLER kinetis_uart1s, KINETIS_IRQ_UART1S /* Vector 49: UART1 status */
+ HANDLER kinetis_uart1e, KINETIS_IRQ_UART1E /* Vector 50: UART1 error */
+ HANDLER kinetis_uart2s, KINETIS_IRQ_UART2S /* Vector 51: UART2 status */
+ HANDLER kinetis_uart2e, KINETIS_IRQ_UART2E /* Vector 52: UART2 error */
+ HANDLER kinetis_uart3s, KINETIS_IRQ_UART3S /* Vector 53: UART3 status */
+ HANDLER kinetis_uart3e, KINETIS_IRQ_UART3E /* Vector 54: UART3 error */
+ HANDLER kinetis_adc0, KINETIS_IRQ_ADC0 /* Vector 55: ADC0 */
+ HANDLER kinetis_cmp0, KINETIS_IRQ_CMP0 /* Vector 56: CMP0 */
+ HANDLER kinetis_cmp1, KINETIS_IRQ_CMP1 /* Vector 57: CMP1 */
+ HANDLER kinetis_ftm0, KINETIS_IRQ_FTM0 /* Vector 58: FTM0 all sources */
+ HANDLER kinetis_ftm1, KINETIS_IRQ_FTM1 /* Vector 59: FTM1 all sources */
+ HANDLER kinetis_ftm2, KINETIS_IRQ_FTM2 /* Vector 60: FTM2 all sources */
+ HANDLER kinetis_cmt, KINETIS_IRQ_CMT /* Vector 61: CMT */
+ HANDLER kinetis_rtc0, KINETIS_IRQ_RTC0 /* Vector 62: RTC alarm interrupt */
+ HANDLER kinetis_rtc1, KINETIS_IRQ_RTC1 /* Vector 63: RTC seconds interrupt */
+ HANDLER kinetis_pitch0, KINETIS_IRQ_PITCH0 /* Vector 64: PIT channel 0 */
+ HANDLER kinetis_pitch1, KINETIS_IRQ_PITCH1 /* Vector 65: PIT channel 1 */
+ HANDLER kinetis_pitch2, KINETIS_IRQ_PITCH2 /* Vector 66: PIT channel 2 */
+ HANDLER kinetis_pitch3, KINETIS_IRQ_PITCH3 /* Vector 67: PIT channel 3 */
+ HANDLER kinetis_pdb, KINETIS_IRQ_PDB /* Vector 68: PDB */
+ HANDLER kinetis_usbotg, KINETIS_IRQ_USBOTG /* Vector 68: USB OTG */
+ HANDLER kinetis_usbcd, KINETIS_IRQ_USBCD /* Vector 70: USB charger detect */
+ HANDLER kinetis_dac0, KINETIS_IRQ_DAC0 /* Vector 72: DAC0 */
+ HANDLER kinetis_mcg, KINETIS_IRQ_MCG /* Vector 73: MCG */
+ HANDLER kinetis_lpt, KINETIS_IRQ_LPT /* Vector 74: Low power timer */
+ HANDLER kinetis_porta, KINETIS_IRQ_PORTA /* Vector 75: Pin detect port A */
+ HANDLER kinetis_portb, KINETIS_IRQ_PORTB /* Vector 76: Pin detect port B */
+ HANDLER kinetis_portc, KINETIS_IRQ_PORTC /* Vector 77: Pin detect port C */
+ HANDLER kinetis_portd, KINETIS_IRQ_PORTD /* Vector 78: Pin detect port D */
+ HANDLER kinetis_porte, KINETIS_IRQ_PORTE /* Vector 79: Pin detect port E */
+ HANDLER kinetis_software, KINETIS_IRQ_SOFTWARE /* Vector 80: Software interrupt */
+ HANDLER kinetis_spi2, KINETIS_IRQ_SPI2 /* Vector 81: SPI2 all sources */
+ HANDLER kinetis_uart4s, KINETIS_IRQ_UART4S /* Vector 82: UART4 status */
+ HANDLER kinetis_uart4e, KINETIS_IRQ_UART4E /* Vector 83: UART4 error */
+ HANDLER kinetis_uart5s, KINETIS_IRQ_UART5S /* Vector 84: UART5 status */
+ HANDLER kinetis_uart5e, KINETIS_IRQ_UART5E /* Vector 85: UART5 error */
+ HANDLER kinetis_cmp2, KINETIS_IRQ_CMP2 /* Vector 86: CMP2 */
+ HANDLER kinetis_ftm3, KINETIS_IRQ_FTM3 /* Vector 87: FTM3 all sources */
+ HANDLER kinetis_dac1, KINETIS_IRQ_DAC1 /* Vector 88: DAC1 */
+ HANDLER kinetis_adc1, KINETIS_IRQ_ADC1 /* Vector 89: ADC1 */
+ HANDLER kinetis_i2c2, KINETIS_IRQ_I2C2 /* Vector 90: I2C2 */
+ HANDLER kinetis_can0mb, KINETIS_IRQ_CAN0MB /* Vector 91: CAN0 ORed Message buffer (0-15) */
+ HANDLER kinetis_can0bo, KINETIS_IRQ_CAN0BO /* Vector 92: CAN0 Bus Off */
+ HANDLER kinetis_can0err, KINETIS_IRQ_CAN0ERR /* Vector 93: CAN0 Error */
+ HANDLER kinetis_can0tw, KINETIS_IRQ_CAN0TW /* Vector 94: CAN0 Transmit Warning */
+ HANDLER kinetis_can0rw, KINETIS_IRQ_CAN0RW /* Vector 95: CAN0 Receive Warning */
+ HANDLER kinetis_can0wu, KINETIS_IRQ_CAN0WU /* Vector 96: CAN0 Wake UP */
+ HANDLER kinetis_sdhc, KINETIS_IRQ_SDHC /* Vector 97: SDHC */
+ HANDLER kinetis_emactmr, KINETIS_IRQ_EMACTMR /* Vector 91: Ethernet MAC IEEE 1588 timer interrupt */
+ HANDLER kinetis_emactx, KINETIS_IRQ_EMACTX /* Vector 92: Ethernet MAC transmit interrupt */
+ HANDLER kinetis_emacrx, KINETIS_IRQ_EMACRX /* Vector 93: Ethernet MAC receive interrupt */
+ HANDLER kinetis_emacmisc, KINETIS_IRQ_EMACMISC /* Vector 94: Ethernet MAC error and misc interrupt */
+
#else
# error "No handlers for this Kinetis part"
#endif
diff --git a/arch/arm/src/kinetis/kinetis_wdog.c b/arch/arm/src/kinetis/kinetis_wdog.c
index 9dc29b80d8963576c400758580b4fa4edecb5945..3beaad8d4bce5d1e0db6153578fe1d9290903f67 100644
--- a/arch/arm/src/kinetis/kinetis_wdog.c
+++ b/arch/arm/src/kinetis/kinetis_wdog.c
@@ -1,6 +1,5 @@
/****************************************************************************
* arch/arm/src/kinetis/kinetis_wdog.c
- * arch/arm/src/chip/kinetis_wdog.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -44,19 +43,7 @@
#include "up_arch.h"
#include "kinetis.h"
-#include "kinetis_wdog.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
+#include "chip/kinetis_wdog.h"
/****************************************************************************
* Private Functions
diff --git a/arch/arm/src/lpc43xx/lpc43_ethernet.c b/arch/arm/src/lpc43xx/lpc43_ethernet.c
index db05295ec07ca18b38d07784e3369d580c3434df..086dd0b8f3eb54f44359d0323b82e6506e2756a9 100644
--- a/arch/arm/src/lpc43xx/lpc43_ethernet.c
+++ b/arch/arm/src/lpc43xx/lpc43_ethernet.c
@@ -3392,6 +3392,9 @@ static int lpc43_phyinit(FAR struct lpc43_ethmac_s *priv)
priv->mbps100 = 1;
}
#endif
+#endif
+
+#else /* Auto-negotion not selected */
#ifdef CONFIG_LPC43_ETHFD
priv->mbps100 = 1;
@@ -3399,12 +3402,10 @@ static int lpc43_phyinit(FAR struct lpc43_ethmac_s *priv)
#ifdef CONFIG_LPC43_ETH100MBPS
priv->fduplex = 1;
-#endif
#endif
- /* However we got here, commit to the hardware */
-
phyval = 0;
+
if (priv->mbps100)
{
phyval |= MII_MCR_FULLDPLX;
diff --git a/arch/arm/src/lpc43xx/lpc43_irq.c b/arch/arm/src/lpc43xx/lpc43_irq.c
index 345f63b5c24eb8f639da0c47e9dfe3ed04f1a5d4..26881472c8d15ec3395fdc454f9a391d2bca1b2c 100644
--- a/arch/arm/src/lpc43xx/lpc43_irq.c
+++ b/arch/arm/src/lpc43xx/lpc43_irq.c
@@ -242,53 +242,23 @@ static inline void lpc43_prioritize_syscall(int priority)
static int lpc43_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit,
uintptr_t offset)
{
+ int n;
+
DEBUGASSERT(irq >= LPC43_IRQ_NMI && irq < NR_IRQS);
/* Check for external interrupt */
if (irq >= LPC43_IRQ_EXTINT)
{
- /* NOTE: We assume that there are at least 32 interrupts */
-
- if (irq < (LPC43_IRQ_EXTINT + 32))
- {
- /* Interrupt in range {0-31} */
-
- *regaddr = (NVIC_IRQ0_31_ENABLE + offset);
- *bit = 1 << (irq - LPC43_IRQ_EXTINT);
- }
-#if LPC43M4_IRQ_NEXTINT > 95
-# error Extension to interrupt logic needed
-#elif LPC43M4_IRQ_NEXTINT > 63
- else if (irq < (LPC43_IRQ_EXTINT + 64))
- {
- /* Interrupt in range {32-63} */
+ n = irq - LPC43_IRQ_EXTINT;
+ *regaddr = NVIC_IRQ_ENABLE(n) + offset;
- *regaddr = (NVIC_IRQ32_63_ENABLE + offset);
- *bit = 1 << (irq - LPC43_IRQ_EXTINT - 32);
- }
- else if (irq < LPC43M4_IRQ_NIRQS)
+ while (n >= 32)
{
- /* Interrupt in range {64-LPC43M4_IRQ_NIRQS}, LPC43M4_IRQ_NIRQS <= 95 */
-
- *regaddr = (NVIC_IRQ64_95_ENABLE + offset);
- *bit = 1 << (irq - LPC43_IRQ_EXTINT - 64);
+ n -= 32;
}
-#else /* if LPC43M4_IRQ_NEXTINT > 31 */
- else if (irq < LPC43M4_IRQ_NIRQS)
- {
- /* Interrupt in range {32-LPC43M4_IRQ_NIRQS}, LPC43M4_IRQ_NIRQS <= 63 */
- *regaddr = (NVIC_IRQ32_63_ENABLE + offset);
- *bit = 1 << (irq - LPC43_IRQ_EXTINT - 32);
- }
-#endif
- else
- {
- /* Interrupt >= LPC43M4_IRQ_NIRQS */
-
- return ERROR; /* Invalid interrupt */
- }
+ *bit = 1 << n;
}
/* Handle processor exceptions. Only a few can be disabled */
@@ -342,16 +312,14 @@ void up_irqinitialize(void)
uint32_t regval;
#endif
int num_priority_registers;
+ int i;
/* Disable all interrupts */
- putreg32(0, NVIC_IRQ0_31_ENABLE);
-#if LPC43M4_IRQ_NEXTINT > 31
- putreg32(0, NVIC_IRQ32_63_ENABLE);
-#if LPC43M4_IRQ_NEXTINT > 63
- putreg32(0, NVIC_IRQ64_95_ENABLE);
-#endif
-#endif
+ for (i = 0; i < LPC43M4_IRQ_NEXTINT; i += 32)
+ {
+ putreg32(0xffffffff, NVIC_IRQ_CLEAR(i));
+ }
/* Make sure that we are using the correct vector table. The default
* vector address is 0x0000:0000 but if we are executing code that is
diff --git a/arch/arm/src/sam34/chip/sam_dacc.h b/arch/arm/src/sam34/chip/sam_dacc.h
index 4581289edae6b27b4a6f78da6a3868b6718fbf4f..80a61d874a7a20d37ca6ec65aef0813165f8b0eb 100644
--- a/arch/arm/src/sam34/chip/sam_dacc.h
+++ b/arch/arm/src/sam34/chip/sam_dacc.h
@@ -209,7 +209,7 @@
#define DACC_WPMR_WPEN (1 << 0) /* Bit 0: Write Protect Enable */
#define DACC_WPMR_WPKEY_SHIFT (8) /* Bits 8-31: Write Protect KEY */
#define DACC_WPMR_WPKEY_MASK (0x00ffffff << DACC_WPMR_WPKEY_SHIFT)
-# define DACC_WPMR_WPKEY_MASK (0x00444143 << DACC_WPMR_WPKEY_SHIFT)
+# define DACC_WPMR_WPKEY (0x00444143 << DACC_WPMR_WPKEY_SHIFT)
/* Write Protect Status register */
diff --git a/arch/arm/src/sam34/sam_twi.c b/arch/arm/src/sam34/sam_twi.c
index 6e4aae14271885d3f60bc02d3dfbfb9ba829e79d..74d0e7d6ed337277c2c0a6791a96fed794bced95 100644
--- a/arch/arm/src/sam34/sam_twi.c
+++ b/arch/arm/src/sam34/sam_twi.c
@@ -666,7 +666,7 @@ static void twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg)
static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg)
{
- if ((msg->flags & I2C_M_READ) == 0)
+ if ((msg->flags & I2C_M_READ) != 0)
{
twi_startread(priv, msg);
}
diff --git a/arch/arm/src/samv7/Kconfig b/arch/arm/src/samv7/Kconfig
index 55eb92d485db39acded624b749de51ca94a0131c..9507e0c59c842e4897254f332795f2124e8edb14 100644
--- a/arch/arm/src/samv7/Kconfig
+++ b/arch/arm/src/samv7/Kconfig
@@ -957,16 +957,85 @@ config SAMV7_TWIHS0_FREQUENCY
default 100000
depends on SAMV7_TWIHS0
+config SAMV7_TWIHS0_GLITCH_FILTER
+ int "TWIHS0 Glitch Filter Time"
+ default 1
+ range 0 7
+ depends on SAMV7_TWIHS0
+ ---help---
+ Apply filtering on TWIHS Inputs. Given number is the maximum pulse width
+ (defined in peripheral CLKs) of spikes to be suppressed by the input filter.
+ Setting this value to zero will disable glitch filtering.
+
+config SAMV7_TWIHS0_SINGLE_MASTER
+ bool "TWIHS0 Single Master Mode"
+ default y
+ depends on SAMV7_TWIHS0
+ depends on I2C_RESET
+ ---help---
+ Enables a mode, where errors on the I2C-Bus (e.g. by EMC or
+ stuck slaves) are automatically handled by the driver.
+ In an error-case the I2C-Bus is reset so further communication
+ on the bus can take place.
+ This option is default on because the TWI-Driver can't handle
+ Multi-Master I2C anyways.
+
config SAMV7_TWIHS1_FREQUENCY
int "TWIHS1 Frequency"
default 100000
depends on SAMV7_TWIHS1
+config SAMV7_TWIHS1_GLITCH_FILTER
+ int "TWIHS1 Glitch Filter Time"
+ default 1
+ range 0 7
+ depends on SAMV7_TWIHS1
+ ---help---
+ Apply filtering on TWIHS Inputs. Given number is the maximum pulse width
+ (defined in peripheral CLKs) of spikes to be suppressed by the input filter.
+ Setting this value to zero will disable glitch filtering.
+
+config SAMV7_TWIHS1_SINGLE_MASTER
+ bool "TWIHS1 Single Master Mode"
+ default y
+ depends on SAMV7_TWIHS1
+ depends on I2C_RESET
+ ---help---
+ Enables a mode, where errors on the I2C-Bus (e.g. by EMC or
+ stuck slaves) are automatically handled by the driver.
+ In an error-case the I2C-Bus is reset so further communication
+ on the bus can take place.
+ This option is default on because the TWI-Driver can't handle
+ Multi-Master I2C anyways.
+
config SAMV7_TWIHS2_FREQUENCY
int "TWIHS2 Frequency"
default 100000
depends on SAMV7_TWIHS2
+config SAMV7_TWIHS2_GLITCH_FILTER
+ int "TWIHS2 Glitch Filter Time"
+ default 1
+ range 0 7
+ depends on SAMV7_TWIHS2
+ ---help---
+ Apply filtering on TWIHS Inputs. Given number is the maximum pulse width
+ (defined in peripheral CLKs) of spikes to be suppressed by the input filter.
+ Setting this value to zero will disable glitch filtering.
+
+config SAMV7_TWIHS2_SINGLE_MASTER
+ bool "TWIHS2 Single Master Mode"
+ default y
+ depends on SAMV7_TWIHS2
+ depends on I2C_RESET
+ ---help---
+ Enables a mode, where errors on the I2C-Bus (e.g. by EMC or
+ stuck slaves) are automatically handled by the driver.
+ In an error-case the I2C-Bus is reset so further communication
+ on the bus can take place.
+ This option is default on because the TWI-Driver can't handle
+ Multi-Master I2C anyways.
+
config SAMV7_TWIHS_REGDEBUG
bool "TWIHS register level debug"
depends on DEBUG_I2C_INFO
diff --git a/arch/arm/src/samv7/chip/sam_mcan.h b/arch/arm/src/samv7/chip/sam_mcan.h
index b3951aef703890ae6597eb7e2ac15516e15c774d..4212ca3c291d7877a2003488c401bbcd9e514130 100644
--- a/arch/arm/src/samv7/chip/sam_mcan.h
+++ b/arch/arm/src/samv7/chip/sam_mcan.h
@@ -747,7 +747,7 @@
#define STDFILTER_S0_SFID1_SHIFT (16) /* Bits 16-26: Standard Filter ID 2 */
#define STDFILTER_S0_SFID1_MASK (0x3ff << STDFILTER_S0_SFID1_SHIFT)
# define STDFILTER_S0_SFID1(n) ((uint32_t)(n) << STDFILTER_S0_SFID1_SHIFT)
-#define STDFILTER_S0_SFEC_SHIFT (17) /* Bits 27-29: Standard Filter Element Configuration */
+#define STDFILTER_S0_SFEC_SHIFT (27) /* Bits 27-29: Standard Filter Element Configuration */
#define STDFILTER_S0_SFEC_MASK (7 << STDFILTER_S0_SFEC_SHIFT)
# define STDFILTER_S0_SFEC_DISABLE (0 << STDFILTER_S0_SFEC_SHIFT) /* Disable filter element */
# define STDFILTER_S0_SFEC_FIFO0 (1 << STDFILTER_S0_SFEC_SHIFT) /* Store in Rx FIFO 0 on match */
diff --git a/arch/arm/src/samv7/sam_gpio.c b/arch/arm/src/samv7/sam_gpio.c
index 9b322f8381445a8a8ebcde81ed2dc7f5adbe9e8e..cf681e766207c252f92d0e5969b5d275ebf3d3a3 100644
--- a/arch/arm/src/samv7/sam_gpio.c
+++ b/arch/arm/src/samv7/sam_gpio.c
@@ -543,15 +543,11 @@ bool sam_gpioread(gpio_pinset_t pinset)
uint32_t pin = sam_gpio_pinmask(pinset);
uint32_t regval;
- if ((pinset & GPIO_MODE_MASK) == GPIO_OUTPUT)
- {
- regval = getreg32(base + SAM_PIO_ODSR_OFFSET);
- }
- else
- {
- regval = getreg32(base + SAM_PIO_PDSR_OFFSET);
- }
+ /* Always read the Pin Data Status Register. Otherwise an Open-Drain
+ * Output pin will not be read back correctly.
+ */
+ regval = getreg32(base + SAM_PIO_PDSR_OFFSET);
return (regval & pin) != 0;
}
diff --git a/arch/arm/src/samv7/sam_mcan.c b/arch/arm/src/samv7/sam_mcan.c
index 2091390cab257f0bdd125995525bd9da35316e72..748b01b10b3545e22edea228cd2c1cf12bcb0393 100644
--- a/arch/arm/src/samv7/sam_mcan.c
+++ b/arch/arm/src/samv7/sam_mcan.c
@@ -802,6 +802,7 @@
/****************************************************************************
* Private Types
****************************************************************************/
+
/* CAN mode of operation */
enum sam_canmode_e
@@ -1833,6 +1834,22 @@ static int mcan_add_extfilter(FAR struct sam_mcan_s *priv,
if (priv->nextalloc == 1)
{
+ /* Enable the Initialization state */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval |= MCAN_CCCR_INIT;
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
+ /* Wait for initialization mode to take effect */
+
+ while ((mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET) & MCAN_CCCR_INIT) == 0);
+
+ /* Enable writing to configuration registers */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval |= (MCAN_CCCR_INIT | MCAN_CCCR_CCE);
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
/* Update the Global Filter Configuration so that received
* messages are rejected if they do not match the acceptance
* filter.
@@ -1844,6 +1861,12 @@ static int mcan_add_extfilter(FAR struct sam_mcan_s *priv,
regval &= ~MCAN_GFC_ANFE_MASK;
regval |= MCAN_GFC_ANFE_REJECTED;
mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval);
+
+ /* Disable writing to configuration registers */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval &= ~(MCAN_CCCR_INIT | MCAN_CCCR_CCE);
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
}
mcan_dev_unlock(priv);
@@ -1903,6 +1926,22 @@ static int mcan_del_extfilter(FAR struct sam_mcan_s *priv, int ndx)
if (priv->nextalloc == 0)
{
+ /* Enable the Initialization state */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval |= MCAN_CCCR_INIT;
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
+ /* Wait for initialization mode to take effect */
+
+ while ((mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET) & MCAN_CCCR_INIT) == 0);
+
+ /* Enable writing to configuration registers */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval |= (MCAN_CCCR_INIT | MCAN_CCCR_CCE);
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
/* If there are no extended filters, then modify Global Filter
* Configuration so that all rejected messages are places in RX
* FIFO0.
@@ -1914,6 +1953,12 @@ static int mcan_del_extfilter(FAR struct sam_mcan_s *priv, int ndx)
regval &= ~MCAN_GFC_ANFE_MASK;
regval |= MCAN_GFC_ANFE_RX_FIFO0;
mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval);
+
+ /* Disable writing to configuration registers */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval &= ~(MCAN_CCCR_INIT | MCAN_CCCR_CCE);
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
}
/* Deactivate the filter last so that no messages are lost. */
@@ -2021,6 +2066,22 @@ static int mcan_add_stdfilter(FAR struct sam_mcan_s *priv,
if (priv->nstdalloc == 1)
{
+ /* Enable the Initialization state */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval |= MCAN_CCCR_INIT;
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
+ /* Wait for initialization mode to take effect */
+
+ while ((mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET) & MCAN_CCCR_INIT) == 0);
+
+ /* Enable writing to configuration registers */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval |= (MCAN_CCCR_INIT | MCAN_CCCR_CCE);
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
/* Update the Global Filter Configuration so that received
* messages are rejected if they do not match the acceptance
* filter.
@@ -2032,6 +2093,12 @@ static int mcan_add_stdfilter(FAR struct sam_mcan_s *priv,
regval &= ~MCAN_GFC_ANFS_MASK;
regval |= MCAN_GFC_ANFS_REJECTED;
mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval);
+
+ /* Disable writing to configuration registers */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval &= ~(MCAN_CCCR_INIT | MCAN_CCCR_CCE);
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
}
mcan_dev_unlock(priv);
@@ -2089,6 +2156,22 @@ static int mcan_del_stdfilter(FAR struct sam_mcan_s *priv, int ndx)
if (priv->nstdalloc == 0)
{
+ /* Enable the Initialization state */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval |= MCAN_CCCR_INIT;
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
+ /* Wait for initialization mode to take effect */
+
+ while ((mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET) & MCAN_CCCR_INIT) == 0);
+
+ /* Enable writing to configuration registers */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval |= (MCAN_CCCR_INIT | MCAN_CCCR_CCE);
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
/* If there are no standard filters, then modify Global Filter
* Configuration so that all rejected messages are places in RX
* FIFO0.
@@ -2100,6 +2183,12 @@ static int mcan_del_stdfilter(FAR struct sam_mcan_s *priv, int ndx)
regval &= ~MCAN_GFC_ANFS_MASK;
regval |= MCAN_GFC_ANFS_RX_FIFO0;
mcan_putreg(priv, SAM_MCAN_GFC_OFFSET, regval);
+
+ /* Disable writing to configuration registers */
+
+ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+ regval &= ~(MCAN_CCCR_INIT | MCAN_CCCR_CCE);
+ mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
}
/* Deactivate the filter last so that no messages are lost. */
diff --git a/arch/arm/src/samv7/sam_twihs.c b/arch/arm/src/samv7/sam_twihs.c
index 6a0de18ef4d7df03708ed9d06fa7e903e1231ebf..6800ecbba89dc0d9f5c00c03ed97199152a4233a 100644
--- a/arch/arm/src/samv7/sam_twihs.c
+++ b/arch/arm/src/samv7/sam_twihs.c
@@ -116,13 +116,13 @@
#define TWIHS_MAX_FREQUENCY 66000000 /* Maximum TWIHS frequency */
-/* Macros to convert a I2C pin to a PIO open-drain output */
+/* Macros to convert a I2C pin to a GPIO open-drain output */
-#define I2C_INPUT (PIO_INPUT | PIO_CFG_PULLUP)
-#define I2C_OUTPUT (PIO_OUTPUT | PIO_CFG_OPENDRAIN | PIO_OUTPUT_SET)
+#define I2C_INPUT (GPIO_INPUT | GPIO_CFG_PULLUP)
+#define I2C_OUTPUT (GPIO_OUTPUT | GPIO_CFG_OPENDRAIN | GPIO_OUTPUT_SET)
-#define MKI2C_INPUT(p) (((p) & (PIO_PORT_MASK | PIO_PIN_MASK)) | I2C_INPUT)
-#define MKI2C_OUTPUT(p) (((p) & (PIO_PORT_MASK | PIO_PIN_MASK)) | I2C_OUTPUT)
+#define MKI2C_INPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_INPUT)
+#define MKI2C_OUTPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT)
/****************************************************************************
* Private Types
@@ -133,6 +133,8 @@ struct twi_attr_s
{
uint8_t twi; /* TWIHS device number (for debug output) */
uint8_t pid; /* TWIHS peripheral ID */
+ uint8_t glitchfltr; /* Pulse width of a glich to be suppressed by the filter */
+ bool s_master; /* true: Single-Master Mode active */
uint16_t irq; /* IRQ number for this TWIHS bus */
gpio_pinset_t sclcfg; /* TWIHS CK pin configuration (SCL in I2C-ese) */
gpio_pinset_t sdacfg; /* TWIHS D pin configuration (SDA in I2C-ese) */
@@ -219,6 +221,7 @@ static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg);
static int twi_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
+static int twi_reset_internal(FAR struct i2c_master_s *dev);
static int twi_reset(FAR struct i2c_master_s * dev);
#endif
@@ -234,13 +237,19 @@ static void twi_hw_initialize(struct twi_dev_s *priv, uint32_t frequency);
#ifdef CONFIG_SAMV7_TWIHS0
static const struct twi_attr_s g_twi0attr =
{
- .twi = 0,
- .pid = SAM_PID_TWIHS0,
- .irq = SAM_IRQ_TWIHS0,
- .sclcfg = GPIO_TWIHS0_CK,
- .sdacfg = GPIO_TWIHS0_D,
- .base = SAM_TWIHS0_BASE,
- .handler = twi0_interrupt,
+ .twi = 0,
+ .pid = SAM_PID_TWIHS0,
+ .irq = SAM_IRQ_TWIHS0,
+ .glitchfltr = CONFIG_SAMV7_TWIHS0_GLITCH_FILTER,
+#ifdef CONFIG_SAMV7_TWIHS0_SINGLE_MASTER
+ .s_master = true,
+#else
+ .s_master = false,
+#endif
+ .sclcfg = GPIO_TWIHS0_CK,
+ .sdacfg = GPIO_TWIHS0_D,
+ .base = SAM_TWIHS0_BASE,
+ .handler = twi0_interrupt,
};
static struct twi_dev_s g_twi0;
@@ -249,13 +258,19 @@ static struct twi_dev_s g_twi0;
#ifdef CONFIG_SAMV7_TWIHS1
static const struct twi_attr_s g_twi1attr =
{
- .twi = 1,
- .pid = SAM_PID_TWIHS1,
- .irq = SAM_IRQ_TWIHS1,
- .sclcfg = GPIO_TWIHS1_CK,
- .sdacfg = GPIO_TWIHS1_D,
- .base = SAM_TWIHS1_BASE,
- .handler = twi1_interrupt,
+ .twi = 1,
+ .pid = SAM_PID_TWIHS1,
+ .irq = SAM_IRQ_TWIHS1,
+ .glitchfltr = CONFIG_SAMV7_TWIHS1_GLITCH_FILTER,
+#ifdef CONFIG_SAMV7_TWIHS1_SINGLE_MASTER
+ .s_master = true,
+#else
+ .s_master = false,
+#endif
+ .sclcfg = GPIO_TWIHS1_CK,
+ .sdacfg = GPIO_TWIHS1_D,
+ .base = SAM_TWIHS1_BASE,
+ .handler = twi1_interrupt,
};
static struct twi_dev_s g_twi1;
@@ -264,13 +279,19 @@ static struct twi_dev_s g_twi1;
#ifdef CONFIG_SAMV7_TWIHS2
static const struct twi_attr_s g_twi2attr =
{
- .twi = 2,
- .pid = SAM_PID_TWIHS2,
- .irq = SAM_IRQ_TWIHS2,
- .sclcfg = GPIO_TWIHS2_CK,
- .sdacfg = GPIO_TWIHS2_D,
- .base = SAM_TWIHS2_BASE,
- .handler = twi2_interrupt,
+ .twi = 2,
+ .pid = SAM_PID_TWIHS2,
+ .irq = SAM_IRQ_TWIHS2,
+ .glitchfltr = CONFIG_SAMV7_TWIHS2_GLITCH_FILTER,
+#ifdef CONFIG_SAMV7_TWIHS2_SINGLE_MASTER
+ .s_master = true,
+#else
+ .s_master = false,
+#endif
+ .sclcfg = GPIO_TWIHS2_CK,
+ .sdacfg = GPIO_TWIHS2_D,
+ .base = SAM_TWIHS2_BASE,
+ .handler = twi2_interrupt,
};
static struct twi_dev_s g_twi2;
@@ -278,9 +299,9 @@ static struct twi_dev_s g_twi2;
static const struct i2c_ops_s g_twiops =
{
- .transfer = twi_transfer
+ .transfer = twi_transfer
#ifdef CONFIG_I2C_RESET
- , .reset = twi_reset
+ , .reset = twi_reset
#endif
};
@@ -312,7 +333,7 @@ static void twi_takesem(sem_t *sem)
* awakened by a signal.
*/
- ASSERT(errno == EINTR);
+ DEBUGASSERT(errno == EINTR);
}
}
@@ -494,6 +515,26 @@ static int twi_wait(struct twi_dev_s *priv, unsigned int size)
* all further interrupts for the TWIHS have been disabled.
*/
+#ifdef CONFIG_I2C_RESET
+ /* Check if an Arbitration Lost has occured */
+
+ if (priv->result == -EUSERS)
+ {
+ /* Something bad happened on the bus so force a reset */
+
+ priv->result = twi_reset_internal(&priv->dev);
+
+ /* Although the reset was successful tell the higher driver that it's
+ * transfer has failed and should be repeated.
+ */
+
+ if (priv->result == OK)
+ {
+ priv->result = -EIO;
+ }
+ }
+#endif
+
return priv->result;
}
@@ -607,6 +648,22 @@ static int twi_interrupt(struct twi_dev_s *priv)
}
}
+#ifdef CONFIG_I2C_RESET
+ /* If Single-Master Mode is enabled and we lost arbitration (someone else or
+ * an EMC-Pulse did something on the bus) something went very wrong. So we end
+ * the current transfer with an EUSERS. The wait function will then reset
+ * the bus so further communication can take place.
+ */
+
+ else if ((priv->attr->s_master) && ((pending & TWIHS_INT_ARBLST) != 0))
+ {
+ /* Wake up the thread with an Arbitration Lost error indication */
+
+ i2cerr("ERROR: TWIHS%d Arbitration Lost\n");
+ twi_wakeup(priv, -EUSERS);
+ }
+#endif
+
/* Check for errors. We must check for errors *before* checking TXRDY or
* TXCMP because the error can be signaled in combination with TXRDY or
* TXCOMP.
@@ -856,6 +913,9 @@ static int twi_transfer(FAR struct i2c_master_s *dev,
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
irqstate_t flags;
unsigned int size;
+#ifdef CONFIG_I2C_RESET
+ uint32_t sr;
+#endif
int i;
int ret;
@@ -891,6 +951,26 @@ static int twi_transfer(FAR struct i2c_master_s *dev,
twi_setfrequency(priv, msgs->frequency);
+#ifdef CONFIG_I2C_RESET
+ /* When we are in Single Master Mode check if the bus is ready (no stuck
+ * DATA or CLK line).
+ * Otherwise initiate a bus reset.
+ */
+
+ if (priv->attr->s_master)
+ {
+ sr = twi_getrel(priv, SAM_TWIHS_SR_OFFSET);
+ if (((sr & TWIHS_INT_SDA) == 0) || ((sr & TWIHS_INT_SCL) == 0))
+ {
+ ret = twi_reset_internal(&priv->dev);
+ if (ret != OK)
+ {
+ goto errout;
+ }
+ }
+ }
+#endif
+
/* Initiate the transfer. The rest will be handled from interrupt
* logic. Interrupts must be disabled to prevent re-entrance from the
* interrupt level.
@@ -904,46 +984,48 @@ static int twi_transfer(FAR struct i2c_master_s *dev,
*/
ret = twi_wait(priv, size);
+ leave_critical_section(flags);
+
+#ifdef CONFIG_I2C_RESET
+errout:
+#endif
if (ret < 0)
{
i2cerr("ERROR: Transfer failed: %d\n", ret);
}
- leave_critical_section(flags);
twi_givesem(&priv->exclsem);
return ret;
}
/************************************************************************************
- * Name: twi_reset
- *
- * Description:
- * Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
- *
- * Input Parameters:
- * dev - Device-specific state data
- *
- * Returned Value:
- * Zero (OK) on success; a negated errno value on failure.
- *
- ************************************************************************************/
+* Name: twi_reset_internal
+*
+* Description:
+* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
+* This function can be called from inside the driver while the TWIHS device is
+* already locked, so we must not handle any semapores inside.
+* To initiate a bus reset from outside the driver use twi_reset(dev).
+*
+* Input Parameters:
+* dev - Device-specific state data
+*
+* Returned Value:
+* Zero (OK) on success; a negated errno value on failure.
+*
+************************************************************************************/
#ifdef CONFIG_I2C_RESET
-static int twi_reset(FAR struct i2c_master_s *dev)
+static int twi_reset_internal(FAR struct i2c_master_s *dev)
{
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
unsigned int clockcnt;
unsigned int stretchcnt;
uint32_t sclpin;
uint32_t sdapin;
+ uint8_t wait_us;
int ret;
- ASSERT(priv);
-
- /* Get exclusive access to the TWIHS device */
-
- twi_takesem(&priv->exclsem);
-
/* Disable TWIHS interrupts */
up_disable_irq(priv->attr->irq);
@@ -960,28 +1042,31 @@ static int twi_reset(FAR struct i2c_master_s *dev)
sam_configgpio(sclpin);
sam_configgpio(sdapin);
- /* Peripheral clocking must be enabled in order to read valid data from
- * the output pin (clocking is enabled automatically for pins configured
- * as inputs).
- */
-
- sam_pio_forceclk(sclpin, true);
- sam_pio_forceclk(sdapin, true);
-
/* Clock the bus until any slaves currently driving it low let it float.
* Reading from the output will return the actual sensed level on the
* SDA pin (not the level that we wrote).
*/
+ /* Set the wait-time according to the TWI-Bus-Frequency */
+
+ if (priv->frequency >= 330000)
+ {
+ wait_us = 3;
+ }
+ else
+ {
+ wait_us = 10;
+ }
+
clockcnt = 0;
- while (sam_pioread(sdapin) == false)
+ while (sam_gpioread(sdapin) == false)
{
/* Give up if we have tried too hard */
if (clockcnt++ > 10)
{
ret = -ETIMEDOUT;
- goto errout_with_lock;
+ goto errout;
}
/* Sniff to make sure that clock stretching has finished. SCL should
@@ -991,55 +1076,85 @@ static int twi_reset(FAR struct i2c_master_s *dev)
*/
stretchcnt = 0;
- while (sam_pioread(sclpin) == false)
+ while (sam_gpioread(sclpin) == false)
{
/* Give up if we have tried too hard */
if (stretchcnt++ > 10)
{
ret = -EAGAIN;
- goto errout_with_lock;
+ goto errout;
}
- up_udelay(10);
+ up_udelay(wait_us);
}
/* Drive SCL low */
- sam_piowrite(sclpin, false);
- up_udelay(10);
+ sam_gpiowrite(sclpin, false);
+ up_udelay(wait_us);
/* Drive SCL high (floating) again */
- sam_piowrite(sclpin, true);
- up_udelay(10);
+ sam_gpiowrite(sclpin, true);
+ up_udelay(wait_us);
}
/* Generate a start followed by a stop to reset slave
* state machines.
*/
- sam_piowrite(sdapin, false);
- up_udelay(10);
- sam_piowrite(sclpin, false);
- up_udelay(10);
-
- sam_piowrite(sclpin, true);
- up_udelay(10);
- sam_piowrite(sdapin, true);
- up_udelay(10);
+ sam_gpiowrite(sdapin, false);
+ up_udelay(wait_us);
+ sam_gpiowrite(sclpin, false);
+ up_udelay(wait_us);
- /* Clocking is no longer forced */
-
- sam_pio_forceclk(sclpin, false);
- sam_pio_forceclk(sdapin, false);
+ sam_gpiowrite(sclpin, true);
+ up_udelay(wait_us);
+ sam_gpiowrite(sdapin, true);
+ up_udelay(wait_us);
/* Re-initialize the port hardware */
twi_hw_initialize(priv, priv->frequency);
ret = OK;
-errout_with_lock:
+errout:
+ return ret;
+}
+#endif /* CONFIG_I2C_RESET */
+
+/************************************************************************************
+ * Name: twi_reset
+ *
+ * Description:
+ * Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
+ * This function can be called from outside the driver, so lock the TWIHS Device
+ * and then let the internal reset function do the work.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_I2C_RESET
+static int twi_reset(FAR struct i2c_master_s *dev)
+{
+ struct twi_dev_s *priv = (struct twi_dev_s *)dev;
+ int ret;
+
+ DEBUGASSERT(priv != NULL);
+
+ /* Get exclusive access to the TWIHS device */
+
+ twi_takesem(&priv->exclsem);
+
+ /* Do the reset-procedure */
+
+ ret = twi_reset_internal(dev);
/* Release our lock on the bus */
@@ -1217,6 +1332,19 @@ static void twi_hw_initialize(struct twi_dev_s *priv, uint32_t frequency)
regval |= PMC_PCR_PID(priv->attr->pid) | PMC_PCR_CMD | PMC_PCR_EN;
twi_putabs(priv, SAM_PMC_PCR, regval);
+ /* Set the TWIHS Input Filters */
+
+ if (priv->attr->glitchfltr)
+ {
+ regval = TWIHS_FILTR_FILT | TWIHS_FILTR_THRES(priv->attr->glitchfltr);
+ }
+ else
+ {
+ regval = 0;
+ }
+
+ twi_putrel(priv, SAM_TWIHS_FILTR_OFFSET, regval);
+
/* Set the initial TWIHS data transfer frequency */
priv->frequency = 0;
diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig
index 4a838eb07d6a3cef477984d896e5b04f5e905cfc..932e74c81b5f34cfe1f7d721db66faffa8b2daf0 100644
--- a/arch/arm/src/stm32/Kconfig
+++ b/arch/arm/src/stm32/Kconfig
@@ -2544,6 +2544,54 @@ config STM32_FSMC_SRAM
menu "Timer Configuration"
+if SCHED_TICKLESS
+
+config STM32_ONESHOT
+ bool
+ default y
+
+config STM32_FREERUN
+ bool
+ default y
+
+endif # SCHED_TICKLESS
+
+if !SCHED_TICKLESS
+
+config STM32_ONESHOT
+ bool "TIM one-shot wrapper"
+ default n
+ ---help---
+ Enable a wrapper around the low level timer/counter functions to
+ support one-shot timer.
+
+config STM32_FREERUN
+ bool "TIM free-running wrapper"
+ default n
+ ---help---
+ Enable a wrapper around the low level timer/counter functions to
+ support a free-running timer.
+
+endif # !SCHED_TICKLESS
+
+config STM32_TICKLESS_ONESHOT
+ int "Tickless one-shot timer channel"
+ default 2
+ range 1 14
+ depends on STM32_ONESHOT
+ ---help---
+ If the Tickless OS feature is enabled, the one clock must be
+ assigned to provided the one-shot timer needed by the OS.
+
+config STM32_TICKLESS_FREERUN
+ int "Tickless free-running timer channel"
+ default 5
+ range 1 14
+ depends on STM32_FREERUN
+ ---help---
+ If the Tickless OS feature is enabled, the one clock must be
+ assigned to provided the free-running timer needed by the OS.
+
config STM32_TIM1_PWM
bool "TIM1 PWM"
default n
diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs
index 1a3355d24d446ddf1b0e7e5c0d3c096207cdc355..aef4ef081552e0ca842838d713704463cea0dd8b 100644
--- a/arch/arm/src/stm32/Make.defs
+++ b/arch/arm/src/stm32/Make.defs
@@ -120,6 +120,16 @@ endif
ifneq ($(CONFIG_SCHED_TICKLESS),y)
CHIP_CSRCS += stm32_timerisr.c
+else
+CHIP_CSRCS += stm32_tickless.c
+endif
+
+ifeq ($(CONFIG_STM32_ONESHOT),y)
+CHIP_CSRCS += stm32_oneshot.c
+endif
+
+ifeq ($(CONFIG_STM32_FREERUN),y)
+CHIP_CSRCS += stm32_freerun.c
endif
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
diff --git a/arch/arm/src/stm32/chip/stm32_can.h b/arch/arm/src/stm32/chip/stm32_can.h
index 6b4a12a855e8d442119699ee32ee9adf9581396d..c1e3500d5e68bc1217b820a5fe88435d31fe0b5a 100644
--- a/arch/arm/src/stm32/chip/stm32_can.h
+++ b/arch/arm/src/stm32/chip/stm32_can.h
@@ -360,7 +360,7 @@
#define CAN_BTR_SJW_SHIFT (24) /* Bits 25-24: Resynchronization Jump Width */
#define CAN_BTR_SJW_MASK (3 << CAN_BTR_SJW_SHIFT)
#define CAN_BTR_LBKM (1 << 30) /* Bit 30: Loop Back Mode (Debug) */
-#define CAN_BTR_SILM (1 << 31) /* Bit 31: Silent Mode (Debug) */
+#define CAN_BTR_SILM (1ul << 31) /* Bit 31: Silent Mode (Debug) */
#define CAN_BTR_BRP_MAX (1024) /* Maximum BTR value (without decrement) */
#define CAN_BTR_TSEG1_MAX (16) /* Maximum TSEG1 value (without decrement) */
diff --git a/arch/arm/src/stm32/stm32_bbsram.c b/arch/arm/src/stm32/stm32_bbsram.c
index e35f5e05a7ec83189cc95f5554a1dc7291d558c4..81c49340ae9e6b20dd76babd5fca731867763bbc 100644
--- a/arch/arm/src/stm32/stm32_bbsram.c
+++ b/arch/arm/src/stm32/stm32_bbsram.c
@@ -593,8 +593,9 @@ static int stm32_bbsram_ioctl(FAR struct file *filep, int cmd,
bbrr->fileno = bbr->bbf->fileno;
bbrr->lastwrite = bbr->bbf->lastwrite;
bbrr->len = bbr->bbf->len;
- bbrr->flags = (bbr->bbf->crc == stm32_bbsram_crc(bbr->bbf)) ? eCRCValid : 0;
- bbrr->flags = (bbr->bbf->dirty) ? eDirty : 0;
+ bbrr->flags = ((bbr->bbf->crc == stm32_bbsram_crc(bbr->bbf))
+ ? BBSRAM_CRC_VALID : 0);
+ bbrr->flags |= ((bbr->bbf->dirty) ? BBSRAM_DIRTY : 0);
ret = OK;
}
diff --git a/arch/arm/src/stm32/stm32_bbsram.h b/arch/arm/src/stm32/stm32_bbsram.h
index 69d0046f5cfba0136aed5c1030790ba054aa380a..bcb813d6fa1675269ffab47a3614a28d5729d6e0 100644
--- a/arch/arm/src/stm32/stm32_bbsram.h
+++ b/arch/arm/src/stm32/stm32_bbsram.h
@@ -83,9 +83,8 @@
enum bbsramdf_e
{
- eCRCValid = 1, /* The crc is valid */
- eDirty = 2, /* The file was closed */
-
+ BBSRAM_CRC_VALID = 1, /* The crc is valid */
+ BBSRAM_DIRTY = 2, /* The file was closed */
};
struct bbsramd_s
diff --git a/arch/arm/src/stm32/stm32_can.c b/arch/arm/src/stm32/stm32_can.c
index cd902bf7e2f6a38a7d262b847b5736a40f1bf9c9..334c7337d62eb89cd5e43922446af7de9bace7e8 100644
--- a/arch/arm/src/stm32/stm32_can.c
+++ b/arch/arm/src/stm32/stm32_can.c
@@ -1,4 +1,4 @@
-/************************************************************************************
+/****************************************************************************
* arch/arm/src/stm32/stm32_can.c
*
* Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
@@ -34,7 +34,7 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- ************************************************************************************/
+ ****************************************************************************/
/****************************************************************************
* Included Files
@@ -58,16 +58,17 @@
#include "up_internal.h"
#include "up_arch.h"
-
#include "chip.h"
#include "stm32.h"
#include "stm32_can.h"
-#if defined(CONFIG_CAN) && (defined(CONFIG_STM32_CAN1) || defined(CONFIG_STM32_CAN2))
+#if defined(CONFIG_CAN) && \
+ (defined(CONFIG_STM32_CAN1) || defined(CONFIG_STM32_CAN2))
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
+
/* Delays *******************************************************************/
/* Time out for INAK bit */
@@ -106,50 +107,70 @@ struct stm32_can_s
/* CAN Register access */
-static uint32_t can_getreg(FAR struct stm32_can_s *priv, int offset);
-static uint32_t can_getfreg(FAR struct stm32_can_s *priv, int offset);
-static void can_putreg(FAR struct stm32_can_s *priv, int offset,
- uint32_t value);
-static void can_putfreg(FAR struct stm32_can_s *priv, int offset,
- uint32_t value);
+static uint32_t stm32can_getreg(FAR struct stm32_can_s *priv,
+ int offset);
+static uint32_t stm32can_getfreg(FAR struct stm32_can_s *priv,
+ int offset);
+static void stm32can_putreg(FAR struct stm32_can_s *priv, int offset,
+ uint32_t value);
+static void stm32can_putfreg(FAR struct stm32_can_s *priv, int offset,
+ uint32_t value);
#ifdef CONFIG_STM32_CAN_REGDEBUG
-static void can_dumpctrlregs(FAR struct stm32_can_s *priv,
- FAR const char *msg);
-static void can_dumpmbregs(FAR struct stm32_can_s *priv,
- FAR const char *msg);
-static void can_dumpfiltregs(FAR struct stm32_can_s *priv,
- FAR const char *msg);
+static void stm32can_dumpctrlregs(FAR struct stm32_can_s *priv,
+ FAR const char *msg);
+static void stm32can_dumpmbregs(FAR struct stm32_can_s *priv,
+ FAR const char *msg);
+static void stm32can_dumpfiltregs(FAR struct stm32_can_s *priv,
+ FAR const char *msg);
#else
-# define can_dumpctrlregs(priv,msg)
-# define can_dumpmbregs(priv,msg)
-# define can_dumpfiltregs(priv,msg)
+# define stm32can_dumpctrlregs(priv,msg)
+# define stm32can_dumpmbregs(priv,msg)
+# define stm32can_dumpfiltregs(priv,msg)
#endif
+/* Filtering (todo) */
+
+#ifdef CONFIG_CAN_EXTID
+static int stm32can_addextfilter(FAR struct stm32_can_s *priv,
+ FAR struct canioc_extfilter_s *arg);
+static int stm32can_delextfilter(FAR struct stm32_can_s *priv,
+ int arg);
+#endif
+static int stm32can_addstdfilter(FAR struct stm32_can_s *priv,
+ FAR struct canioc_stdfilter_s *arg);
+static int stm32can_delstdfilter(FAR struct stm32_can_s *priv,
+ int arg);
+
/* CAN driver methods */
-static void can_reset(FAR struct can_dev_s *dev);
-static int can_setup(FAR struct can_dev_s *dev);
-static void can_shutdown(FAR struct can_dev_s *dev);
-static void can_rxint(FAR struct can_dev_s *dev, bool enable);
-static void can_txint(FAR struct can_dev_s *dev, bool enable);
-static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg);
-static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id);
-static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg);
-static bool can_txready(FAR struct can_dev_s *dev);
-static bool can_txempty(FAR struct can_dev_s *dev);
+static void stm32can_reset(FAR struct can_dev_s *dev);
+static int stm32can_setup(FAR struct can_dev_s *dev);
+static void stm32can_shutdown(FAR struct can_dev_s *dev);
+static void stm32can_rxint(FAR struct can_dev_s *dev, bool enable);
+static void stm32can_txint(FAR struct can_dev_s *dev, bool enable);
+static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
+ unsigned long arg);
+static int stm32can_remoterequest(FAR struct can_dev_s *dev,
+ uint16_t id);
+static int stm32can_send(FAR struct can_dev_s *dev,
+ FAR struct can_msg_s *msg);
+static bool stm32can_txready(FAR struct can_dev_s *dev);
+static bool stm32can_txempty(FAR struct can_dev_s *dev);
/* CAN interrupt handling */
-static int can_rxinterrupt(int irq, FAR void *context, int rxmb);
-static int can_rx0interrupt(int irq, FAR void *context);
-static int can_rx1interrupt(int irq, FAR void *context);
-static int can_txinterrupt(int irq, FAR void *context);
+static int stm32can_rxinterrupt(int irq, FAR void *context, int rxmb);
+static int stm32can_rx0interrupt(int irq, FAR void *context);
+static int stm32can_rx1interrupt(int irq, FAR void *context);
+static int stm32can_txinterrupt(int irq, FAR void *context);
/* Initialization */
-static int can_bittiming(FAR struct stm32_can_s *priv);
-static int can_cellinit(FAR struct stm32_can_s *priv);
-static int can_filterinit(FAR struct stm32_can_s *priv);
+static int stm32can_enterinitmode(FAR struct stm32_can_s *priv);
+static int stm32can_exitinitmode(FAR struct stm32_can_s *priv);
+static int stm32can_bittiming(FAR struct stm32_can_s *priv);
+static int stm32can_cellinit(FAR struct stm32_can_s *priv);
+static int stm32can_filterinit(FAR struct stm32_can_s *priv);
/****************************************************************************
* Private Data
@@ -157,16 +178,16 @@ static int can_filterinit(FAR struct stm32_can_s *priv);
static const struct can_ops_s g_canops =
{
- .co_reset = can_reset,
- .co_setup = can_setup,
- .co_shutdown = can_shutdown,
- .co_rxint = can_rxint,
- .co_txint = can_txint,
- .co_ioctl = can_ioctl,
- .co_remoterequest = can_remoterequest,
- .co_send = can_send,
- .co_txready = can_txready,
- .co_txempty = can_txempty,
+ .co_reset = stm32can_reset,
+ .co_setup = stm32can_setup,
+ .co_shutdown = stm32can_shutdown,
+ .co_rxint = stm32can_rxint,
+ .co_txint = stm32can_txint,
+ .co_ioctl = stm32can_ioctl,
+ .co_remoterequest = stm32can_remoterequest,
+ .co_send = stm32can_send,
+ .co_txready = stm32can_txready,
+ .co_txempty = stm32can_txempty,
};
#ifdef CONFIG_STM32_CAN1
@@ -220,8 +241,8 @@ static struct can_dev_s g_can2dev =
****************************************************************************/
/****************************************************************************
- * Name: can_getreg
- * Name: can_getfreg
+ * Name: stm32can_getreg
+ * Name: stm32can_getfreg
*
* Description:
* Read the value of a CAN register or filter block register.
@@ -235,7 +256,7 @@ static struct can_dev_s g_can2dev =
****************************************************************************/
#ifdef CONFIG_STM32_CAN_REGDEBUG
-static uint32_t can_vgetreg(uint32_t addr)
+static uint32_t stm32can_vgetreg(uint32_t addr)
{
static uint32_t prevaddr = 0;
static uint32_t preval = 0;
@@ -288,23 +309,23 @@ static uint32_t can_vgetreg(uint32_t addr)
return val;
}
-static uint32_t can_getreg(FAR struct stm32_can_s *priv, int offset)
+static uint32_t stm32can_getreg(FAR struct stm32_can_s *priv, int offset)
{
- return can_vgetreg(priv->base + offset);
+ return stm32can_vgetreg(priv->base + offset);
}
-static uint32_t can_getfreg(FAR struct stm32_can_s *priv, int offset)
+static uint32_t stm32can_getfreg(FAR struct stm32_can_s *priv, int offset)
{
- return can_vgetreg(priv->fbase + offset);
+ return stm32can_vgetreg(priv->fbase + offset);
}
#else
-static uint32_t can_getreg(FAR struct stm32_can_s *priv, int offset)
+static uint32_t stm32can_getreg(FAR struct stm32_can_s *priv, int offset)
{
return getreg32(priv->base + offset);
}
-static uint32_t can_getfreg(FAR struct stm32_can_s *priv, int offset)
+static uint32_t stm32can_getfreg(FAR struct stm32_can_s *priv, int offset)
{
return getreg32(priv->fbase + offset);
}
@@ -312,8 +333,8 @@ static uint32_t can_getfreg(FAR struct stm32_can_s *priv, int offset)
#endif
/****************************************************************************
- * Name: can_putreg
- * Name: can_putfreg
+ * Name: stm32can_putreg
+ * Name: stm32can_putfreg
*
* Description:
* Set the value of a CAN register or filter block register.
@@ -329,9 +350,8 @@ static uint32_t can_getfreg(FAR struct stm32_can_s *priv, int offset)
****************************************************************************/
#ifdef CONFIG_STM32_CAN_REGDEBUG
-static void can_vputreg(uint32_t addr, uint32_t value)
+static void stm32can_vputreg(uint32_t addr, uint32_t value)
{
-
/* Show the register value being written */
caninfo("%08x<-%08x\n", addr, value);
@@ -341,34 +361,34 @@ static void can_vputreg(uint32_t addr, uint32_t value)
putreg32(value, addr);
}
-static void can_putreg(FAR struct stm32_can_s *priv, int offset,
- uint32_t value)
+static void stm32can_putreg(FAR struct stm32_can_s *priv, int offset,
+ uint32_t value)
{
- can_vputreg(priv->base + offset, value);
+ stm32can_vputreg(priv->base + offset, value);
}
-static void can_putfreg(FAR struct stm32_can_s *priv, int offset,
- uint32_t value)
+static void stm32can_putfreg(FAR struct stm32_can_s *priv, int offset,
+ uint32_t value)
{
- can_vputreg(priv->fbase + offset, value);
+ stm32can_vputreg(priv->fbase + offset, value);
}
#else
-static void can_putreg(FAR struct stm32_can_s *priv, int offset,
- uint32_t value)
+static void stm32can_putreg(FAR struct stm32_can_s *priv, int offset,
+ uint32_t value)
{
putreg32(value, priv->base + offset);
}
-static void can_putfreg(FAR struct stm32_can_s *priv, int offset,
- uint32_t value)
+static void stm32can_putfreg(FAR struct stm32_can_s *priv, int offset,
+ uint32_t value)
{
putreg32(value, priv->fbase + offset);
}
#endif
/****************************************************************************
- * Name: can_dumpctrlregs
+ * Name: stm32can_dumpctrlregs
*
* Description:
* Dump the contents of all CAN control registers
@@ -382,8 +402,8 @@ static void can_putfreg(FAR struct stm32_can_s *priv, int offset,
****************************************************************************/
#ifdef CONFIG_STM32_CAN_REGDEBUG
-static void can_dumpctrlregs(FAR struct stm32_can_s *priv,
- FAR const char *msg)
+static void stm32can_dumpctrlregs(FAR struct stm32_can_s *priv,
+ FAR const char *msg)
{
if (msg)
{
@@ -413,7 +433,7 @@ static void can_dumpctrlregs(FAR struct stm32_can_s *priv,
#endif
/****************************************************************************
- * Name: can_dumpmbregs
+ * Name: stm32can_dumpmbregs
*
* Description:
* Dump the contents of all CAN mailbox registers
@@ -427,8 +447,8 @@ static void can_dumpctrlregs(FAR struct stm32_can_s *priv,
****************************************************************************/
#ifdef CONFIG_STM32_CAN_REGDEBUG
-static void can_dumpmbregs(FAR struct stm32_can_s *priv,
- FAR const char *msg)
+static void stm32can_dumpmbregs(FAR struct stm32_can_s *priv,
+ FAR const char *msg)
{
if (msg)
{
@@ -474,7 +494,7 @@ static void can_dumpmbregs(FAR struct stm32_can_s *priv,
#endif
/****************************************************************************
- * Name: can_dumpfiltregs
+ * Name: stm32can_dumpfiltregs
*
* Description:
* Dump the contents of all CAN filter registers
@@ -488,8 +508,8 @@ static void can_dumpmbregs(FAR struct stm32_can_s *priv,
****************************************************************************/
#ifdef CONFIG_STM32_CAN_REGDEBUG
-static void can_dumpfiltregs(FAR struct stm32_can_s *priv,
- FAR const char *msg)
+static void stm32can_dumpfiltregs(FAR struct stm32_can_s *priv,
+ FAR const char *msg)
{
int i;
@@ -519,11 +539,11 @@ static void can_dumpfiltregs(FAR struct stm32_can_s *priv,
#endif
/****************************************************************************
- * Name: can_reset
+ * Name: stm32can_reset
*
* Description:
* Reset the CAN device. Called early to initialize the hardware. This
- * function is called, before can_setup() and on error conditions.
+ * function is called, before stm32can_setup() and on error conditions.
*
* Input Parameters:
* dev - An instance of the "upper half" can driver state structure.
@@ -533,7 +553,7 @@ static void can_dumpfiltregs(FAR struct stm32_can_s *priv,
*
****************************************************************************/
-static void can_reset(FAR struct can_dev_s *dev)
+static void stm32can_reset(FAR struct can_dev_s *dev)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
uint32_t regval;
@@ -581,7 +601,7 @@ static void can_reset(FAR struct can_dev_s *dev)
}
/****************************************************************************
- * Name: can_setup
+ * Name: stm32can_setup
*
* Description:
* Configure the CAN. This method is called the first time that the CAN
@@ -597,7 +617,7 @@ static void can_reset(FAR struct can_dev_s *dev)
*
****************************************************************************/
-static int can_setup(FAR struct can_dev_s *dev)
+static int stm32can_setup(FAR struct can_dev_s *dev)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
int ret;
@@ -607,39 +627,42 @@ static int can_setup(FAR struct can_dev_s *dev)
/* CAN cell initialization */
- ret = can_cellinit(priv);
+ ret = stm32can_cellinit(priv);
if (ret < 0)
{
- canerr("ERROR: CAN%d cell initialization failed: %d\n", priv->port, ret);
+ canerr("ERROR: CAN%d cell initialization failed: %d\n",
+ priv->port, ret);
return ret;
}
- can_dumpctrlregs(priv, "After cell initialization");
- can_dumpmbregs(priv, NULL);
+ stm32can_dumpctrlregs(priv, "After cell initialization");
+ stm32can_dumpmbregs(priv, NULL);
/* CAN filter initialization */
- ret = can_filterinit(priv);
+ ret = stm32can_filterinit(priv);
if (ret < 0)
{
- canerr("ERROR: CAN%d filter initialization failed: %d\n", priv->port, ret);
+ canerr("ERROR: CAN%d filter initialization failed: %d\n",
+ priv->port, ret);
return ret;
}
- can_dumpfiltregs(priv, "After filter initialization");
+
+ stm32can_dumpfiltregs(priv, "After filter initialization");
/* Attach the CAN RX FIFO 0/1 interrupts and TX interrupts.
* The others are not used.
*/
- ret = irq_attach(priv->canrx[0], can_rx0interrupt);
+ ret = irq_attach(priv->canrx[0], stm32can_rx0interrupt);
if (ret < 0)
{
- canerr(ERROR: "Failed to attach CAN%d RX0 IRQ (%d)",
+ canerr("ERROR: Failed to attach CAN%d RX0 IRQ (%d)",
priv->port, priv->canrx[0]);
return ret;
}
- ret = irq_attach(priv->canrx[1], can_rx1interrupt);
+ ret = irq_attach(priv->canrx[1], stm32can_rx1interrupt);
if (ret < 0)
{
canerr("ERROR: Failed to attach CAN%d RX1 IRQ (%d)",
@@ -647,7 +670,7 @@ static int can_setup(FAR struct can_dev_s *dev)
return ret;
}
- ret = irq_attach(priv->cantx, can_txinterrupt);
+ ret = irq_attach(priv->cantx, stm32can_txinterrupt);
if (ret < 0)
{
canerr("ERROR: Failed to attach CAN%d TX IRQ (%d)",
@@ -667,7 +690,7 @@ static int can_setup(FAR struct can_dev_s *dev)
}
/****************************************************************************
- * Name: can_shutdown
+ * Name: stm32can_shutdown
*
* Description:
* Disable the CAN. This method is called when the CAN device is closed.
@@ -681,7 +704,7 @@ static int can_setup(FAR struct can_dev_s *dev)
*
****************************************************************************/
-static void can_shutdown(FAR struct can_dev_s *dev)
+static void stm32can_shutdown(FAR struct can_dev_s *dev)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
@@ -701,11 +724,11 @@ static void can_shutdown(FAR struct can_dev_s *dev)
/* And reset the hardware */
- can_reset(dev);
+ stm32can_reset(dev);
}
/****************************************************************************
- * Name: can_rxint
+ * Name: stm32can_rxint
*
* Description:
* Call to enable or disable RX interrupts.
@@ -718,7 +741,7 @@ static void can_shutdown(FAR struct can_dev_s *dev)
*
****************************************************************************/
-static void can_rxint(FAR struct can_dev_s *dev, bool enable)
+static void stm32can_rxint(FAR struct can_dev_s *dev, bool enable)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
uint32_t regval;
@@ -727,7 +750,7 @@ static void can_rxint(FAR struct can_dev_s *dev, bool enable)
/* Enable/disable the FIFO 0/1 message pending interrupt */
- regval = can_getreg(priv, STM32_CAN_IER_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_IER_OFFSET);
if (enable)
{
regval |= CAN_IER_FMPIE0 | CAN_IER_FMPIE1;
@@ -736,11 +759,12 @@ static void can_rxint(FAR struct can_dev_s *dev, bool enable)
{
regval &= ~(CAN_IER_FMPIE0 | CAN_IER_FMPIE1);
}
- can_putreg(priv, STM32_CAN_IER_OFFSET, regval);
+
+ stm32can_putreg(priv, STM32_CAN_IER_OFFSET, regval);
}
/****************************************************************************
- * Name: can_txint
+ * Name: stm32can_txint
*
* Description:
* Call to enable or disable TX interrupts.
@@ -753,7 +777,7 @@ static void can_rxint(FAR struct can_dev_s *dev, bool enable)
*
****************************************************************************/
-static void can_txint(FAR struct can_dev_s *dev, bool enable)
+static void stm32can_txint(FAR struct can_dev_s *dev, bool enable)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
uint32_t regval;
@@ -764,14 +788,14 @@ static void can_txint(FAR struct can_dev_s *dev, bool enable)
if (!enable)
{
- regval = can_getreg(priv, STM32_CAN_IER_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_IER_OFFSET);
regval &= ~CAN_IER_TMEIE;
- can_putreg(priv, STM32_CAN_IER_OFFSET, regval);
+ stm32can_putreg(priv, STM32_CAN_IER_OFFSET, regval);
}
}
/****************************************************************************
- * Name: can_ioctl
+ * Name: stm32can_ioctl
*
* Description:
* All ioctl calls will be routed through this method
@@ -784,15 +808,311 @@ static void can_txint(FAR struct can_dev_s *dev, bool enable)
*
****************************************************************************/
-static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg)
+static int stm32can_ioctl(FAR struct can_dev_s *dev, int cmd,
+ unsigned long arg)
{
- /* No CAN ioctls are supported */
+ FAR struct stm32_can_s *priv;
+ int ret = -ENOTTY;
- return -ENOTTY;
+ caninfo("cmd=%04x arg=%lu\n", cmd, arg);
+
+ DEBUGASSERT(dev && dev->cd_priv);
+ priv = dev->cd_priv;
+
+ /* Handle the command */
+
+ switch (cmd)
+ {
+ /* CANIOC_GET_BITTIMING:
+ * Description: Return the current bit timing settings
+ * Argument: A pointer to a write-able instance of struct
+ * canioc_bittiming_s in which current bit timing
+ * values will be returned.
+ * Returned Value: Zero (OK) is returned on success. Otherwise -1
+ * (ERROR) is returned with the errno variable set
+ * to indicate the nature of the error.
+ * Dependencies: None
+ */
+
+ case CANIOC_GET_BITTIMING:
+ {
+ FAR struct canioc_bittiming_s *bt =
+ (FAR struct canioc_bittiming_s *)arg;
+ uint32_t regval;
+ uint32_t brp;
+
+ DEBUGASSERT(bt != NULL);
+ regval = stm32can_getreg(priv, STM32_CAN_BTR_OFFSET);
+ bt->bt_sjw = ((regval & CAN_BTR_SJW_MASK) >> CAN_BTR_SJW_SHIFT) + 1;
+ bt->bt_tseg1 = ((regval & CAN_BTR_TS1_MASK) >> CAN_BTR_TS1_SHIFT) + 1;
+ bt->bt_tseg2 = ((regval & CAN_BTR_TS2_MASK) >> CAN_BTR_TS2_SHIFT) + 1;
+
+ brp = ((regval & CAN_BTR_BRP_MASK) >> CAN_BTR_BRP_SHIFT) + 1;
+ bt->bt_baud = STM32_PCLK1_FREQUENCY /
+ (brp * (bt->bt_tseg1 + bt->bt_tseg2 + 1));
+ ret = OK;
+ }
+ break;
+
+ /* CANIOC_SET_BITTIMING:
+ * Description: Set new current bit timing values
+ * Argument: A pointer to a read-able instance of struct
+ * canioc_bittiming_s in which the new bit timing
+ * values are provided.
+ * Returned Value: Zero (OK) is returned on success. Otherwise -1
+ * (ERROR)is returned with the errno variable set
+ * to indicate thenature of the error.
+ * Dependencies: None
+ *
+ * REVISIT: There is probably a limitation here: If there are multiple
+ * threads trying to send CAN packets, when one of these threads
+ * reconfigures the bitrate, the MCAN hardware will be reset and the
+ * context of operation will be lost. Hence, this IOCTL can only safely
+ * be executed in quiescent time periods.
+ */
+
+ case CANIOC_SET_BITTIMING:
+ {
+ FAR const struct canioc_bittiming_s *bt =
+ (FAR const struct canioc_bittiming_s *)arg;
+ uint32_t brp;
+ uint32_t can_bit_quanta;
+ uint32_t tmp;
+ uint32_t regval;
+
+ DEBUGASSERT(bt != NULL);
+ DEBUGASSERT(bt->bt_baud < STM32_PCLK1_FREQUENCY);
+ DEBUGASSERT(bt->bt_sjw > 0 && bt->bt_sjw <= 4);
+ DEBUGASSERT(bt->bt_tseg1 > 0 && bt->bt_tseg1 <= 16);
+ DEBUGASSERT(bt->bt_tseg2 > 0 && bt->bt_tseg2 <= 8);
+
+ regval = stm32can_getreg(priv, STM32_CAN_BTR_OFFSET);
+
+ /* Extract bit timing data */
+ /* tmp is in clocks per bit time */
+
+ tmp = STM32_PCLK1_FREQUENCY / bt->bt_baud;
+
+ /* This value is dynamic as requested by user */
+
+ can_bit_quanta = bt->bt_tseg1 + bt->bt_tseg2 + 1;
+
+ if (tmp < can_bit_quanta)
+ {
+ /* This timing is not possible */
+
+ ret = -EINVAL;
+ break;
+ }
+
+ /* Otherwise, nquanta is can_bit_quanta, ts1 and ts2 are
+ * provided by the user and we calculate brp to achieve
+ * can_bit_quanta quanta in the bit times
+ */
+
+ else
+ {
+ brp = (tmp + (can_bit_quanta/2)) / can_bit_quanta;
+ DEBUGASSERT(brp >= 1 && brp <= CAN_BTR_BRP_MAX);
+ }
+
+ caninfo("TS1: %d TS2: %d BRP: %d\n",
+ bt->bt_tseg1, bt->bt_tseg2, brp);
+
+ /* Configure bit timing. */
+
+ regval &= ~(CAN_BTR_BRP_MASK | CAN_BTR_TS1_MASK |
+ CAN_BTR_TS2_MASK | CAN_BTR_SJW_MASK);
+ regval |= ((brp - 1) << CAN_BTR_BRP_SHIFT) |
+ ((bt->bt_tseg1 - 1) << CAN_BTR_TS1_SHIFT) |
+ ((bt->bt_tseg2 - 1) << CAN_BTR_TS2_SHIFT) |
+ ((bt->bt_sjw - 1) << CAN_BTR_SJW_SHIFT);
+
+ /* Bit timing can only be configured in init mode. */
+
+ ret = stm32can_enterinitmode(priv);
+ if (ret < 0)
+ {
+ break;
+ }
+
+ stm32can_putreg(priv, STM32_CAN_BTR_OFFSET, regval);
+
+ ret = stm32can_exitinitmode(priv);
+ if (ret >= 0)
+ {
+ priv->baud = STM32_PCLK1_FREQUENCY /
+ (brp * (bt->bt_tseg1 + bt->bt_tseg2 + 1));
+ }
+ }
+ break;
+
+ /* CANIOC_GET_CONNMODES:
+ * Description: Get the current bus connection modes
+ * Argument: A pointer to a write-able instance of struct
+ * canioc_connmodes_s in which the new bus modes will
+ * be returned.
+ * Returned Value: Zero (OK) is returned on success. Otherwise -1
+ * (ERROR)is returned with the errno variable set
+ * to indicate the nature of the error.
+ * Dependencies: None
+ */
+
+ case CANIOC_GET_CONNMODES:
+ {
+ FAR struct canioc_connmodes_s *bm =
+ (FAR struct canioc_connmodes_s *)arg;
+ uint32_t regval;
+
+ DEBUGASSERT(bm != NULL);
+
+ regval = stm32can_getreg(priv, STM32_CAN_BTR_OFFSET);
+
+ bm->bm_loopback = ((regval & CAN_BTR_LBKM) == CAN_BTR_LBKM);
+ bm->bm_silent = ((regval & CAN_BTR_SILM) == CAN_BTR_SILM);
+ ret = OK;
+ break;
+ }
+
+ /* CANIOC_SET_CONNMODES:
+ * Description: Set new bus connection modes values
+ * Argument: A pointer to a read-able instance of struct
+ * canioc_connmodes_s in which the new bus modes
+ * are provided.
+ * Returned Value: Zero (OK) is returned on success. Otherwise -1
+ * (ERROR) is returned with the errno variable set
+ * to indicate the nature of the error.
+ * Dependencies: None
+ */
+
+ case CANIOC_SET_CONNMODES:
+ {
+ FAR struct canioc_connmodes_s *bm =
+ (FAR struct canioc_connmodes_s *)arg;
+ uint32_t regval;
+
+ DEBUGASSERT(bm != NULL);
+
+ regval = stm32can_getreg(priv, STM32_CAN_BTR_OFFSET);
+
+ if (bm->bm_loopback)
+ {
+ regval |= CAN_BTR_LBKM;
+ }
+ else
+ {
+ regval &= ~CAN_BTR_LBKM;
+ }
+
+ if (bm->bm_silent)
+ {
+ regval |= CAN_BTR_SILM;
+ }
+ else
+ {
+ regval &= ~CAN_BTR_SILM;
+ }
+
+ /* This register can only be configured in init mode. */
+
+ ret = stm32can_enterinitmode(priv);
+ if (ret < 0)
+ {
+ break;
+ }
+
+ stm32can_putreg(priv, STM32_CAN_BTR_OFFSET, regval);
+
+ ret = stm32can_exitinitmode(priv);
+ }
+ break;
+
+#ifdef CONFIG_CAN_EXTID
+ /* CANIOC_ADD_EXTFILTER:
+ * Description: Add an address filter for a extended 29 bit
+ * address.
+ * Argument: A reference to struct canioc_extfilter_s
+ * Returned Value: A non-negative filter ID is returned on success.
+ * Otherwise -1 (ERROR) is returned with the errno
+ * variable set to indicate the nature of the error.
+ */
+
+ case CANIOC_ADD_EXTFILTER:
+ {
+ DEBUGASSERT(arg != 0);
+ ret = stm32can_addextfilter(priv,
+ (FAR struct canioc_extfilter_s *)arg);
+ }
+ break;
+
+ /* CANIOC_DEL_EXTFILTER:
+ * Description: Remove an address filter for a standard 29 bit
+ * address.
+ * Argument: The filter index previously returned by the
+ * CANIOC_ADD_EXTFILTER command
+ * Returned Value: Zero (OK) is returned on success. Otherwise -1
+ * (ERROR)is returned with the errno variable set
+ * to indicate the nature of the error.
+ */
+
+ case CANIOC_DEL_EXTFILTER:
+ {
+#if 0 /* Unimplemented */
+ DEBUGASSERT(arg <= priv->config->nextfilters);
+#endif
+ ret = stm32can_delextfilter(priv, (int)arg);
+ }
+ break;
+#endif
+
+ /* CANIOC_ADD_STDFILTER:
+ * Description: Add an address filter for a standard 11 bit
+ * address.
+ * Argument: A reference to struct canioc_stdfilter_s
+ * Returned Value: A non-negative filter ID is returned on success.
+ * Otherwise -1 (ERROR) is returned with the errno
+ * variable set to indicate the nature of the error.
+ */
+
+ case CANIOC_ADD_STDFILTER:
+ {
+ DEBUGASSERT(arg != 0);
+ ret = stm32can_addstdfilter(priv,
+ (FAR struct canioc_stdfilter_s *)arg);
+ }
+ break;
+
+ /* CANIOC_DEL_STDFILTER:
+ * Description: Remove an address filter for a standard 11 bit
+ * address.
+ * Argument: The filter index previously returned by the
+ * CANIOC_ADD_STDFILTER command
+ * Returned Value: Zero (OK) is returned on success. Otherwise -1
+ * (ERROR) is returned with the errno variable set
+ * to indicate the nature of the error.
+ */
+
+ case CANIOC_DEL_STDFILTER:
+ {
+#if 0 /* Unimplemented */
+ DEBUGASSERT(arg <= priv->config->nstdfilters);
+#endif
+ ret = stm32can_delstdfilter(priv, (int)arg);
+ }
+ break;
+
+ /* Unsupported/unrecognized command */
+
+ default:
+ canerr("ERROR: Unrecognized command: %04x\n", cmd);
+ break;
+ }
+
+ return ret;
}
/****************************************************************************
- * Name: can_remoterequest
+ * Name: stm32can_remoterequest
*
* Description:
* Send a remote request
@@ -805,14 +1125,14 @@ static int can_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg)
*
****************************************************************************/
-static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id)
+static int stm32can_remoterequest(FAR struct can_dev_s *dev, uint16_t id)
{
#warning "Remote request not implemented"
return -ENOSYS;
}
/****************************************************************************
- * Name: can_send
+ * Name: stm32can_send
*
* Description:
* Send one can message.
@@ -834,7 +1154,8 @@ static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id)
*
****************************************************************************/
-static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
+static int stm32can_send(FAR struct can_dev_s *dev,
+ FAR struct can_msg_s *msg)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
FAR uint8_t *ptr;
@@ -848,7 +1169,7 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
/* Select one empty transmit mailbox */
- regval = can_getreg(priv, STM32_CAN_TSR_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_TSR_OFFSET);
if ((regval & CAN_TSR_TME0) != 0 && (regval & CAN_TSR_RQCP0) == 0)
{
txmb = 0;
@@ -869,10 +1190,10 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
/* Clear TXRQ, RTR, IDE, EXID, and STID fields */
- regval = can_getreg(priv, STM32_CAN_TIR_OFFSET(txmb));
+ regval = stm32can_getreg(priv, STM32_CAN_TIR_OFFSET(txmb));
regval &= ~(CAN_TIR_TXRQ | CAN_TIR_RTR | CAN_TIR_IDE |
CAN_TIR_EXID_MASK | CAN_TIR_STID_MASK);
- can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval);
+ stm32can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval);
/* Set up the ID, standard 11-bit or extended 29-bit. */
@@ -892,15 +1213,15 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
regval &= ~CAN_TIR_STID_MASK;
regval |= (uint32_t)msg->cm_hdr.ch_id << CAN_TIR_STID_SHIFT;
#endif
- can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval);
+ stm32can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval);
/* Set up the DLC */
dlc = msg->cm_hdr.ch_dlc;
- regval = can_getreg(priv, STM32_CAN_TDTR_OFFSET(txmb));
+ regval = stm32can_getreg(priv, STM32_CAN_TDTR_OFFSET(txmb));
regval &= ~(CAN_TDTR_DLC_MASK | CAN_TDTR_TGT);
regval |= (uint32_t)dlc << CAN_TDTR_DLC_SHIFT;
- can_putreg(priv, STM32_CAN_TDTR_OFFSET(txmb), regval);
+ stm32can_putreg(priv, STM32_CAN_TDTR_OFFSET(txmb), regval);
/* Set up the data fields */
@@ -930,7 +1251,8 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
}
}
}
- can_putreg(priv, STM32_CAN_TDLR_OFFSET(txmb), regval);
+
+ stm32can_putreg(priv, STM32_CAN_TDLR_OFFSET(txmb), regval);
regval = 0;
if (dlc > 4)
@@ -956,26 +1278,27 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
}
}
}
- can_putreg(priv, STM32_CAN_TDHR_OFFSET(txmb), regval);
+
+ stm32can_putreg(priv, STM32_CAN_TDHR_OFFSET(txmb), regval);
/* Enable the transmit mailbox empty interrupt (may already be enabled) */
- regval = can_getreg(priv, STM32_CAN_IER_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_IER_OFFSET);
regval |= CAN_IER_TMEIE;
- can_putreg(priv, STM32_CAN_IER_OFFSET, regval);
+ stm32can_putreg(priv, STM32_CAN_IER_OFFSET, regval);
/* Request transmission */
- regval = can_getreg(priv, STM32_CAN_TIR_OFFSET(txmb));
+ regval = stm32can_getreg(priv, STM32_CAN_TIR_OFFSET(txmb));
regval |= CAN_TIR_TXRQ; /* Transmit Mailbox Request */
- can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval);
+ stm32can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval);
- can_dumpmbregs(priv, "After send");
+ stm32can_dumpmbregs(priv, "After send");
return OK;
}
/****************************************************************************
- * Name: can_txready
+ * Name: stm32can_txready
*
* Description:
* Return true if the CAN hardware can accept another TX message.
@@ -988,21 +1311,21 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
*
****************************************************************************/
-static bool can_txready(FAR struct can_dev_s *dev)
+static bool stm32can_txready(FAR struct can_dev_s *dev)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
uint32_t regval;
/* Return true if any mailbox is available */
- regval = can_getreg(priv, STM32_CAN_TSR_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_TSR_OFFSET);
caninfo("CAN%d TSR: %08x\n", priv->port, regval);
return (regval & CAN_ALL_MAILBOXES) != 0;
}
/****************************************************************************
- * Name: can_txempty
+ * Name: stm32can_txempty
*
* Description:
* Return true if all message have been sent. If for example, the CAN
@@ -1019,21 +1342,21 @@ static bool can_txready(FAR struct can_dev_s *dev)
*
****************************************************************************/
-static bool can_txempty(FAR struct can_dev_s *dev)
+static bool stm32can_txempty(FAR struct can_dev_s *dev)
{
FAR struct stm32_can_s *priv = dev->cd_priv;
uint32_t regval;
/* Return true if all mailboxes are available */
- regval = can_getreg(priv, STM32_CAN_TSR_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_TSR_OFFSET);
caninfo("CAN%d TSR: %08x\n", priv->port, regval);
return (regval & CAN_ALL_MAILBOXES) == CAN_ALL_MAILBOXES;
}
/****************************************************************************
- * Name: can_rxinterrupt
+ * Name: stm32can_rxinterrupt
*
* Description:
* CAN RX FIFO 0/1 interrupt handler
@@ -1048,7 +1371,7 @@ static bool can_txempty(FAR struct can_dev_s *dev)
*
****************************************************************************/
-static int can_rxinterrupt(int irq, FAR void *context, int rxmb)
+static int stm32can_rxinterrupt(int irq, FAR void *context, int rxmb)
{
FAR struct can_dev_s *dev = NULL;
FAR struct stm32_can_s *priv;
@@ -1080,7 +1403,7 @@ static int can_rxinterrupt(int irq, FAR void *context, int rxmb)
/* Verify that a message is pending in the FIFO */
- regval = can_getreg(priv, STM32_CAN_RFR_OFFSET(rxmb));
+ regval = stm32can_getreg(priv, STM32_CAN_RFR_OFFSET(rxmb));
npending = (regval & CAN_RFR_FMP_MASK) >> CAN_RFR_FMP_SHIFT;
if (npending < 1)
{
@@ -1090,16 +1413,16 @@ static int can_rxinterrupt(int irq, FAR void *context, int rxmb)
if (rxmb == 0)
{
- can_dumpmbregs(priv, "RX0 interrupt");
+ stm32can_dumpmbregs(priv, "RX0 interrupt");
}
else
{
- can_dumpmbregs(priv, "RX1 interrupt");
+ stm32can_dumpmbregs(priv, "RX1 interrupt");
}
/* Get the CAN identifier. */
- regval = can_getreg(priv, STM32_CAN_RIR_OFFSET(rxmb));
+ regval = stm32can_getreg(priv, STM32_CAN_RIR_OFFSET(rxmb));
#ifdef CONFIG_CAN_EXTID
if ((regval & CAN_RIR_IDE) != 0)
@@ -1136,18 +1459,18 @@ static int can_rxinterrupt(int irq, FAR void *context, int rxmb)
/* Get the DLC */
- regval = can_getreg(priv, STM32_CAN_RDTR_OFFSET(rxmb));
+ regval = stm32can_getreg(priv, STM32_CAN_RDTR_OFFSET(rxmb));
hdr.ch_dlc = (regval & CAN_RDTR_DLC_MASK) >> CAN_RDTR_DLC_SHIFT;
/* Save the message data */
- regval = can_getreg(priv, STM32_CAN_RDLR_OFFSET(rxmb));
+ regval = stm32can_getreg(priv, STM32_CAN_RDLR_OFFSET(rxmb));
data[0] = (regval & CAN_RDLR_DATA0_MASK) >> CAN_RDLR_DATA0_SHIFT;
data[1] = (regval & CAN_RDLR_DATA1_MASK) >> CAN_RDLR_DATA1_SHIFT;
data[2] = (regval & CAN_RDLR_DATA2_MASK) >> CAN_RDLR_DATA2_SHIFT;
data[3] = (regval & CAN_RDLR_DATA3_MASK) >> CAN_RDLR_DATA3_SHIFT;
- regval = can_getreg(priv, STM32_CAN_RDHR_OFFSET(rxmb));
+ regval = stm32can_getreg(priv, STM32_CAN_RDHR_OFFSET(rxmb));
data[4] = (regval & CAN_RDHR_DATA4_MASK) >> CAN_RDHR_DATA4_SHIFT;
data[5] = (regval & CAN_RDHR_DATA5_MASK) >> CAN_RDHR_DATA5_SHIFT;
data[6] = (regval & CAN_RDHR_DATA6_MASK) >> CAN_RDHR_DATA6_SHIFT;
@@ -1162,14 +1485,14 @@ static int can_rxinterrupt(int irq, FAR void *context, int rxmb)
#ifndef CONFIG_CAN_EXTID
errout:
#endif
- regval = can_getreg(priv, STM32_CAN_RFR_OFFSET(rxmb));
+ regval = stm32can_getreg(priv, STM32_CAN_RFR_OFFSET(rxmb));
regval |= CAN_RFR_RFOM;
- can_putreg(priv, STM32_CAN_RFR_OFFSET(rxmb), regval);
+ stm32can_putreg(priv, STM32_CAN_RFR_OFFSET(rxmb), regval);
return ret;
}
/****************************************************************************
- * Name: can_rx0interrupt
+ * Name: stm32can_rx0interrupt
*
* Description:
* CAN RX FIFO 0 interrupt handler
@@ -1183,13 +1506,13 @@ errout:
*
****************************************************************************/
-static int can_rx0interrupt(int irq, FAR void *context)
+static int stm32can_rx0interrupt(int irq, FAR void *context)
{
- return can_rxinterrupt(irq, context, 0);
+ return stm32can_rxinterrupt(irq, context, 0);
}
/****************************************************************************
- * Name: can_rx1interrupt
+ * Name: stm32can_rx1interrupt
*
* Description:
* CAN RX FIFO 1 interrupt handler
@@ -1203,13 +1526,13 @@ static int can_rx0interrupt(int irq, FAR void *context)
*
****************************************************************************/
-static int can_rx1interrupt(int irq, FAR void *context)
+static int stm32can_rx1interrupt(int irq, FAR void *context)
{
- return can_rxinterrupt(irq, context, 1);
+ return stm32can_rxinterrupt(irq, context, 1);
}
/****************************************************************************
- * Name: can_txinterrupt
+ * Name: stm32can_txinterrupt
*
* Description:
* CAN TX mailbox complete interrupt handler
@@ -1223,7 +1546,7 @@ static int can_rx1interrupt(int irq, FAR void *context)
*
****************************************************************************/
-static int can_txinterrupt(int irq, FAR void *context)
+static int stm32can_txinterrupt(int irq, FAR void *context)
{
FAR struct can_dev_s *dev = NULL;
FAR struct stm32_can_s *priv;
@@ -1251,7 +1574,7 @@ static int can_txinterrupt(int irq, FAR void *context)
/* Get the transmit status */
- regval = can_getreg(priv, STM32_CAN_TSR_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_TSR_OFFSET);
/* Check for RQCP0: Request completed mailbox 0 */
@@ -1261,7 +1584,7 @@ static int can_txinterrupt(int irq, FAR void *context)
* ALST0 and TERR0) for Mailbox 0.
*/
- can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP0);
+ stm32can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP0);
/* Check for errors */
@@ -1281,7 +1604,7 @@ static int can_txinterrupt(int irq, FAR void *context)
* ALST1 and TERR1) for Mailbox 1.
*/
- can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP1);
+ stm32can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP1);
/* Check for errors */
@@ -1301,7 +1624,7 @@ static int can_txinterrupt(int irq, FAR void *context)
* ALST2 and TERR2) for Mailbox 2.
*/
- can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP2);
+ stm32can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP2);
/* Check for errors */
@@ -1317,7 +1640,7 @@ static int can_txinterrupt(int irq, FAR void *context)
}
/****************************************************************************
- * Name: can_bittiming
+ * Name: stm32can_bittiming
*
* Description:
* Set the CAN bit timing register (BTR) based on the configured BAUD.
@@ -1360,6 +1683,7 @@ static int can_txinterrupt(int irq, FAR void *context)
* Tbs1 = Tq * ts1
* Tbs2 = Tq * ts2
* Tq = brp * Tpclk1
+ * baud = Fpclk1 / (brp * (1 + ts1 + ts2))
*
* Where:
* Tpclk1 is the period of the APB1 clock (PCLK1).
@@ -1372,7 +1696,7 @@ static int can_txinterrupt(int irq, FAR void *context)
*
****************************************************************************/
-static int can_bittiming(FAR struct stm32_can_s *priv)
+static int stm32can_bittiming(FAR struct stm32_can_s *priv)
{
uint32_t tmp;
uint32_t brp;
@@ -1451,15 +1775,17 @@ static int can_bittiming(FAR struct stm32_can_s *priv)
tmp |= CAN_BTR_LBKM;
#endif
- can_putreg(priv, STM32_CAN_BTR_OFFSET, tmp);
+ stm32can_putreg(priv, STM32_CAN_BTR_OFFSET, tmp);
return OK;
}
/****************************************************************************
- * Name: can_cellinit
+ * Name: stm32can_enterinitmode
*
* Description:
- * CAN cell initialization
+ * Put the CAN cell in Initialization mode. This only disconnects the CAN
+ * peripheral, no registers are changed. The initialization mode is
+ * required to change the baud rate.
*
* Input Parameter:
* priv - A pointer to the private data structure for this CAN block
@@ -1469,30 +1795,24 @@ static int can_bittiming(FAR struct stm32_can_s *priv)
*
****************************************************************************/
-static int can_cellinit(FAR struct stm32_can_s *priv)
+static int stm32can_enterinitmode(FAR struct stm32_can_s *priv)
{
- volatile uint32_t timeout;
uint32_t regval;
- int ret;
+ volatile uint32_t timeout;
caninfo("CAN%d\n", priv->port);
- /* Exit from sleep mode */
-
- regval = can_getreg(priv, STM32_CAN_MCR_OFFSET);
- regval &= ~CAN_MCR_SLEEP;
- can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
-
/* Enter initialization mode */
+ regval = stm32can_getreg(priv, STM32_CAN_MCR_OFFSET);
regval |= CAN_MCR_INRQ;
- can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
+ stm32can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
/* Wait until initialization mode is acknowledged */
for (timeout = INAK_TIMEOUT; timeout > 0; timeout--)
{
- regval = can_getreg(priv, STM32_CAN_MSR_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_MSR_OFFSET);
if ((regval & CAN_MSR_INAK) != 0)
{
/* We are in initialization mode */
@@ -1509,41 +1829,39 @@ static int can_cellinit(FAR struct stm32_can_s *priv)
return -ETIMEDOUT;
}
- /* Disable the following modes:
- *
- * - Time triggered communication mode
- * - Automatic bus-off management
- * - Automatic wake-up mode
- * - No automatic retransmission
- * - Receive FIFO locked mode
- * - Transmit FIFO priority
- */
-
- regval = can_getreg(priv, STM32_CAN_MCR_OFFSET);
- regval &= ~(CAN_MCR_TXFP | CAN_MCR_RFLM | CAN_MCR_NART |
- CAN_MCR_AWUM | CAN_MCR_ABOM | CAN_MCR_TTCM);
- can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
+ return OK;
+}
- /* Configure bit timing. */
+/****************************************************************************
+ * Name: stm32can_exitinitmode
+ *
+ * Description:
+ * Put the CAN cell out of the Initialization mode (to Normal mode)
+ *
+ * Input Parameter:
+ * priv - A pointer to the private data structure for this CAN block
+ *
+ * Returned Value:
+ * Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
- ret = can_bittiming(priv);
- if (ret < 0)
- {
- canerr("ERROR: Failed to set bit timing: %d\n", ret);
- return ret;
- }
+static int stm32can_exitinitmode(FAR struct stm32_can_s *priv)
+{
+ uint32_t regval;
+ volatile uint32_t timeout;
- /* Exit initialization mode */
+ /* Exit Initialization mode, enter Normal mode */
- regval = can_getreg(priv, STM32_CAN_MCR_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_MCR_OFFSET);
regval &= ~CAN_MCR_INRQ;
- can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
+ stm32can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
/* Wait until the initialization mode exit is acknowledged */
for (timeout = INAK_TIMEOUT; timeout > 0; timeout--)
{
- regval = can_getreg(priv, STM32_CAN_MSR_OFFSET);
+ regval = stm32can_getreg(priv, STM32_CAN_MSR_OFFSET);
if ((regval & CAN_MSR_INAK) == 0)
{
/* We are out of initialization mode */
@@ -1560,11 +1878,72 @@ static int can_cellinit(FAR struct stm32_can_s *priv)
regval);
return -ETIMEDOUT;
}
+
return OK;
}
/****************************************************************************
- * Name: can_filterinit
+ * Name: stm32can_cellinit
+ *
+ * Description:
+ * CAN cell initialization
+ *
+ * Input Parameter:
+ * priv - A pointer to the private data structure for this CAN block
+ *
+ * Returned Value:
+ * Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int stm32can_cellinit(FAR struct stm32_can_s *priv)
+{
+ uint32_t regval;
+ int ret;
+
+ caninfo("CAN%d\n", priv->port);
+
+ /* Exit from sleep mode */
+
+ regval = stm32can_getreg(priv, STM32_CAN_MCR_OFFSET);
+ regval &= ~CAN_MCR_SLEEP;
+ stm32can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
+
+ ret = stm32can_enterinitmode(priv);
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ /* Disable the following modes:
+ *
+ * - Time triggered communication mode
+ * - Automatic bus-off management
+ * - Automatic wake-up mode
+ * - No automatic retransmission
+ * - Receive FIFO locked mode
+ * - Transmit FIFO priority
+ */
+
+ regval = stm32can_getreg(priv, STM32_CAN_MCR_OFFSET);
+ regval &= ~(CAN_MCR_TXFP | CAN_MCR_RFLM | CAN_MCR_NART |
+ CAN_MCR_AWUM | CAN_MCR_ABOM | CAN_MCR_TTCM);
+ stm32can_putreg(priv, STM32_CAN_MCR_OFFSET, regval);
+
+ /* Configure bit timing. */
+
+ ret = stm32can_bittiming(priv);
+ if (ret < 0)
+ {
+ canerr("ERROR: Failed to set bit timing: %d\n", ret);
+ return ret;
+ }
+
+ return stm32can_exitinitmode(priv);
+}
+
+/****************************************************************************
+ * Name: stm32can_filterinit
*
* Description:
* CAN filter initialization. CAN filters are not currently used by this
@@ -1596,7 +1975,7 @@ static int can_cellinit(FAR struct stm32_can_s *priv)
*
****************************************************************************/
-static int can_filterinit(FAR struct stm32_can_s *priv)
+static int stm32can_filterinit(FAR struct stm32_can_s *priv)
{
uint32_t regval;
uint32_t bitmask;
@@ -1609,66 +1988,162 @@ static int can_filterinit(FAR struct stm32_can_s *priv)
/* Enter filter initialization mode */
- regval = can_getfreg(priv, STM32_CAN_FMR_OFFSET);
+ regval = stm32can_getfreg(priv, STM32_CAN_FMR_OFFSET);
regval |= CAN_FMR_FINIT;
- can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval);
+ stm32can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval);
/* Assign half the filters to CAN1, half to CAN2 */
#if defined(CONFIG_STM32_CONNECTIVITYLINE) || \
defined(CONFIG_STM32_STM32F20XX) || \
defined(CONFIG_STM32_STM32F40XX)
- regval = can_getfreg(priv, STM32_CAN_FMR_OFFSET);
+ regval = stm32can_getfreg(priv, STM32_CAN_FMR_OFFSET);
regval &= CAN_FMR_CAN2SB_MASK;
regval |= (CAN_NFILTERS / 2) << CAN_FMR_CAN2SB_SHIFT;
- can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval);
+ stm32can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval);
#endif
/* Disable the filter */
- regval = can_getfreg(priv, STM32_CAN_FA1R_OFFSET);
+ regval = stm32can_getfreg(priv, STM32_CAN_FA1R_OFFSET);
regval &= ~bitmask;
- can_putfreg(priv, STM32_CAN_FA1R_OFFSET, regval);
+ stm32can_putfreg(priv, STM32_CAN_FA1R_OFFSET, regval);
/* Select the 32-bit scale for the filter */
- regval = can_getfreg(priv, STM32_CAN_FS1R_OFFSET);
+ regval = stm32can_getfreg(priv, STM32_CAN_FS1R_OFFSET);
regval |= bitmask;
- can_putfreg(priv, STM32_CAN_FS1R_OFFSET, regval);
+ stm32can_putfreg(priv, STM32_CAN_FS1R_OFFSET, regval);
/* There are 14 or 28 filter banks (depending) on the device.
* Each filter bank is composed of two 32-bit registers, CAN_FiR:
*/
- can_putfreg(priv, STM32_CAN_FIR_OFFSET(priv->filter, 1), 0);
- can_putfreg(priv, STM32_CAN_FIR_OFFSET(priv->filter, 2), 0);
+ stm32can_putfreg(priv, STM32_CAN_FIR_OFFSET(priv->filter, 1), 0);
+ stm32can_putfreg(priv, STM32_CAN_FIR_OFFSET(priv->filter, 2), 0);
/* Set Id/Mask mode for the filter */
- regval = can_getfreg(priv, STM32_CAN_FM1R_OFFSET);
+ regval = stm32can_getfreg(priv, STM32_CAN_FM1R_OFFSET);
regval &= ~bitmask;
- can_putfreg(priv, STM32_CAN_FM1R_OFFSET, regval);
+ stm32can_putfreg(priv, STM32_CAN_FM1R_OFFSET, regval);
/* Assign FIFO 0 for the filter */
- regval = can_getfreg(priv, STM32_CAN_FFA1R_OFFSET);
+ regval = stm32can_getfreg(priv, STM32_CAN_FFA1R_OFFSET);
regval &= ~bitmask;
- can_putfreg(priv, STM32_CAN_FFA1R_OFFSET, regval);
+ stm32can_putfreg(priv, STM32_CAN_FFA1R_OFFSET, regval);
/* Enable the filter */
- regval = can_getfreg(priv, STM32_CAN_FA1R_OFFSET);
+ regval = stm32can_getfreg(priv, STM32_CAN_FA1R_OFFSET);
regval |= bitmask;
- can_putfreg(priv, STM32_CAN_FA1R_OFFSET, regval);
+ stm32can_putfreg(priv, STM32_CAN_FA1R_OFFSET, regval);
/* Exit filter initialization mode */
- regval = can_getfreg(priv, STM32_CAN_FMR_OFFSET);
+ regval = stm32can_getfreg(priv, STM32_CAN_FMR_OFFSET);
regval &= ~CAN_FMR_FINIT;
- can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval);
+ stm32can_putfreg(priv, STM32_CAN_FMR_OFFSET, regval);
return OK;
}
+/****************************************************************************
+ * Name: stm32can_addextfilter
+ *
+ * Description:
+ * Add a filter for extended CAN IDs
+ *
+ * Input Parameter:
+ * priv - A pointer to the private data structure for this CAN block
+ * arg - A pointer to a structure describing the filter
+ *
+ * Returned Value:
+ * A non-negative filter ID is returned on success.
+ * Otherwise -1 (ERROR) is returned with the errno
+ * set to indicate the nature of the error.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_CAN_EXTID
+static int stm32can_addextfilter(FAR struct stm32_can_s *priv,
+ FAR struct canioc_extfilter_s *arg)
+{
+ return -ENOTTY;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32can_delextfilter
+ *
+ * Description:
+ * Remove a filter for extended CAN IDs
+ *
+ * Input Parameter:
+ * priv - A pointer to the private data structure for this CAN block
+ * arg - The filter index previously returned by the
+ * CANIOC_ADD_EXTFILTER command
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. Otherwise -1 (ERROR)
+ * returned with the errno variable set to indicate the
+ * of the error.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_CAN_EXTID
+static int stm32can_delextfilter(FAR struct stm32_can_s *priv, int arg)
+{
+ return -ENOTTY;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32can_addstdfilter
+ *
+ * Description:
+ * Add a filter for standard CAN IDs
+ *
+ * Input Parameter:
+ * priv - A pointer to the private data structure for this CAN block
+ * arg - A pointer to a structure describing the filter
+ *
+ * Returned Value:
+ * A non-negative filter ID is returned on success.
+ * Otherwise -1 (ERROR) is returned with the errno
+ * set to indicate the nature of the error.
+ *
+ ****************************************************************************/
+
+static int stm32can_addstdfilter(FAR struct stm32_can_s *priv,
+ FAR struct canioc_stdfilter_s *arg)
+{
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: stm32can_delstdfilter
+ *
+ * Description:
+ * Remove a filter for standard CAN IDs
+ *
+ * Input Parameter:
+ * priv - A pointer to the private data structure for this CAN block
+ * arg - The filter index previously returned by the
+ * CANIOC_ADD_STDFILTER command
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. Otherwise -1 (ERROR)
+ * returned with the errno variable set to indicate the
+ * of the error.
+ *
+ ****************************************************************************/
+
+static int stm32can_delstdfilter(FAR struct stm32_can_s *priv, int arg)
+{
+ return -ENOTTY;
+}
+
/****************************************************************************
* Public Functions
****************************************************************************/
diff --git a/arch/arm/src/stm32/stm32_freerun.c b/arch/arm/src/stm32/stm32_freerun.c
new file mode 100644
index 0000000000000000000000000000000000000000..836df043ad79478b17307d8fb7808b81717bfb71
--- /dev/null
+++ b/arch/arm/src/stm32/stm32_freerun.c
@@ -0,0 +1,296 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_freerun.c
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 names NuttX nor Atmel 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
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "stm32_freerun.h"
+
+#ifdef CONFIG_STM32_FREERUN
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static struct stm32_freerun_s *g_freerun;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_freerun_handler
+ *
+ * Description:
+ * Timer interrupt callback. When the freerun timer counter overflows,
+ * this interrupt will occur. We will just increment an overflow count.
+ *
+ * Input Parameters:
+ * tch - The handle that represents the timer state
+ * arg - An opaque argument provided when the interrupt was registered
+ * sr - The value of the timer interrupt status register at the time
+ * that the interrupt occurred.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static int stm32_freerun_handler(int irq, void *context)
+{
+ struct stm32_freerun_s *freerun = g_freerun;
+
+ DEBUGASSERT(freerun != NULL && freerun->overflow < UINT32_MAX);
+ freerun->overflow++;
+
+ STM32_TIM_ACKINT(freerun->tch, 0);
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_freerun_initialize
+ *
+ * Description:
+ * Initialize the freerun timer wrapper
+ *
+ * Input Parameters:
+ * freerun Caller allocated instance of the freerun state structure
+ * chan Timer counter channel to be used.
+ * resolution The required resolution of the timer in units of
+ * microseconds. NOTE that the range is restricted to the
+ * range of uint16_t (excluding zero).
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_freerun_initialize(struct stm32_freerun_s *freerun, int chan,
+ uint16_t resolution)
+{
+ uint32_t frequency;
+
+ tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
+ DEBUGASSERT(freerun != NULL && resolution > 0);
+
+ /* Get the TC frequency the corresponds to the requested resolution */
+
+ frequency = USEC_PER_SEC / (uint32_t)resolution;
+ freerun->frequency = frequency;
+
+ freerun->tch = stm32_tim_init(chan);
+ if (!freerun->tch)
+ {
+ tmrerr("ERROR: Failed to allocate TIM%d\n", chan);
+ return -EBUSY;
+ }
+
+ STM32_TIM_SETCLOCK(freerun->tch, frequency);
+
+ /* Initialize the remaining fields in the state structure and return
+ * success.
+ */
+
+ freerun->chan = chan;
+ freerun->running = false;
+ freerun->overflow = 0;
+
+ g_freerun = freerun;
+
+ /* Set up to receive the callback when the counter overflow occurs */
+
+ STM32_TIM_SETISR(freerun->tch, stm32_freerun_handler, 0);
+
+ /* Set timer period */
+
+ STM32_TIM_SETPERIOD(freerun->tch, UINT32_MAX);
+
+ /* Start the counter */
+
+ STM32_TIM_SETMODE(freerun->tch, STM32_TIM_MODE_UP);
+ STM32_TIM_ACKINT(freerun->tch, 0);
+ STM32_TIM_ENABLEINT(freerun->tch, 0);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_freerun_counter
+ *
+ * Description:
+ * Read the counter register of the free-running timer.
+ *
+ * Input Parameters:
+ * freerun Caller allocated instance of the freerun state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_freerun_initialize();
+ * ts The location in which to return the time from the free-running
+ * timer.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_freerun_counter(struct stm32_freerun_s *freerun,
+ struct timespec *ts)
+{
+ uint64_t usec;
+ uint32_t counter;
+ uint32_t verify;
+ uint32_t overflow;
+ uint32_t sec;
+ int pending;
+ irqstate_t flags;
+
+ DEBUGASSERT(freerun && freerun->tch && ts);
+
+ /* Temporarily disable the overflow counter. NOTE that we have to be
+ * careful here because stm32_tc_getpending() will reset the pending
+ * interrupt status. If we do not handle the overflow here then, it will
+ * be lost.
+ */
+
+ flags = enter_critical_section();
+
+ overflow = freerun->overflow;
+ counter = STM32_TIM_GETCOUNTER(freerun->tch);
+ pending = STM32_TIM_CHECKINT(freerun->tch, 0);
+ verify = STM32_TIM_GETCOUNTER(freerun->tch);
+
+ /* If an interrupt was pending before we re-enabled interrupts,
+ * then the overflow needs to be incremented.
+ */
+
+ if (pending)
+ {
+ STM32_TIM_ACKINT(freerun->tch, 0);
+
+ /* Increment the overflow count and use the value of the
+ * guaranteed to be AFTER the overflow occurred.
+ */
+
+ overflow++;
+ counter = verify;
+
+ /* Update freerun overflow counter. */
+
+ freerun->overflow = overflow;
+ }
+
+ leave_critical_section(flags);
+
+ tmrinfo("counter=%lu (%lu) overflow=%lu, pending=%i\n",
+ (unsigned long)counter, (unsigned long)verify,
+ (unsigned long)overflow, pending);
+ tmrinfo("frequency=%u\n", freerun->frequency);
+
+ /* Convert the whole thing to units of microseconds.
+ *
+ * frequency = ticks / second
+ * seconds = ticks * frequency
+ * usecs = (ticks * USEC_PER_SEC) / frequency;
+ */
+
+ usec = ((((uint64_t)overflow << 32) + (uint64_t)counter) * USEC_PER_SEC) /
+ freerun->frequency;
+
+ /* And return the value of the timer */
+
+ sec = (uint32_t)(usec / USEC_PER_SEC);
+ ts->tv_sec = sec;
+ ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
+
+ tmrinfo("usec=%llu ts=(%u, %lu)\n",
+ usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_freerun_uninitialize
+ *
+ * Description:
+ * Stop the free-running timer and release all resources that it uses.
+ *
+ * Input Parameters:
+ * freerun Caller allocated instance of the freerun state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_freerun_initialize();
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_freerun_uninitialize(struct stm32_freerun_s *freerun)
+{
+ DEBUGASSERT(freerun && freerun->tch);
+
+ /* Now we can disable the timer interrupt and disable the timer. */
+
+ STM32_TIM_DISABLEINT(freerun->tch, 0);
+ STM32_TIM_SETMODE(freerun->tch, STM32_TIM_MODE_DISABLED);
+ STM32_TIM_SETISR(freerun->tch, NULL, 0);
+
+ /* Free the timer */
+
+ stm32_tim_deinit(freerun->tch);
+ freerun->tch = NULL;
+
+ g_freerun = NULL;
+ return OK;
+}
+
+#endif /* CONFIG_STM32_ONESHOT */
diff --git a/arch/arm/src/stm32/stm32_freerun.h b/arch/arm/src/stm32/stm32_freerun.h
new file mode 100644
index 0000000000000000000000000000000000000000..08dd1786da7cb3d73e95913e7c5a6abf9e44b757
--- /dev/null
+++ b/arch/arm/src/stm32/stm32_freerun.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_freerun.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_STM32_FREERUN_H
+#define __ARCH_ARM_SRC_STM32_FREERUN_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+
+#include "stm32_tim.h"
+
+#ifdef CONFIG_STM32_FREERUN
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* The freerun client must allocate an instance of this structure and called
+ * stm32_freerun_initialize() before using the freerun facilities. The client
+ * should not access the contents of this structure directly since the
+ * contents are subject to change.
+ */
+
+struct stm32_freerun_s
+{
+ uint8_t chan; /* The timer/counter in use */
+ bool running; /* True: the timer is running */
+ uint32_t overflow; /* Timer counter overflow */
+ FAR struct stm32_tim_dev_s *tch; /* Handle returned by stm32_tim_init() */
+ uint32_t frequency;
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_freerun_initialize
+ *
+ * Description:
+ * Initialize the freerun timer wrapper
+ *
+ * Input Parameters:
+ * freerun Caller allocated instance of the freerun state structure
+ * chan Timer counter channel to be used.
+ * resolution The required resolution of the timer in units of
+ * microseconds. NOTE that the range is restricted to the
+ * range of uint16_t (excluding zero).
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_freerun_initialize(struct stm32_freerun_s *freerun, int chan,
+ uint16_t resolution);
+
+/****************************************************************************
+ * Name: stm32_freerun_counter
+ *
+ * Description:
+ * Read the counter register of the free-running timer.
+ *
+ * Input Parameters:
+ * freerun Caller allocated instance of the freerun state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_freerun_initialize();
+ * ts The location in which to return the time remaining on the
+ * oneshot timer.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_freerun_counter(struct stm32_freerun_s *freerun,
+ struct timespec *ts);
+
+/****************************************************************************
+ * Name: stm32_freerun_uninitialize
+ *
+ * Description:
+ * Stop the free-running timer and release all resources that it uses.
+ *
+ * Input Parameters:
+ * freerun Caller allocated instance of the freerun state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_freerun_initialize();
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_freerun_uninitialize(struct stm32_freerun_s *freerun);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONFIG_STM32_FREERUN */
+#endif /* __ARCH_ARM_SRC_STM32_FREERUN_H */
diff --git a/arch/arm/src/stm32/stm32_irq.c b/arch/arm/src/stm32/stm32_irq.c
index 062d63fb7499afddac41d1dfac7f9b0b31f45e7e..ea7c4ddfcbe1d1039a2ab46567ef8beb772e815e 100644
--- a/arch/arm/src/stm32/stm32_irq.c
+++ b/arch/arm/src/stm32/stm32_irq.c
@@ -245,31 +245,23 @@ static inline void stm32_prioritize_syscall(int priority)
static int stm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit,
uintptr_t offset)
{
+ int n;
+
DEBUGASSERT(irq >= STM32_IRQ_NMI && irq < NR_IRQS);
/* Check for external interrupt */
if (irq >= STM32_IRQ_FIRST)
{
- if (irq < STM32_IRQ_FIRST + 32)
- {
- *regaddr = (NVIC_IRQ0_31_ENABLE + offset);
- *bit = 1 << (irq - STM32_IRQ_FIRST);
- }
- else if (irq < STM32_IRQ_FIRST + 64)
- {
- *regaddr = (NVIC_IRQ32_63_ENABLE + offset);
- *bit = 1 << (irq - STM32_IRQ_FIRST - 32);
- }
- else if (irq < NR_IRQS)
- {
- *regaddr = (NVIC_IRQ64_95_ENABLE + offset);
- *bit = 1 << (irq - STM32_IRQ_FIRST - 64);
- }
- else
+ n = irq - STM32_IRQ_FIRST;
+ *regaddr = NVIC_IRQ_ENABLE(n) + offset;
+
+ while (n >= 32)
{
- return ERROR; /* Invalid interrupt */
+ n -= 32;
}
+
+ *bit = 1 << n;
}
/* Handle processor exceptions. Only a few can be disabled */
@@ -315,11 +307,14 @@ void up_irqinitialize(void)
{
uint32_t regaddr;
int num_priority_registers;
+ int i;
/* Disable all interrupts */
- putreg32(0, NVIC_IRQ0_31_ENABLE);
- putreg32(0, NVIC_IRQ32_63_ENABLE);
+ for (i = 0; i < NR_IRQS - STM32_IRQ_FIRST; i += 32)
+ {
+ putreg32(0xffffffff, NVIC_IRQ_CLEAR(i));
+ }
/* Colorize the interrupt stack for debug purposes */
diff --git a/arch/arm/src/stm32/stm32_oneshot.c b/arch/arm/src/stm32/stm32_oneshot.c
new file mode 100644
index 0000000000000000000000000000000000000000..8f5e89df6229ebff2cee0a7c966254b82bca4311
--- /dev/null
+++ b/arch/arm/src/stm32/stm32_oneshot.c
@@ -0,0 +1,415 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_oneshot.c
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 names NuttX nor Atmel 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
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "stm32_oneshot.h"
+
+#ifdef CONFIG_STM32_ONESHOT
+
+/****************************************************************************
+ * Private Date
+ ****************************************************************************/
+
+static struct stm32_oneshot_s *g_oneshot;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_oneshot_handler
+ *
+ * Description:
+ * Timer interrupt callback. When the oneshot timer interrupt expires,
+ * this function will be called. It will forward the call to the next
+ * level up.
+ *
+ * Input Parameters:
+ * tch - The handle that represents the timer state
+ * arg - An opaque argument provided when the interrupt was registered
+ * sr - The value of the timer interrupt status register at the time
+ * that the interrupt occurred.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static int stm32_oneshot_handler(int irq, void *context)
+{
+ struct stm32_oneshot_s *oneshot = g_oneshot;
+ oneshot_handler_t oneshot_handler;
+ void *oneshot_arg;
+
+ tmrinfo("Expired...\n");
+ DEBUGASSERT(oneshot != NULL && oneshot->handler);
+
+ /* The clock was stopped, but not disabled when the RC match occurred.
+ * Disable the TC now and disable any further interrupts.
+ */
+
+ STM32_TIM_SETMODE(oneshot->tch, STM32_TIM_MODE_DISABLED);
+ STM32_TIM_ACKINT(oneshot->tch, 0);
+ STM32_TIM_DISABLEINT(oneshot->tch, 0);
+
+ /* The timer is no longer running */
+
+ oneshot->running = false;
+
+ /* Forward the event, clearing out any vestiges */
+
+ oneshot_handler = (oneshot_handler_t)oneshot->handler;
+ oneshot->handler = NULL;
+ oneshot_arg = (void *)oneshot->arg;
+ oneshot->arg = NULL;
+
+ oneshot_handler(oneshot_arg);
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_oneshot_initialize
+ *
+ * Description:
+ * Initialize the oneshot timer wrapper
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure
+ * chan Timer counter channel to be used.
+ * resolution The required resolution of the timer in units of
+ * microseconds. NOTE that the range is restricted to the
+ * range of uint16_t (excluding zero).
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_initialize(struct stm32_oneshot_s *oneshot, int chan,
+ uint16_t resolution)
+{
+ uint32_t frequency;
+
+ tmrinfo("chan=%d resolution=%d usec\n", chan, resolution);
+ DEBUGASSERT(oneshot && resolution > 0);
+
+ /* Get the TC frequency the corresponds to the requested resolution */
+
+ frequency = USEC_PER_SEC / (uint32_t)resolution;
+ oneshot->frequency = frequency;
+
+ oneshot->tch = stm32_tim_init(chan);
+ if (!oneshot->tch)
+ {
+ tmrerr("ERROR: Failed to allocate TIM%d\n", chan);
+ return -EBUSY;
+ }
+
+ STM32_TIM_SETCLOCK(oneshot->tch, frequency);
+
+ /* Initialize the remaining fields in the state structure and return
+ * success.
+ */
+
+ oneshot->chan = chan;
+ oneshot->running = false;
+ oneshot->handler = NULL;
+ oneshot->arg = NULL;
+
+ g_oneshot = oneshot;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_oneshot_max_delay
+ *
+ * Description:
+ * Determine the maximum delay of the one-shot timer (in microseconds)
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_max_delay(struct stm32_oneshot_s *oneshot, uint64_t *usec)
+{
+ DEBUGASSERT(oneshot != NULL && usec != NULL);
+
+ *usec = (uint64_t)(UINT32_MAX / oneshot->frequency) *
+ (uint64_t)USEC_PER_SEC;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_oneshot_start
+ *
+ * Description:
+ * Start the oneshot timer
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_oneshot_initialize();
+ * handler The function to call when when the oneshot timer expires.
+ * arg An opaque argument that will accompany the callback.
+ * ts Provides the duration of the one shot timer.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_start(struct stm32_oneshot_s *oneshot,
+ oneshot_handler_t handler, void *arg,
+ const struct timespec *ts)
+{
+ uint64_t usec;
+ uint64_t period;
+ irqstate_t flags;
+
+ tmrinfo("handler=%p arg=%p, ts=(%lu, %lu)\n",
+ handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
+ DEBUGASSERT(oneshot && handler && ts);
+ DEBUGASSERT(oneshot->tch);
+
+ /* Was the oneshot already running? */
+
+ flags = enter_critical_section();
+ if (oneshot->running)
+ {
+ /* Yes.. then cancel it */
+
+ tmrinfo("Already running... cancelling\n");
+ (void)stm32_oneshot_cancel(oneshot, NULL);
+ }
+
+ /* Save the new handler and its argument */
+
+ oneshot->handler = handler;
+ oneshot->arg = arg;
+
+ /* Express the delay in microseconds */
+
+ usec = (uint64_t)ts->tv_sec * USEC_PER_SEC +
+ (uint64_t)(ts->tv_nsec / NSEC_PER_USEC);
+
+ /* Get the timer counter frequency and determine the number of counts need
+ * to achieve the requested delay.
+ *
+ * frequency = ticks / second
+ * ticks = seconds * frequency
+ * = (usecs * frequency) / USEC_PER_SEC;
+ */
+
+ period = (usec * (uint64_t)oneshot->frequency) / USEC_PER_SEC;
+
+ tmrinfo("usec=%llu period=%08llx\n", usec, period);
+ DEBUGASSERT(period <= UINT32_MAX);
+
+ /* Set up to receive the callback when the interrupt occurs */
+
+ STM32_TIM_SETISR(oneshot->tch, stm32_oneshot_handler, 0);
+
+ /* Set timer period */
+
+ oneshot->period = (uint32_t)period;
+ STM32_TIM_SETPERIOD(oneshot->tch, (uint32_t)period);
+
+ /* Start the counter */
+
+ STM32_TIM_SETMODE(oneshot->tch, STM32_TIM_MODE_PULSE);
+
+ STM32_TIM_ACKINT(oneshot->tch, 0);
+ STM32_TIM_ENABLEINT(oneshot->tch, 0);
+
+ /* Enable interrupts. We should get the callback when the interrupt
+ * occurs.
+ */
+
+ oneshot->running = true;
+ leave_critical_section(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_oneshot_cancel
+ *
+ * Description:
+ * Cancel the oneshot timer and return the time remaining on the timer.
+ *
+ * NOTE: This function may execute at a high rate with no timer running (as
+ * when pre-emption is enabled and disabled).
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_oneshot_initialize();
+ * ts The location in which to return the time remaining on the
+ * oneshot timer. A time of zero is returned if the timer is
+ * not running. ts may be zero in which case the time remaining
+ * is not returned.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. A call to up_timer_cancel() when
+ * the timer is not active should also return success; a negated errno
+ * value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_cancel(struct stm32_oneshot_s *oneshot,
+ struct timespec *ts)
+{
+ irqstate_t flags;
+ uint64_t usec;
+ uint64_t sec;
+ uint64_t nsec;
+ uint32_t count;
+ uint32_t period;
+
+ /* Was the timer running? */
+
+ flags = enter_critical_section();
+ if (!oneshot->running)
+ {
+ /* No.. Just return zero timer remaining and successful cancellation.
+ * This function may execute at a high rate with no timer running
+ * (as when pre-emption is enabled and disabled).
+ */
+
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ leave_critical_section(flags);
+ return OK;
+ }
+
+ /* Yes.. Get the timer counter and period registers and stop the counter.
+ * If the counter expires while we are doing this, the counter clock will
+ * be stopped, but the clock will not be disabled.
+ *
+ * The expected behavior is that the the counter register will freezes at
+ * a value equal to the RC register when the timer expires. The counter
+ * should have values between 0 and RC in all other cased.
+ *
+ * REVISIT: This does not appear to be the case.
+ */
+
+ tmrinfo("Cancelling...\n");
+
+ count = STM32_TIM_GETCOUNTER(oneshot->tch);
+ period = oneshot->period;
+
+ /* Now we can disable the interrupt and stop the timer. */
+
+ STM32_TIM_DISABLEINT(oneshot->tch, 0);
+ STM32_TIM_SETMODE(oneshot->tch, STM32_TIM_MODE_DISABLED);
+
+ oneshot->running = false;
+ oneshot->handler = NULL;
+ oneshot->arg = NULL;
+ leave_critical_section(flags);
+
+ /* Did the caller provide us with a location to return the time
+ * remaining?
+ */
+
+ if (ts)
+ {
+ /* Yes.. then calculate and return the time remaining on the
+ * oneshot timer.
+ */
+
+ tmrinfo("period=%lu count=%lu\n",
+ (unsigned long)period, (unsigned long)count);
+
+ /* REVISIT: I am not certain why the timer counter value sometimes
+ * exceeds RC. Might be a bug, or perhaps the counter does not stop
+ * in all cases.
+ */
+
+ if (count >= period)
+ {
+ /* No time remaining (?) */
+
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ }
+ else
+ {
+ /* The total time remaining is the difference. Convert the that
+ * to units of microseconds.
+ *
+ * frequency = ticks / second
+ * seconds = ticks * frequency
+ * usecs = (ticks * USEC_PER_SEC) / frequency;
+ */
+
+ usec = (((uint64_t)(period - count)) * USEC_PER_SEC) /
+ oneshot->frequency;
+
+ /* Return the time remaining in the correct form */
+
+ sec = usec / USEC_PER_SEC;
+ nsec = ((usec) - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
+
+ ts->tv_sec = (time_t)sec;
+ ts->tv_nsec = (unsigned long)nsec;
+ }
+
+ tmrinfo("remaining (%lu, %lu)\n",
+ (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
+ }
+
+ return OK;
+}
+
+#endif /* CONFIG_STM32_ONESHOT */
diff --git a/arch/arm/src/stm32/stm32_oneshot.h b/arch/arm/src/stm32/stm32_oneshot.h
new file mode 100644
index 0000000000000000000000000000000000000000..bff21319393237845d02b0522ce0f36886838c05
--- /dev/null
+++ b/arch/arm/src/stm32/stm32_oneshot.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_oneshot.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_STM32_ONESHOT_H
+#define __ARCH_ARM_SRC_STM32_ONESHOT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+
+#include "stm32_tim.h"
+
+#ifdef CONFIG_STM32_ONESHOT
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* This describes the callback function that will be invoked when the oneshot
+ * timer expires. The oneshot fires, the client will receive:
+ *
+ * arg - The opaque argument provided when the interrupt was registered
+ */
+
+typedef void (*oneshot_handler_t)(void *arg);
+
+/* The oneshot client must allocate an instance of this structure and called
+ * stm32_oneshot_initialize() before using the oneshot facilities. The client
+ * should not access the contents of this structure directly since the
+ * contents are subject to change.
+ */
+
+struct stm32_oneshot_s
+{
+ uint8_t chan; /* The timer/counter in use */
+ volatile bool running; /* True: the timer is running */
+ FAR struct stm32_tim_dev_s *tch; /* Pointer returned by
+ * stm32_tim_init() */
+ volatile oneshot_handler_t handler; /* Oneshot expiration callback */
+ volatile void *arg; /* The argument that will accompany
+ * the callback */
+ uint32_t frequency;
+ uint32_t period;
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_oneshot_initialize
+ *
+ * Description:
+ * Initialize the oneshot timer wrapper
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure
+ * chan Timer counter channel to be used.
+ * resolution The required resolution of the timer in units of
+ * microseconds. NOTE that the range is restricted to the
+ * range of uint16_t (excluding zero).
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_initialize(struct stm32_oneshot_s *oneshot, int chan,
+ uint16_t resolution);
+
+/****************************************************************************
+ * Name: stm32_oneshot_max_delay
+ *
+ * Description:
+ * Determine the maximum delay of the one-shot timer (in microseconds)
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_max_delay(struct stm32_oneshot_s *oneshot, uint64_t *usec);
+
+/****************************************************************************
+ * Name: stm32_oneshot_start
+ *
+ * Description:
+ * Start the oneshot timer
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_oneshot_initialize();
+ * handler The function to call when when the oneshot timer expires.
+ * arg An opaque argument that will accompany the callback.
+ * ts Provides the duration of the one shot timer.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_start(struct stm32_oneshot_s *oneshot,
+ oneshot_handler_t handler, void *arg,
+ const struct timespec *ts);
+
+/****************************************************************************
+ * Name: stm32_oneshot_cancel
+ *
+ * Description:
+ * Cancel the oneshot timer and return the time remaining on the timer.
+ *
+ * NOTE: This function may execute at a high rate with no timer running (as
+ * when pre-emption is enabled and disabled).
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_oneshot_initialize();
+ * ts The location in which to return the time remaining on the
+ * oneshot timer. A time of zero is returned if the timer is
+ * not running.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. A call to up_timer_cancel() when
+ * the timer is not active should also return success; a negated errno
+ * value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_cancel(struct stm32_oneshot_s *oneshot,
+ struct timespec *ts);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONFIG_STM32_ONESHOT */
+#endif /* __ARCH_ARM_SRC_STM32_ONESHOT_H */
diff --git a/arch/arm/src/stm32/stm32_tickless.c b/arch/arm/src/stm32/stm32_tickless.c
new file mode 100644
index 0000000000000000000000000000000000000000..eadef5ce90db97c91eb797d5e03648a495ce44ed
--- /dev/null
+++ b/arch/arm/src/stm32/stm32_tickless.c
@@ -0,0 +1,350 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_tickless.c
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * Tickless OS Support.
+ *
+ * When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts
+ * is suppressed and the platform specific code is expected to provide the
+ * following custom functions.
+ *
+ * void up_timer_initialize(void): Initializes the timer facilities.
+ * Called early in the initialization sequence (by up_intialize()).
+ * int up_timer_gettime(FAR struct timespec *ts): Returns the current
+ * time from the platform specific time source.
+ * int up_timer_cancel(void): Cancels the interval timer.
+ * int up_timer_start(FAR const struct timespec *ts): Start (or re-starts)
+ * the interval timer.
+ *
+ * The RTOS will provide the following interfaces for use by the platform-
+ * specific interval timer implementation:
+ *
+ * void sched_timer_expiration(void): Called by the platform-specific
+ * logic when the interval timer expires.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * SAM34 Timer Usage
+ *
+ * This current implementation uses two timers: A one-shot timer to provide
+ * the timed events and a free running timer to provide the current time.
+ * Since timers are a limited resource, that could be an issue on some
+ * systems.
+ *
+ * We could do the job with a single timer if we were to keep the single
+ * timer in a free-running at all times. The STM32 timer/counters have
+ * 16-bit/32-bit counters with the capability to generate a compare interrupt
+ * when the timer matches a compare value but also to continue counting
+ * without stopping (giving another, different interrupt when the timer
+ * rolls over from 0xffffffff to zero). So we could potentially just set
+ * the compare at the number of ticks you want PLUS the current value of
+ * timer. Then you could have both with a single timer: An interval timer
+ * and a free-running counter with the same timer!
+ *
+ * Patches are welcome!
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include "stm32_oneshot.h"
+#include "stm32_freerun.h"
+
+#ifdef CONFIG_SCHED_TICKLESS
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_STM32_ONESHOT
+# error CONFIG_STM32_ONESHOT must be selected for the Tickless OS option
+#endif
+
+#ifndef CONFIG_STM32_FREERUN
+# error CONFIG_STM32_FREERUN must be selected for the Tickless OS option
+#endif
+
+#ifndef CONFIG_STM32_TICKLESS_FREERUN
+# error CONFIG_STM32_TICKLESS_FREERUN must be selected for the Tickless OS option
+#endif
+
+#ifndef CONFIG_STM32_TICKLESS_ONESHOT
+# error CONFIG_STM32_TICKLESS_ONESHOT must be selected for the Tickless OS option
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct stm32_tickless_s
+{
+ struct stm32_oneshot_s oneshot;
+ struct stm32_freerun_s freerun;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct stm32_tickless_s g_tickless;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_oneshot_handler
+ *
+ * Description:
+ * Called when the one shot timer expires
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Called early in the initialization sequence before any special
+ * concurrency protections are required.
+ *
+ ****************************************************************************/
+
+static void stm32_oneshot_handler(void *arg)
+{
+ tmrinfo("Expired...\n");
+ sched_timer_expiration();
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_timer_initialize
+ *
+ * Description:
+ * Initializes all platform-specific timer facilities. This function is
+ * called early in the initialization sequence by up_intialize().
+ * On return, the current up-time should be available from
+ * up_timer_gettime() and the interval timer is ready for use (but not
+ * actively timing.
+ *
+ * Provided by platform-specific code and called from the architecture-
+ * specific logic.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Called early in the initialization sequence before any special
+ * concurrency protections are required.
+ *
+ ****************************************************************************/
+
+void up_timer_initialize(void)
+{
+#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
+ uint64_t max_delay;
+#endif
+ int ret;
+
+ /* Initialize the one-shot timer */
+
+ ret = stm32_oneshot_initialize(&g_tickless.oneshot,
+ CONFIG_STM32_TICKLESS_ONESHOT,
+ CONFIG_USEC_PER_TICK);
+ if (ret < 0)
+ {
+ tmrerr("ERROR: stm32_oneshot_initialize failed\n");
+ PANIC();
+ }
+
+#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
+ /* Get the maximum delay of the one-shot timer in microseconds */
+
+ ret = stm32_oneshot_max_delay(&g_tickless.oneshot, &max_delay);
+ if (ret < 0)
+ {
+ tmrerr("ERROR: stm32_oneshot_max_delay failed\n");
+ PANIC();
+ }
+
+ /* Convert this to configured clock ticks for use by the OS timer logic */
+
+ max_delay /= CONFIG_USEC_PER_TICK;
+ if (max_delay > UINT32_MAX)
+ {
+ g_oneshot_maxticks = UINT32_MAX;
+ }
+ else
+ {
+ g_oneshot_maxticks = max_delay;
+ }
+#endif
+
+ /* Initialize the free-running timer */
+
+ ret = stm32_freerun_initialize(&g_tickless.freerun,
+ CONFIG_STM32_TICKLESS_FREERUN,
+ CONFIG_USEC_PER_TICK);
+ if (ret < 0)
+ {
+ tmrerr("ERROR: stm32_freerun_initialize failed\n");
+ PANIC();
+ }
+}
+
+/****************************************************************************
+ * Name: up_timer_gettime
+ *
+ * Description:
+ * Return the elapsed time since power-up (or, more correctly, since
+ * up_timer_initialize() was called). This function is functionally
+ * equivalent to:
+ *
+ * int clock_gettime(clockid_t clockid, FAR struct timespec *ts);
+ *
+ * when clockid is CLOCK_MONOTONIC.
+ *
+ * This function provides the basis for reporting the current time and
+ * also is used to eliminate error build-up from small errors in interval
+ * time calculations.
+ *
+ * Provided by platform-specific code and called from the RTOS base code.
+ *
+ * Input Parameters:
+ * ts - Provides the location in which to return the up-time.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure.
+ *
+ * Assumptions:
+ * Called from the the normal tasking context. The implementation must
+ * provide whatever mutual exclusion is necessary for correct operation.
+ * This can include disabling interrupts in order to assure atomic register
+ * operations.
+ *
+ ****************************************************************************/
+
+int up_timer_gettime(FAR struct timespec *ts)
+{
+ return stm32_freerun_counter(&g_tickless.freerun, ts);
+}
+
+/****************************************************************************
+ * Name: up_timer_cancel
+ *
+ * Description:
+ * Cancel the interval timer and return the time remaining on the timer.
+ * These two steps need to be as nearly atomic as possible.
+ * sched_timer_expiration() will not be called unless the timer is
+ * restarted with up_timer_start().
+ *
+ * If, as a race condition, the timer has already expired when this
+ * function is called, then that pending interrupt must be cleared so
+ * that up_timer_start() and the remaining time of zero should be
+ * returned.
+ *
+ * NOTE: This function may execute at a high rate with no timer running (as
+ * when pre-emption is enabled and disabled).
+ *
+ * Provided by platform-specific code and called from the RTOS base code.
+ *
+ * Input Parameters:
+ * ts - Location to return the remaining time. Zero should be returned
+ * if the timer is not active. ts may be zero in which case the
+ * time remaining is not returned.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. A call to up_timer_cancel() when
+ * the timer is not active should also return success; a negated errno
+ * value is returned on any failure.
+ *
+ * Assumptions:
+ * May be called from interrupt level handling or from the normal tasking
+ * level. Interrupts may need to be disabled internally to assure
+ * non-reentrancy.
+ *
+ ****************************************************************************/
+
+int up_timer_cancel(FAR struct timespec *ts)
+{
+ return stm32_oneshot_cancel(&g_tickless.oneshot, ts);
+}
+
+/****************************************************************************
+ * Name: up_timer_start
+ *
+ * Description:
+ * Start the interval timer. sched_timer_expiration() will be
+ * called at the completion of the timeout (unless up_timer_cancel
+ * is called to stop the timing.
+ *
+ * Provided by platform-specific code and called from the RTOS base code.
+ *
+ * Input Parameters:
+ * ts - Provides the time interval until sched_timer_expiration() is
+ * called.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure.
+ *
+ * Assumptions:
+ * May be called from interrupt level handling or from the normal tasking
+ * level. Interrupts may need to be disabled internally to assure
+ * non-reentrancy.
+ *
+ ****************************************************************************/
+
+int up_timer_start(FAR const struct timespec *ts)
+{
+ return stm32_oneshot_start(&g_tickless.oneshot, stm32_oneshot_handler, NULL, ts);
+}
+#endif /* CONFIG_SCHED_TICKLESS */
diff --git a/arch/arm/src/stm32/stm32_tim.c b/arch/arm/src/stm32/stm32_tim.c
index 62e2783e3a8ff1281fad5e58e35f2259a7ff0128..ff470b3065cf118062a182e5293962a7f6020ce8 100644
--- a/arch/arm/src/stm32/stm32_tim.c
+++ b/arch/arm/src/stm32/stm32_tim.c
@@ -64,8 +64,9 @@
#include "stm32_tim.h"
/************************************************************************************
- * Private Types
+ * Pre-processor Definitions
************************************************************************************/
+
/* Configuration ********************************************************************/
/* Timer devices may be used for different purposes. Such special purposes include:
*
@@ -157,9 +158,12 @@
# undef CONFIG_STM32_TIM17
#endif
+#undef HAVE_TIM_GPIOCONFIG
#if defined(CONFIG_STM32_TIM1)
# if defined(GPIO_TIM1_CH1OUT) ||defined(GPIO_TIM1_CH2OUT)||\
defined(GPIO_TIM1_CH3OUT) ||defined(GPIO_TIM1_CH4OUT)
+# undef HAVE_TIM_GPIOCONFIG
+# define HAVE_TIM_GPIOCONFIG 1
# define HAVE_TIM1_GPIOCONFIG 1
#endif
#endif
@@ -167,6 +171,8 @@
#if defined(CONFIG_STM32_TIM2)
# if defined(GPIO_TIM2_CH1OUT) ||defined(GPIO_TIM2_CH2OUT)||\
defined(GPIO_TIM2_CH3OUT) ||defined(GPIO_TIM2_CH4OUT)
+# undef HAVE_TIM_GPIOCONFIG
+# define HAVE_TIM_GPIOCONFIG 1
# define HAVE_TIM2_GPIOCONFIG 1
#endif
#endif
@@ -174,6 +180,8 @@
#if defined(CONFIG_STM32_TIM3)
# if defined(GPIO_TIM3_CH1OUT) ||defined(GPIO_TIM3_CH2OUT)||\
defined(GPIO_TIM3_CH3OUT) ||defined(GPIO_TIM3_CH4OUT)
+# undef HAVE_TIM_GPIOCONFIG
+# define HAVE_TIM_GPIOCONFIG 1
# define HAVE_TIM3_GPIOCONFIG 1
#endif
#endif
@@ -181,6 +189,8 @@
#if defined(CONFIG_STM32_TIM4)
# if defined(GPIO_TIM4_CH1OUT) ||defined(GPIO_TIM4_CH2OUT)||\
defined(GPIO_TIM4_CH3OUT) ||defined(GPIO_TIM4_CH4OUT)
+# undef HAVE_TIM_GPIOCONFIG
+# define HAVE_TIM_GPIOCONFIG 1
# define HAVE_TIM4_GPIOCONFIG 1
#endif
#endif
@@ -188,6 +198,8 @@
#if defined(CONFIG_STM32_TIM5)
# if defined(GPIO_TIM5_CH1OUT) ||defined(GPIO_TIM5_CH2OUT)||\
defined(GPIO_TIM5_CH3OUT) ||defined(GPIO_TIM5_CH4OUT)
+# undef HAVE_TIM_GPIOCONFIG
+# define HAVE_TIM_GPIOCONFIG 1
# define HAVE_TIM5_GPIOCONFIG 1
#endif
#endif
@@ -195,6 +207,8 @@
#if defined(CONFIG_STM32_TIM8)
# if defined(GPIO_TIM8_CH1OUT) ||defined(GPIO_TIM8_CH2OUT)||\
defined(GPIO_TIM8_CH3OUT) ||defined(GPIO_TIM8_CH4OUT)
+# undef HAVE_TIM_GPIOCONFIG
+# define HAVE_TIM_GPIOCONFIG 1
# define HAVE_TIM8_GPIOCONFIG 1
#endif
#endif
@@ -284,16 +298,243 @@
struct stm32_tim_priv_s
{
- struct stm32_tim_ops_s *ops;
- stm32_tim_mode_t mode;
- uint32_t base; /* TIMn base address */
+ const struct stm32_tim_ops_s *ops;
+ stm32_tim_mode_t mode;
+ uint32_t base; /* TIMn base address */
+};
+
+/************************************************************************************
+ * Private Function prototypes
+ ************************************************************************************/
+
+/* Register helpers */
+
+static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev,
+ uint8_t offset);
+static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset,
+ uint16_t value);
+static inline void stm32_modifyreg16(FAR struct stm32_tim_dev_s *dev,
+ uint8_t offset, uint16_t clearbits,
+ uint16_t setbits);
+static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev,
+ uint8_t offset);
+static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, uint8_t offset,
+ uint32_t value);
+
+/* Timer helpers */
+
+static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev);
+static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev);
+static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev);
+static void stm32_tim_reset(FAR struct stm32_tim_dev_s *dev);
+
+#ifdef HAVE_TIM_GPIOCONFIG
+static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode);
+#endif
+
+/* Timer methods */
+
+static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode);
+static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq);
+static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev,
+ uint32_t period);
+static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev);
+static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
+ stm32_tim_channel_t mode);
+static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
+ uint32_t compare);
+static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel);
+static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev,
+ int (*handler)(int irq, void *context),
+ int source);
+static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source);
+static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source);
+static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source);
+static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source);
+
+/************************************************************************************
+ * Private Data
+ ************************************************************************************/
+
+static const struct stm32_tim_ops_s stm32_tim_ops =
+{
+ .setmode = stm32_tim_setmode,
+ .setclock = stm32_tim_setclock,
+ .setperiod = stm32_tim_setperiod,
+ .getcounter = stm32_tim_getcounter,
+ .setchannel = stm32_tim_setchannel,
+ .setcompare = stm32_tim_setcompare,
+ .getcapture = stm32_tim_getcapture,
+ .setisr = stm32_tim_setisr,
+ .enableint = stm32_tim_enableint,
+ .disableint = stm32_tim_disableint,
+ .ackint = stm32_tim_ackint,
+ .checkint = stm32_tim_checkint,
+};
+
+#ifdef CONFIG_STM32_TIM1
+struct stm32_tim_priv_s stm32_tim1_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM1_BASE,
+};
+#endif
+#ifdef CONFIG_STM32_TIM2
+struct stm32_tim_priv_s stm32_tim2_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM2_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM3
+struct stm32_tim_priv_s stm32_tim3_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM3_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM4
+struct stm32_tim_priv_s stm32_tim4_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM4_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM5
+struct stm32_tim_priv_s stm32_tim5_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM5_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM6
+struct stm32_tim_priv_s stm32_tim6_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM6_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM7
+struct stm32_tim_priv_s stm32_tim7_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM7_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM8
+struct stm32_tim_priv_s stm32_tim8_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM8_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM9
+struct stm32_tim_priv_s stm32_tim9_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM9_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM10
+struct stm32_tim_priv_s stm32_tim10_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM10_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM11
+struct stm32_tim_priv_s stm32_tim11_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM11_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM12
+struct stm32_tim_priv_s stm32_tim12_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM12_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM13
+struct stm32_tim_priv_s stm32_tim13_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM13_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM14
+struct stm32_tim_priv_s stm32_tim14_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM14_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM15
+struct stm32_tim_priv_s stm32_tim15_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM15_BASE,
};
+#endif
+
+#ifdef CONFIG_STM32_TIM16
+struct stm32_tim_priv_s stm32_tim16_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM16_BASE,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM17
+struct stm32_tim_priv_s stm32_tim17_priv =
+{
+ .ops = &stm32_tim_ops,
+ .mode = STM32_TIM_MODE_UNUSED,
+ .base = STM32_TIM17_BASE,
+};
+#endif
/************************************************************************************
* Private Functions
************************************************************************************/
-/* Get a 16-bit register value by offset */
+/************************************************************************************
+ * Name: stm32_getreg16
+ *
+ * Description:
+ * Get a 16-bit register value by offset
+ *
+ ************************************************************************************/
static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev,
uint8_t offset)
@@ -301,7 +542,13 @@ static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev,
return getreg16(((struct stm32_tim_priv_s *)dev)->base + offset);
}
-/* Put a 16-bit register value by offset */
+/************************************************************************************
+ * Name: stm32_putreg16
+ *
+ * Description:
+ * Put a 16-bit register value by offset
+ *
+ ************************************************************************************/
static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset,
uint16_t value)
@@ -309,7 +556,13 @@ static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offse
putreg16(value, ((struct stm32_tim_priv_s *)dev)->base + offset);
}
-/* Modify a 16-bit register value by offset */
+/************************************************************************************
+ * Name: stm32_modifyreg16
+ *
+ * Description:
+ * Modify a 16-bit register value by offset
+ *
+ ************************************************************************************/
static inline void stm32_modifyreg16(FAR struct stm32_tim_dev_s *dev,
uint8_t offset, uint16_t clearbits,
@@ -318,9 +571,14 @@ static inline void stm32_modifyreg16(FAR struct stm32_tim_dev_s *dev,
modifyreg16(((struct stm32_tim_priv_s *)dev)->base + offset, clearbits, setbits);
}
-/* Get a 32-bit register value by offset. This applies only for the STM32 F4
- * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5.
- */
+/************************************************************************************
+ * Name: stm32_getreg32
+ *
+ * Description:
+ * Get a 32-bit register value by offset. This applies only for the STM32 F4
+ * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5.
+ *
+ ************************************************************************************/
static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev,
uint8_t offset)
@@ -328,9 +586,14 @@ static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev,
return getreg32(((struct stm32_tim_priv_s *)dev)->base + offset);
}
-/* Put a 32-bit register value by offset. This applies only for the STM32 F4
- * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5.
- */
+/************************************************************************************
+ * Name: stm32_putreg32
+ *
+ * Description:
+ * Put a 32-bit register value by offset. This applies only for the STM32 F4
+ * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5.
+ *
+ ************************************************************************************/
static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, uint8_t offset,
uint32_t value)
@@ -338,6 +601,10 @@ static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, uint8_t offse
putreg32(value, ((struct stm32_tim_priv_s *)dev)->base + offset);
}
+/************************************************************************************
+ * Name: stm32_tim_reload_counter
+ ************************************************************************************/
+
static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev)
{
uint16_t val = stm32_getreg16(dev, STM32_BTIM_EGR_OFFSET);
@@ -345,6 +612,10 @@ static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev)
stm32_putreg16(dev, STM32_BTIM_EGR_OFFSET, val);
}
+/************************************************************************************
+ * Name: stm32_tim_enable
+ ************************************************************************************/
+
static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev)
{
uint16_t val = stm32_getreg16(dev, STM32_BTIM_CR1_OFFSET);
@@ -353,6 +624,10 @@ static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev)
stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val);
}
+/************************************************************************************
+ * Name: stm32_tim_disable
+ ************************************************************************************/
+
static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev)
{
uint16_t val = stm32_getreg16(dev, STM32_BTIM_CR1_OFFSET);
@@ -360,7 +635,13 @@ static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev)
stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val);
}
-/* Reset timer into system default state, but do not affect output/input pins */
+/************************************************************************************
+ * Name: stm32_tim_reset
+ *
+ * Description:
+ * Reset timer into system default state, but do not affect output/input pins
+ *
+ ************************************************************************************/
static void stm32_tim_reset(FAR struct stm32_tim_dev_s *dev)
{
@@ -368,9 +649,11 @@ static void stm32_tim_reset(FAR struct stm32_tim_dev_s *dev)
stm32_tim_disable(dev);
}
-#if defined(HAVE_TIM1_GPIOCONFIG)||defined(HAVE_TIM2_GPIOCONFIG)||\
- defined(HAVE_TIM3_GPIOCONFIG)||defined(HAVE_TIM4_GPIOCONFIG)||\
- defined(HAVE_TIM5_GPIOCONFIG)||defined(HAVE_TIM8_GPIOCONFIG)
+/************************************************************************************
+ * Name: stm32_tim_gpioconfig
+ ************************************************************************************/
+
+#ifdef HAVE_TIM_GPIOCONFIG
static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode)
{
/* TODO: Add support for input capture and bipolar dual outputs for TIM8 */
@@ -387,7 +670,77 @@ static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode)
#endif
/************************************************************************************
- * Basic Functions
+ * Name: stm32_tim_setmode
+ ************************************************************************************/
+
+static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode)
+{
+ uint16_t val = ATIM_CR1_CEN | ATIM_CR1_ARPE;
+
+ DEBUGASSERT(dev != NULL);
+
+ /* This function is not supported on basic timers. To enable or
+ * disable it, simply set its clock to valid frequency or zero.
+ */
+
+#if STM32_NBTIM > 0
+ if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM6_BASE
+#endif
+#if STM32_NBTIM > 1
+ || ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM7_BASE
+#endif
+#if STM32_NBTIM > 0
+ )
+ {
+ return -EINVAL;
+ }
+#endif
+
+ /* Decode operational modes */
+
+ switch (mode & STM32_TIM_MODE_MASK)
+ {
+ case STM32_TIM_MODE_DISABLED:
+ val = 0;
+ break;
+
+ case STM32_TIM_MODE_DOWN:
+ val |= ATIM_CR1_DIR;
+
+ case STM32_TIM_MODE_UP:
+ break;
+
+ case STM32_TIM_MODE_UPDOWN:
+ val |= ATIM_CR1_CENTER1;
+ // Our default: Interrupts are generated on compare, when counting down
+ break;
+
+ case STM32_TIM_MODE_PULSE:
+ val |= ATIM_CR1_OPM;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ stm32_tim_reload_counter(dev);
+ stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val);
+
+#if STM32_NATIM > 0
+ /* Advanced registers require Main Output Enable */
+
+ if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE ||
+ ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE)
+ {
+ stm32_modifyreg16(dev, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE);
+ }
+#endif
+
+ return OK;
+}
+
+/************************************************************************************
+ * Name: stm32_tim_setclock
************************************************************************************/
static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq)
@@ -531,6 +884,10 @@ static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq)
return prescaler;
}
+/************************************************************************************
+ * Name: stm32_tim_setperiod
+ ************************************************************************************/
+
static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev,
uint32_t period)
{
@@ -538,217 +895,20 @@ static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev,
stm32_putreg32(dev, STM32_BTIM_ARR_OFFSET, period);
}
-static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev,
- int (*handler)(int irq, void *context),
- int source)
-{
- int vectorno;
-
- DEBUGASSERT(dev != NULL);
- DEBUGASSERT(source == 0);
-
- switch (((struct stm32_tim_priv_s *)dev)->base)
- {
-#ifdef CONFIG_STM32_TIM1
- case STM32_TIM1_BASE:
- vectorno = STM32_IRQ_TIM1UP;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM2
- case STM32_TIM2_BASE:
- vectorno = STM32_IRQ_TIM2;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM3
- case STM32_TIM3_BASE:
- vectorno = STM32_IRQ_TIM3;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM4
- case STM32_TIM4_BASE:
- vectorno = STM32_IRQ_TIM4;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM5
- case STM32_TIM5_BASE:
- vectorno = STM32_IRQ_TIM5;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM6
- case STM32_TIM6_BASE:
- vectorno = STM32_IRQ_TIM6;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM7
- case STM32_TIM7_BASE:
- vectorno = STM32_IRQ_TIM7;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM8
- case STM32_TIM8_BASE:
- vectorno = STM32_IRQ_TIM8UP;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM9
- case STM32_TIM9_BASE:
- vectorno = STM32_IRQ_TIM9;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM10
- case STM32_TIM10_BASE:
- vectorno = STM32_IRQ_TIM10;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM11
- case STM32_TIM11_BASE:
- vectorno = STM32_IRQ_TIM11;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM12
- case STM32_TIM12_BASE:
- vectorno = STM32_IRQ_TIM12;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM13
- case STM32_TIM13_BASE:
- vectorno = STM32_IRQ_TIM13;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM14
- case STM32_TIM14_BASE:
- vectorno = STM32_IRQ_TIM14;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM15
- case STM32_TIM15_BASE:
- vectorno = STM32_IRQ_TIM15;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM16
- case STM32_TIM16_BASE:
- vectorno = STM32_IRQ_TIM16;
- break;
-#endif
-#ifdef CONFIG_STM32_TIM17
- case STM32_TIM17_BASE:
- vectorno = STM32_IRQ_TIM17;
- break;
-#endif
-
- default:
- return -EINVAL;
- }
-
- /* Disable interrupt when callback is removed */
-
- if (!handler)
- {
- up_disable_irq(vectorno);
- irq_detach(vectorno);
- return OK;
- }
-
- /* Otherwise set callback and enable interrupt */
-
- irq_attach(vectorno, handler);
- up_enable_irq(vectorno);
-
-#ifdef CONFIG_ARCH_IRQPRIO
- /* Set the interrupt priority */
-
- up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT);
-#endif
-
- return OK;
-}
-
-static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source)
-{
- DEBUGASSERT(dev != NULL);
- stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, 0, ATIM_DIER_UIE);
-}
-
-static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source)
-{
- DEBUGASSERT(dev != NULL);
- stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, ATIM_DIER_UIE, 0);
-}
-
-static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source)
-{
- stm32_putreg16(dev, STM32_BTIM_SR_OFFSET, ~ATIM_SR_UIF);
-}
-
/************************************************************************************
- * General Functions
+ * Name: stm32_tim_getcounter
************************************************************************************/
-static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode)
+static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev)
{
- uint16_t val = ATIM_CR1_CEN | ATIM_CR1_ARPE;
-
DEBUGASSERT(dev != NULL);
-
- /* This function is not supported on basic timers. To enable or
- * disable it, simply set its clock to valid frequency or zero.
- */
-
-#if STM32_NBTIM > 0
- if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM6_BASE
-#endif
-#if STM32_NBTIM > 1
- || ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM7_BASE
-#endif
-#if STM32_NBTIM > 0
- )
- {
- return -EINVAL;
- }
-#endif
-
- /* Decode operational modes */
-
- switch (mode & STM32_TIM_MODE_MASK)
- {
- case STM32_TIM_MODE_DISABLED:
- val = 0;
- break;
-
- case STM32_TIM_MODE_DOWN:
- val |= ATIM_CR1_DIR;
-
- case STM32_TIM_MODE_UP:
- break;
-
- case STM32_TIM_MODE_UPDOWN:
- val |= ATIM_CR1_CENTER1;
- // Our default: Interrupts are generated on compare, when counting down
- break;
-
- case STM32_TIM_MODE_PULSE:
- val |= ATIM_CR1_OPM;
- break;
-
- default:
- return -EINVAL;
- }
-
- stm32_tim_reload_counter(dev);
- stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val);
-
-#if STM32_NATIM > 0
- /* Advanced registers require Main Output Enable */
-
- if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE ||
- ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE)
- {
- stm32_modifyreg16(dev, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE);
- }
-#endif
-
- return OK;
+ return stm32_getreg32(dev, STM32_BTIM_CNT_OFFSET);
}
+/************************************************************************************
+ * Name: stm32_tim_setchannel
+ ************************************************************************************/
+
static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
stm32_tim_channel_t mode)
{
@@ -1268,6 +1428,10 @@ static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel
return OK;
}
+/************************************************************************************
+ * Name: stm32_tim_setcompare
+ ************************************************************************************/
+
static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
uint32_t compare)
{
@@ -1293,6 +1457,10 @@ static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel
return OK;
}
+/************************************************************************************
+ * Name: stm32_tim_getcapture
+ ************************************************************************************/
+
static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel)
{
DEBUGASSERT(dev != NULL);
@@ -1313,183 +1481,178 @@ static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel
}
/************************************************************************************
- * Advanced Functions
+ * Name: stm32_tim_setisr
************************************************************************************/
-/* TODO: Advanced functions for the STM32_ATIM */
-
-/************************************************************************************
- * Device Structures, Instantiation
- ************************************************************************************/
-
-struct stm32_tim_ops_s stm32_tim_ops =
+static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev,
+ int (*handler)(int irq, void *context),
+ int source)
{
- .setmode = &stm32_tim_setmode,
- .setclock = &stm32_tim_setclock,
- .setperiod = &stm32_tim_setperiod,
- .setchannel = &stm32_tim_setchannel,
- .setcompare = &stm32_tim_setcompare,
- .getcapture = &stm32_tim_getcapture,
- .setisr = &stm32_tim_setisr,
- .enableint = &stm32_tim_enableint,
- .disableint = &stm32_tim_disableint,
- .ackint = &stm32_tim_ackint
-};
+ int vectorno;
+
+ DEBUGASSERT(dev != NULL);
+ DEBUGASSERT(source == 0);
+ switch (((struct stm32_tim_priv_s *)dev)->base)
+ {
#ifdef CONFIG_STM32_TIM1
-struct stm32_tim_priv_s stm32_tim1_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM1_BASE,
-};
+ case STM32_TIM1_BASE:
+ vectorno = STM32_IRQ_TIM1UP;
+ break;
#endif
#ifdef CONFIG_STM32_TIM2
-struct stm32_tim_priv_s stm32_tim2_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM2_BASE,
-};
+ case STM32_TIM2_BASE:
+ vectorno = STM32_IRQ_TIM2;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM3
-struct stm32_tim_priv_s stm32_tim3_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM3_BASE,
-};
+ case STM32_TIM3_BASE:
+ vectorno = STM32_IRQ_TIM3;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM4
-struct stm32_tim_priv_s stm32_tim4_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM4_BASE,
-};
+ case STM32_TIM4_BASE:
+ vectorno = STM32_IRQ_TIM4;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM5
-struct stm32_tim_priv_s stm32_tim5_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM5_BASE,
-};
+ case STM32_TIM5_BASE:
+ vectorno = STM32_IRQ_TIM5;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM6
-struct stm32_tim_priv_s stm32_tim6_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM6_BASE,
-};
+ case STM32_TIM6_BASE:
+ vectorno = STM32_IRQ_TIM6;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM7
-struct stm32_tim_priv_s stm32_tim7_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM7_BASE,
-};
+ case STM32_TIM7_BASE:
+ vectorno = STM32_IRQ_TIM7;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM8
-struct stm32_tim_priv_s stm32_tim8_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM8_BASE,
-};
+ case STM32_TIM8_BASE:
+ vectorno = STM32_IRQ_TIM8UP;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM9
-struct stm32_tim_priv_s stm32_tim9_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM9_BASE,
-};
+ case STM32_TIM9_BASE:
+ vectorno = STM32_IRQ_TIM9;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM10
-struct stm32_tim_priv_s stm32_tim10_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM10_BASE,
-};
+ case STM32_TIM10_BASE:
+ vectorno = STM32_IRQ_TIM10;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM11
-struct stm32_tim_priv_s stm32_tim11_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM11_BASE,
-};
+ case STM32_TIM11_BASE:
+ vectorno = STM32_IRQ_TIM11;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM12
-struct stm32_tim_priv_s stm32_tim12_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM12_BASE,
-};
+ case STM32_TIM12_BASE:
+ vectorno = STM32_IRQ_TIM12;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM13
-struct stm32_tim_priv_s stm32_tim13_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM13_BASE,
-};
+ case STM32_TIM13_BASE:
+ vectorno = STM32_IRQ_TIM13;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM14
-struct stm32_tim_priv_s stm32_tim14_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM14_BASE,
-};
+ case STM32_TIM14_BASE:
+ vectorno = STM32_IRQ_TIM14;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM15
-struct stm32_tim_priv_s stm32_tim15_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM15_BASE,
-};
+ case STM32_TIM15_BASE:
+ vectorno = STM32_IRQ_TIM15;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM16
-struct stm32_tim_priv_s stm32_tim16_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM16_BASE,
-};
+ case STM32_TIM16_BASE:
+ vectorno = STM32_IRQ_TIM16;
+ break;
#endif
-
#ifdef CONFIG_STM32_TIM17
-struct stm32_tim_priv_s stm32_tim17_priv =
-{
- .ops = &stm32_tim_ops,
- .mode = STM32_TIM_MODE_UNUSED,
- .base = STM32_TIM17_BASE,
-};
+ case STM32_TIM17_BASE:
+ vectorno = STM32_IRQ_TIM17;
+ break;
+#endif
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Disable interrupt when callback is removed */
+
+ if (!handler)
+ {
+ up_disable_irq(vectorno);
+ irq_detach(vectorno);
+ return OK;
+ }
+
+ /* Otherwise set callback and enable interrupt */
+
+ irq_attach(vectorno, handler);
+ up_enable_irq(vectorno);
+
+#ifdef CONFIG_ARCH_IRQPRIO
+ /* Set the interrupt priority */
+
+ up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT);
#endif
+ return OK;
+}
+
+/************************************************************************************
+ * Name: stm32_tim_enableint
+ ************************************************************************************/
+
+static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source)
+{
+ DEBUGASSERT(dev != NULL);
+ stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, 0, ATIM_DIER_UIE);
+}
+
+/************************************************************************************
+ * Name: stm32_tim_disableint
+ ************************************************************************************/
+
+static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source)
+{
+ DEBUGASSERT(dev != NULL);
+ stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, ATIM_DIER_UIE, 0);
+}
+
+/************************************************************************************
+ * Name: stm32_tim_ackint
+ ************************************************************************************/
+
+static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source)
+{
+ stm32_putreg16(dev, STM32_BTIM_SR_OFFSET, ~ATIM_SR_UIF);
+}
+
+/************************************************************************************
+ * Name: stm32_tim_checkint
+ ************************************************************************************/
+
+static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source)
+{
+ uint16_t regval = stm32_getreg16(dev, STM32_BTIM_SR_OFFSET);
+ return (regval & ATIM_SR_UIF) ? 1 : 0;
+}
+
+/************************************************************************************
+ * Pubic Functions
+ ************************************************************************************/
+
/************************************************************************************
- * Public Function - Initialization
+ * Name: stm32_tim_init
************************************************************************************/
FAR struct stm32_tim_dev_s *stm32_tim_init(int timer)
@@ -1618,7 +1781,12 @@ FAR struct stm32_tim_dev_s *stm32_tim_init(int timer)
return dev;
}
-/* TODO: Detach interrupts, and close down all TIM Channels */
+/************************************************************************************
+ * Name: stm32_tim_deinit
+ *
+ * TODO: Detach interrupts, and close down all TIM Channels
+ *
+ ************************************************************************************/
int stm32_tim_deinit(FAR struct stm32_tim_dev_s * dev)
{
diff --git a/arch/arm/src/stm32/stm32_tim.h b/arch/arm/src/stm32/stm32_tim.h
index 2d3b01a683b71c835641b858bbed7006151e1ebe..e31250537b4727201681adfad2b368b40fa2aa45 100644
--- a/arch/arm/src/stm32/stm32_tim.h
+++ b/arch/arm/src/stm32/stm32_tim.h
@@ -6,7 +6,7 @@
*
* With modifications and updates by:
*
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,7 @@
#define STM32_TIM_SETMODE(d,mode) ((d)->ops->setmode(d,mode))
#define STM32_TIM_SETCLOCK(d,freq) ((d)->ops->setclock(d,freq))
#define STM32_TIM_SETPERIOD(d,period) ((d)->ops->setperiod(d,period))
+#define STM32_TIM_GETCOUNTER(d) ((d)->ops->getcounter(d))
#define STM32_TIM_SETCHANNEL(d,ch,mode) ((d)->ops->setchannel(d,ch,mode))
#define STM32_TIM_SETCOMPARE(d,ch,comp) ((d)->ops->setcompare(d,ch,comp))
#define STM32_TIM_GETCAPTURE(d,ch) ((d)->ops->getcapture(d,ch))
@@ -65,6 +66,7 @@
#define STM32_TIM_ENABLEINT(d,s) ((d)->ops->enableint(d,s))
#define STM32_TIM_DISABLEINT(d,s) ((d)->ops->disableint(d,s))
#define STM32_TIM_ACKINT(d,s) ((d)->ops->ackint(d,s))
+#define STM32_TIM_CHECKINT(d,s) ((d)->ops->checkint(d,s))
/************************************************************************************
* Public Types
@@ -158,19 +160,24 @@ struct stm32_tim_ops_s
int (*setmode)(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode);
int (*setclock)(FAR struct stm32_tim_dev_s *dev, uint32_t freq);
void (*setperiod)(FAR struct stm32_tim_dev_s *dev, uint32_t period);
+ uint32_t (*getcounter)(FAR struct stm32_tim_dev_s *dev);
/* General and Advanced Timers Adds */
- int (*setchannel)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, stm32_tim_channel_t mode);
- int (*setcompare)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, uint32_t compare);
+ int (*setchannel)(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
+ stm32_tim_channel_t mode);
+ int (*setcompare)(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
+ uint32_t compare);
int (*getcapture)(FAR struct stm32_tim_dev_s *dev, uint8_t channel);
/* Timer interrupts */
- int (*setisr)(FAR struct stm32_tim_dev_s *dev, int (*handler)(int irq, void *context), int source);
+ int (*setisr)(FAR struct stm32_tim_dev_s *dev,
+ int (*handler)(int irq, void *context), int source);
void (*enableint)(FAR struct stm32_tim_dev_s *dev, int source);
void (*disableint)(FAR struct stm32_tim_dev_s *dev, int source);
void (*ackint)(FAR struct stm32_tim_dev_s *dev, int source);
+ int (*checkint)(FAR struct stm32_tim_dev_s *dev, int source);
};
/************************************************************************************
diff --git a/arch/arm/src/stm32/stm32f40xxx_rtcc.c b/arch/arm/src/stm32/stm32f40xxx_rtcc.c
index 0e55a4ad7dd7976f86c674028b66b8f10da74fb0..c20024d8b1a4bd2e6ea790c7031af1d6d8bd9484 100644
--- a/arch/arm/src/stm32/stm32f40xxx_rtcc.c
+++ b/arch/arm/src/stm32/stm32f40xxx_rtcc.c
@@ -1,4 +1,4 @@
-/************************************************************************************
+/****************************************************************************
* arch/arm/src/stm32/stm32f40xxx_rtcc.c
*
* Copyright (C) 2012-2016 Gregory Nutt. All rights reserved.
@@ -32,11 +32,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- ************************************************************************************/
+ ****************************************************************************/
-/************************************************************************************
+/****************************************************************************
* Included Files
- ************************************************************************************/
+ ****************************************************************************/
#include
@@ -60,10 +60,11 @@
#ifdef CONFIG_RTC
-/************************************************************************************
+/****************************************************************************
* Pre-processor Definitions
- ************************************************************************************/
-/* Configuration ********************************************************************/
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
/* This RTC implementation supports
* - date/time RTC hardware
* - extended functions Alarm A and B for STM32F4xx and onwards
@@ -81,12 +82,12 @@
# error "CONFIG_STM32_PWR must selected to use this driver"
#endif
-/* Constants ************************************************************************/
+/* Constants ****************************************************************/
#define SYNCHRO_TIMEOUT (0x00020000)
#define INITMODE_TIMEOUT (0x00010000)
-/* Proxy definitions to make the same code work for all the STM32 series ************/
+/* Proxy definitions to make the same code work for all the STM32 series ****/
# define STM32_RCC_XXX STM32_RCC_BDCR
# define RCC_XXX_YYYRST RCC_BDCR_BDRST
@@ -101,10 +102,6 @@
#define MINUTES_IN_HOUR 60
#define HOURS_IN_DAY 24
-/* Can't exceed 24hours-2min without providing extra logic for carry over for day. */
-
-#define MAX_RTC_ALARM_REL_MINUTES (24*MINUTES_IN_HOUR)-2
-
#define hours_add(parm_hrs) \
time->tm_hour += parm_hrs;\
if ((HOURS_IN_DAY-1) < (time->tm_hour))\
@@ -117,9 +114,9 @@
#define RTC_ALRMR_DIS_DATE_MASK (RTC_ALRMR_MSK4)
#define RTC_ALRMR_ENABLE (0)
-/************************************************************************************
+/****************************************************************************
* Private Types
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_RTC_ALARM
typedef unsigned int rtc_alarmreg_t;
@@ -131,9 +128,9 @@ struct alm_cbinfo_s
};
#endif
-/************************************************************************************
+/****************************************************************************
* Private Data
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_RTC_ALARM
/* Callback to use when an EXTI is activated */
@@ -141,17 +138,17 @@ struct alm_cbinfo_s
static struct alm_cbinfo_s g_alarmcb[RTC_ALARM_LAST];
#endif
-/************************************************************************************
+/****************************************************************************
* Public Data
- ************************************************************************************/
+ ****************************************************************************/
/* g_rtc_enabled is set true after the RTC has successfully initialized */
volatile bool g_rtc_enabled = false;
-/************************************************************************************
+/****************************************************************************
* Private Function Prototypes
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_RTC_ALARM
static int rtchw_check_alrawf(void);
@@ -162,11 +159,11 @@ static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg);
#endif
#endif
-/************************************************************************************
+/****************************************************************************
* Private Functions
- ************************************************************************************/
+ ****************************************************************************/
-/************************************************************************************
+/****************************************************************************
* Name: rtc_dumpregs
*
* Description:
@@ -178,7 +175,7 @@ static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg);
* Returned Value:
* None
*
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_DEBUG_RTC_INFO
static void rtc_dumpregs(FAR const char *msg)
@@ -215,7 +212,7 @@ static void rtc_dumpregs(FAR const char *msg)
# define rtc_dumpregs(msg)
#endif
-/************************************************************************************
+/****************************************************************************
* Name: rtc_dumptime
*
* Description:
@@ -227,7 +224,7 @@ static void rtc_dumpregs(FAR const char *msg)
* Returned Value:
* None
*
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_DEBUG_RTC_INFO
static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg)
@@ -244,7 +241,7 @@ static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg)
# define rtc_dumptime(tp, msg)
#endif
-/************************************************************************************
+/****************************************************************************
* Name: rtc_wprunlock
*
* Description:
@@ -256,7 +253,7 @@ static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg)
* Returned Value:
* None
*
- ************************************************************************************/
+ ****************************************************************************/
static void rtc_wprunlock(void)
{
@@ -279,7 +276,7 @@ static void rtc_wprunlock(void)
putreg32(0x53, STM32_RTC_WPR);
}
-/************************************************************************************
+/****************************************************************************
* Name: rtc_wprlock
*
* Description:
@@ -291,7 +288,7 @@ static void rtc_wprunlock(void)
* Returned Value:
* None
*
- ************************************************************************************/
+ ****************************************************************************/
static inline void rtc_wprlock(void)
{
@@ -299,14 +296,14 @@ static inline void rtc_wprlock(void)
putreg32(0xff, STM32_RTC_WPR);
- /* Disable write access to the backup domain (RTC registers, RTC backup data
- * registers and backup SRAM).
+ /* Disable write access to the backup domain (RTC registers, RTC backup
+ * data registers and backup SRAM).
*/
(void)stm32_pwr_enablebkp(false);
}
-/************************************************************************************
+/****************************************************************************
* Name: rtc_synchwait
*
* Description:
@@ -319,7 +316,7 @@ static inline void rtc_wprlock(void)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
static int rtc_synchwait(void)
{
@@ -358,7 +355,7 @@ static int rtc_synchwait(void)
return ret;
}
-/************************************************************************************
+/****************************************************************************
* Name: rtc_enterinit
*
* Description:
@@ -370,7 +367,7 @@ static int rtc_synchwait(void)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
static int rtc_enterinit(void)
{
@@ -406,7 +403,7 @@ static int rtc_enterinit(void)
return ret;
}
-/************************************************************************************
+/****************************************************************************
* Name: rtc_exitinit
*
* Description:
@@ -418,7 +415,7 @@ static int rtc_enterinit(void)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
static void rtc_exitinit(void)
{
@@ -429,7 +426,7 @@ static void rtc_exitinit(void)
putreg32(regval, STM32_RTC_ISR);
}
-/************************************************************************************
+/****************************************************************************
* Name: rtc_bin2bcd
*
* Description:
@@ -441,7 +438,7 @@ static void rtc_exitinit(void)
* Returned Value:
* The value in BCD representation
*
- ************************************************************************************/
+ ****************************************************************************/
static uint32_t rtc_bin2bcd(int value)
{
@@ -456,7 +453,7 @@ static uint32_t rtc_bin2bcd(int value)
return (msbcd << 4) | value;
}
-/************************************************************************************
+/****************************************************************************
* Name: rtc_bin2bcd
*
* Description:
@@ -468,7 +465,7 @@ static uint32_t rtc_bin2bcd(int value)
* Returned Value:
* The value in binary representation
*
- ************************************************************************************/
+ ****************************************************************************/
static int rtc_bcd2bin(uint32_t value)
{
@@ -476,13 +473,13 @@ static int rtc_bcd2bin(uint32_t value)
return (int)(tens + (value & 0x0f));
}
-/************************************************************************************
+/****************************************************************************
* Name: rtc_setup
*
* Description:
- * Performs first time configuration of the RTC. A special value written into
- * back-up register 0 will prevent this function from being called on sub-sequent
- * resets or power up.
+ * Performs first time configuration of the RTC. A special value written
+ * into back-up register 0 will prevent this function from being called on
+ * sub-sequent resets or power up.
*
* Input Parameters:
* None
@@ -490,7 +487,7 @@ static int rtc_bcd2bin(uint32_t value)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
static int rtc_setup(void)
{
@@ -544,12 +541,12 @@ static int rtc_setup(void)
return ret;
}
-/************************************************************************************
+/****************************************************************************
* Name: rtc_resume
*
* Description:
- * Called when the RTC was already initialized on a previous power cycle. This
- * just brings the RTC back into full operation.
+ * Called when the RTC was already initialized on a previous power cycle.
+ * This just brings the RTC back into full operation.
*
* Input Parameters:
* None
@@ -557,7 +554,7 @@ static int rtc_setup(void)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
static void rtc_resume(void)
{
@@ -576,7 +573,7 @@ static void rtc_resume(void)
#endif
}
-/************************************************************************************
+/****************************************************************************
* Name: stm32_rtc_alarm_handler
*
* Description:
@@ -589,7 +586,7 @@ static void rtc_resume(void)
* Returned Value:
* Zero (OK) on success; A negated errno value on failure.
*
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_RTC_ALARM
static int stm32_rtc_alarm_handler(int irq, void *context)
@@ -659,7 +656,7 @@ static int stm32_rtc_alarm_handler(int irq, void *context)
}
#endif
-/************************************************************************************
+/****************************************************************************
* Name: rtchw_check_alrXwf X= a or B
*
* Description:
@@ -671,7 +668,7 @@ static int stm32_rtc_alarm_handler(int irq, void *context)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_RTC_ALARM
static int rtchw_check_alrawf(void)
@@ -725,12 +722,12 @@ static int rtchw_check_alrbwf(void)
}
#endif
-/************************************************************************************
+/****************************************************************************
* Name: stm32_rtchw_set_alrmXr X is a or b
*
* Description:
- * Set the alarm (A or B) hardware registers, using the required hardware access
- * protocol
+ * Set the alarm (A or B) hardware registers, using the required hardware
+ * access protocol
*
* Input Parameters:
* alarmreg - the register
@@ -738,7 +735,7 @@ static int rtchw_check_alrbwf(void)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_RTC_ALARM
static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg)
@@ -814,16 +811,16 @@ rtchw_set_alrmbr_exit:
}
#endif
-/************************************************************************************
+/****************************************************************************
* Public Functions
- ************************************************************************************/
+ ****************************************************************************/
-/************************************************************************************
+/****************************************************************************
* Name: up_rtc_initialize
*
* Description:
- * Initialize the hardware RTC per the selected configuration. This function is
- * called once during the OS initialization sequence
+ * Initialize the hardware RTC per the selected configuration. This
+ * function is called once during the OS initialization sequence
*
* Input Parameters:
* None
@@ -831,7 +828,7 @@ rtchw_set_alrmbr_exit:
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
int up_rtc_initialize(void)
{
@@ -843,9 +840,9 @@ int up_rtc_initialize(void)
int nretry = 0;
/* Clocking for the PWR block must be provided. However, this is done
- * unconditionally in stm32f40xxx_rcc.c on power up. This done unconditionally
- * because the PWR block is also needed to set the internal voltage regulator for
- * maximum performance.
+ * unconditionally in stm32f40xxx_rcc.c on power up. This done
+ * unconditionally because the PWR block is also needed to set the
+ * internal voltage regulator for maximum performance.
*/
/* Select the clock source */
@@ -857,9 +854,9 @@ int up_rtc_initialize(void)
if (regval != RTC_MAGIC)
{
- /* Some boards do not have the external 32khz oscillator installed, for those
- * boards we must fallback to the crummy internal RC clock or the external high
- * rate clock
+ /* Some boards do not have the external 32khz oscillator installed,
+ * for those boards we must fallback to the crummy internal RC clock
+ * or the external high rate clock
*/
#ifdef CONFIG_RTC_HSECLOCK
@@ -942,8 +939,8 @@ int up_rtc_initialize(void)
do
{
- /* Wait for the RTC Time and Date registers to be synchronized with RTC APB
- * clock.
+ /* Wait for the RTC Time and Date registers to be synchronized with RTC
+ * APB clock.
*/
ret = rtc_synchwait();
@@ -1014,12 +1011,12 @@ int up_rtc_initialize(void)
}
#ifdef CONFIG_RTC_ALARM
- /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are
- * connected to the EXTI controller. To enable the RTC Alarm interrupt, the
- * following sequence is required:
+ /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts
+ * are connected to the EXTI controller. To enable the RTC Alarm
+ * interrupt, the following sequence is required:
*
- * 1. Configure and enable the EXTI Line 17 RTC ALARM in interrupt mode and select the
- * rising edge sensitivity.
+ * 1. Configure and enable the EXTI Line 17 RTC ALARM in interrupt mode
+ * and select the rising edge sensitivity.
* For STM32F4xx
* EXTI line 21 RTC Tamper & Timestamp
* EXTI line 22 RTC Wakeup
@@ -1037,18 +1034,18 @@ int up_rtc_initialize(void)
return OK;
}
-/************************************************************************************
+/****************************************************************************
* Name: stm32_rtc_getdatetime_with_subseconds
*
* Description:
* Get the current date and time from the date/time RTC. This interface
* is only supported by the date/time RTC hardware implementation.
- * It is used to replace the system timer. It is only used by the RTOS during
- * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME
- * are selected (and CONFIG_RTC_HIRES is not).
+ * It is used to replace the system timer. It is only used by the RTOS
+ * during initialization to set up the system time when CONFIG_RTC and
+ * CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not).
*
- * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That
- * sub-second accuracy is returned through 'nsec'.
+ * NOTE: Some date/time RTC hardware is capability of sub-second accuracy.
+ * That sub-second accuracy is returned through 'nsec'.
*
* Input Parameters:
* tp - The location to return the high resolution time value.
@@ -1057,7 +1054,7 @@ int up_rtc_initialize(void)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS
int stm32_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec)
@@ -1072,9 +1069,9 @@ int up_rtc_getdatetime(FAR struct tm *tp)
uint32_t tr;
uint32_t tmp;
- /* Sample the data time registers. There is a race condition here... If we sample
- * the time just before midnight on December 31, the date could be wrong because
- * the day rolled over while were sampling.
+ /* Sample the data time registers. There is a race condition here... If
+ * we sample the time just before midnight on December 31, the date could
+ * be wrong because the day rolled over while were sampling.
*/
do
@@ -1158,20 +1155,20 @@ int up_rtc_getdatetime(FAR struct tm *tp)
return OK;
}
-/************************************************************************************
+/****************************************************************************
* Name: up_rtc_getdatetime
*
* Description:
* Get the current date and time from the date/time RTC. This interface
* is only supported by the date/time RTC hardware implementation.
- * It is used to replace the system timer. It is only used by the RTOS during
- * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME
- * are selected (and CONFIG_RTC_HIRES is not).
+ * It is used to replace the system timer. It is only used by the RTOS
+ * during initialization to set up the system time when CONFIG_RTC and
+ * CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not).
*
- * NOTE: Some date/time RTC hardware is capability of sub-second accuracy. That
- * sub-second accuracy is lost in this interface. However, since the system time
- * is reinitialized on each power-up/reset, there will be no timing inaccuracy in
- * the long run.
+ * NOTE: Some date/time RTC hardware is capability of sub-second accuracy.
+ * That sub-second accuracy is lost in this interface. However, since the
+ * system time is reinitialized on each power-up/reset, there will be no
+ * timing inaccuracy in the long run.
*
* Input Parameters:
* tp - The location to return the high resolution time value.
@@ -1179,7 +1176,7 @@ int up_rtc_getdatetime(FAR struct tm *tp)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS
int up_rtc_getdatetime(FAR struct tm *tp)
@@ -1188,13 +1185,13 @@ int up_rtc_getdatetime(FAR struct tm *tp)
}
#endif
-/************************************************************************************
+/****************************************************************************
* Name: stm32_rtc_setdatetime
*
* Description:
* Set the RTC to the provided time. RTC implementations which provide
- * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide this
- * function.
+ * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide
+ * this function.
*
* Input Parameters:
* tp - the time to use
@@ -1202,7 +1199,7 @@ int up_rtc_getdatetime(FAR struct tm *tp)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
int stm32_rtc_setdatetime(FAR const struct tm *tp)
{
@@ -1223,11 +1220,14 @@ int stm32_rtc_setdatetime(FAR const struct tm *tp)
(rtc_bin2bcd(tp->tm_min) << RTC_TR_MNU_SHIFT) |
(rtc_bin2bcd(tp->tm_hour) << RTC_TR_HU_SHIFT);
- /* Now convert the fields in struct tm format to the RTC date register fields:
- * Days: 1-31 match in both cases.
- * Month: STM32 is 1-12, struct tm is 0-11.
- * Years: STM32 is 00-99, struct tm is years since 1900.
- * WeekDay: STM32 is 1 = Mon - 7 = Sun
+ /* Now convert the fields in struct tm format to the RTC date register
+ * fields:
+ *
+ * Days: 1-31 match in both cases.
+ * Month: STM32 is 1-12, struct tm is 0-11.
+ * Years: STM32 is 00-99, struct tm is years since 1900.
+ * WeekDay: STM32 is 1 = Mon - 7 = Sun
+ *
* Issue: I am not sure what the STM32 years mean. Are these the
* years 2000-2099? I'll assume so.
*/
@@ -1270,12 +1270,12 @@ int stm32_rtc_setdatetime(FAR const struct tm *tp)
return ret;
}
-/************************************************************************************
+/****************************************************************************
* Name: up_rtc_settime
*
* Description:
- * Set the RTC to the provided time. All RTC implementations must be able to
- * set their time based on a standard timespec.
+ * Set the RTC to the provided time. All RTC implementations must be able
+ * to set their time based on a standard timespec.
*
* Input Parameters:
* tp - the time to use
@@ -1283,13 +1283,15 @@ int stm32_rtc_setdatetime(FAR const struct tm *tp)
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
- ************************************************************************************/
+ ****************************************************************************/
int up_rtc_settime(FAR const struct timespec *tp)
{
FAR struct tm newtime;
- /* Break out the time values (not that the time is set only to units of seconds) */
+ /* Break out the time values (not that the time is set only to units of
+ * seconds)
+ */
(void)gmtime_r(&tp->tv_sec, &newtime);
return stm32_rtc_setdatetime(&newtime);
diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig
index 0f2f65f84a2a973aa45634b99ccf7f66359525e5..75dd21454b4319ab8d0f6448bbefba0d8b9349f0 100644
--- a/arch/arm/src/stm32f7/Kconfig
+++ b/arch/arm/src/stm32f7/Kconfig
@@ -1195,6 +1195,10 @@ config STM32F7_QUADSPI
bool "QuadSPI"
default n
+config STM32F7_PWR
+ bool "PWR"
+ default n
+
config STM32F7_RNG
bool "RNG"
default n
@@ -1215,12 +1219,16 @@ config STM32F7_SDMMC1
bool "SDMMC1"
default n
select ARCH_HAVE_SDIO
+ select ARCH_HAVE_SDIOWAIT_WRCOMPLETE
+ select SDIO_PREFLIGHT
config STM32F7_SDMMC2
bool "SDMMC2"
default n
depends on STM32F7_HAVE_SDMMC2
select ARCH_HAVE_SDIO
+ select ARCH_HAVE_SDIOWAIT_WRCOMPLETE
+ select SDIO_PREFLIGHT
config STM32F7_SPDIFRX
bool "SPDIFRX"
@@ -1710,12 +1718,157 @@ config STM32F7_I2C_DUTY16_9
endmenu # "I2C Configuration"
+config STM32F7_SDMMC_XFRDEBUG
+ bool "SDMMC transfer debug"
+ depends on DEBUG_FS_INFO && (STM32F7_SDMMC1 || STM32F7_SDMMC2)
+ default n
+ ---help---
+ Enable special debug instrumentation analyze SDMMC data transfers.
+ This logic is as non-invasive as possible: It samples SDMMC
+ registers at key points in the data transfer and then dumps all of
+ the registers at the end of the transfer. If DEBUG_DMA is also
+ enabled, then DMA register will be collected as well. Requires also
+ DEBUG_FS and CONFIG_DEBUG_INFO.
+
+menu "SDMMC1 Configuration"
+ depends on STM32F7_SDMMC1
+
+config SDMMC1_DMA
+ bool "Support DMA data transfers on SDMMC1"
+ default y if STM32F7_DMA2
+ depends on STM32F7_DMA2
+ ---help---
+ Support DMA data transfers on SDMMC1. Requires STM32F7_SDMMC1 and config STM32F7_DMA2.
+
+config SDMMC1_PRI
+ hex "SDMMC1 interrupt priority"
+ default 128
+ depends on ARCH_IRQPRIO && EXPERIMENTAL
+ ---help---
+ Select SDMMC1 interrupt priority. Default: 128.
+
+config SDMMC1_DMAPRIO
+ hex "SDMMC1 DMA priority"
+ default 0x00010000
+ ---help---
+ Select SDMMC1 DMA prority.
+
+ Options are: 0x00000000 low, 0x00010000 medium,
+ 0x00020000 high, 0x00030000 very high. Default: medium.
+
+config SDMMC1_WIDTH_D1_ONLY
+ bool "Use D1 only on SDMMC1"
+ default n
+ ---help---
+ Select 1-bit transfer mode. Default: 4-bit transfer mode.
+
+endmenu # "SDMMC1 Configuration"
+
+menu "SDMMC2 Configuration"
+ depends on STM32F7_SDMMC2
+
+config SDMMC2_DMA
+ bool "Support DMA data transfers on SDMMC2"
+ default y if STM32F7_DMA2
+ depends on STM32F7_DMA2
+ ---help---
+ Support DMA data transfers on SDMMC2. Requires STM32F7_SDMMC2 and config STM32F7_DMA2.
+
+config SDMMC2_PRI
+ hex "SDMMC2 interrupt priority"
+ default 128
+ depends on ARCH_IRQPRIO && EXPERIMENTAL
+ ---help---
+ Select SDMMC2 interrupt priority. Default: 128.
+
+config SDMMC2_DMAPRIO
+ hex "SDMMC2 DMA priority"
+ default 0x00010000
+ ---help---
+ Select SDMMC1 DMA prority.
+
+ Options are: 0x00000000 low, 0x00010000 medium,
+ 0x00020000 high, 0x00030000 very high. Default: medium.
+
+config SDMMC2_WIDTH_D1_ONLY
+ bool "Use D1 only on SDMMC2"
+ default n
+ ---help---
+ Select 1-bit transfer mode. Default: 4-bit transfer mode.
+
+endmenu # "SDMMC2 Configuration"
+
+if STM32F7_BKPSRAM
+
+config STM32F7_BBSRAM
+ bool "BBSRAM File Support"
+ default n
+
+config STM32F7_BBSRAM_FILES
+ int "Max Files to support in BBSRAM"
+ default 4
+
+config STM32F7_SAVE_CRASHDUMP
+ bool "Enable Saving Panic to BBSRAM"
+ default n
+
+endif # STM32F7_BKPSRAM
+
+config STM32F7_HAVE_RTC_COUNTER
+ bool
+ default n
+
+config STM32F7_HAVE_RTC_SUBSECONDS
+ bool
+ default n
+
+config RTC_MAGIC_REG
+ int "The BKP register used to store/check the Magic value to determine if RTC is set already"
+ default 0
+ range 0 31
+ depends on RTC && !STM32F7_HAVE_RTC_COUNTER
+
+config RTC_MAGIC
+ hex "Value used as Magic to determine if RTC is set already"
+ default 0xfacefeee
+ depends on RTC && !STM32F7_HAVE_RTC_COUNTER
+
+choice
+ prompt "RTC clock source"
+ default STM32F7_RTC_LSECLOCK
+ depends on RTC
+
+config STM32F7_RTC_HSECLOCK
+ bool "HSE clock"
+ ---help---
+ Drive the RTC with the HSE clock, divided down to 1MHz.
+
+config STM32F7_RTC_LSECLOCK
+ bool "LSE clock"
+ ---help---
+ Drive the RTC with the LSE clock
+
+config STM32F7_RTC_LSICLOCK
+ bool "LSI clock"
+ ---help---
+ Drive the RTC with the LSI clock
+
+endchoice #"RTC clock source"
+
config STM32F7_CUSTOM_CLOCKCONFIG
bool "Custom clock configuration"
default n
---help---
Enables special, board-specific STM32 clock configuration.
+config STM32F7_DTCMEXCLUDE
+ bool "Exclude DTCM SRAM from the heap"
+ default y if ELF
+ depends on ARMV7M_HAVE_DTCM
+ ---help---
+ Exclude DTCM SRAM from the HEAP because it appears to be impossible
+ to execute ELF modules from DTCM RAM (REVISIT!).
+
config STM32F7_DTCM_PROCFS
bool "DTCM SRAM PROCFS support"
default n
@@ -3364,222 +3517,10 @@ endif # !STM32F7_PWM_MULTICHAN
endif # STM32F7_TIM14_PWM
-config STM32F7_TIM15_PWM
- bool "TIM15 PWM"
- default n
- depends on STM32F7_TIM15
- ---help---
- Reserve timer 15 for use by PWM
-
- Timer devices may be used for different purposes. One special purpose is
- to generate modulated outputs for such things as motor control. If STM32F7_TIM15
- is defined then THIS following may also be defined to indicate that
- the timer is intended to be used for pulsed output modulation.
-
-if STM32F7_TIM15_PWM
-
-if STM32F7_PWM_MULTICHAN
-
-config STM32F7_TIM15_CHANNEL1
- bool "TIM15 Channel 1"
- default n
- ---help---
- Enables channel 1.
-
-if STM32F7_TIM15_CHANNEL1
-
-config STM32F7_TIM15_CH1MODE
- int "TIM15 Channel 1 Mode"
- default 0
- range 0 3 if STM32F7_STM32F30XX
- range 0 1 if !STM32F7_STM32F30XX
- ---help---
- Specifies the channel mode.
-
-config STM32F7_TIM15_CH1OUT
- bool "TIM15 Channel 1 Output"
- default n
- ---help---
- Enables channel 1 output.
-
-endif # STM32F7_TIM15_CHANNEL1
-
-config STM32F7_TIM15_CHANNEL2
- bool "TIM15 Channel 2"
- default n
- ---help---
- Enables channel 2.
-
-if STM32F7_TIM15_CHANNEL2
-
-config STM32F7_TIM15_CH2MODE
- int "TIM15 Channel 2 Mode"
- default 0
- range 0 3 if STM32F7_STM32F30XX
- range 0 1 if !STM32F7_STM32F30XX
- ---help---
- Specifies the channel mode.
-
-config STM32F7_TIM15_CH2OUT
- bool "TIM15 Channel 2 Output"
- default n
- ---help---
- Enables channel 2 output.
-
-endif # STM32F7_TIM15_CHANNEL2
-
-endif # STM32F7_PWM_MULTICHAN
-
-if !STM32F7_PWM_MULTICHAN
-
-config STM32F7_TIM15_CHANNEL
- int "TIM15 PWM Output Channel"
- default 1
- range 1 2
- ---help---
- If TIM15 is enabled for PWM usage, you also need specifies the timer output
- channel {1,2}
-
-config STM32F7_TIM15_CHMODE
- int "TIM15 Channel Mode"
- default 0
- range 0 3 if STM32F7_STM32F30XX
- range 0 1 if !STM32F7_STM32F30XX
- ---help---
- Specifies the channel mode.
-
-endif # !STM32F7_PWM_MULTICHAN
-
-endif # STM32F7_TIM15_PWM
-
-config STM32F7_TIM16_PWM
- bool "TIM16 PWM"
- default n
- depends on STM32F7_TIM16
- ---help---
- Reserve timer 16 for use by PWM
-
- Timer devices may be used for different purposes. One special purpose is
- to generate modulated outputs for such things as motor control. If STM32F7_TIM16
- is defined then THIS following may also be defined to indicate that
- the timer is intended to be used for pulsed output modulation.
-
-if STM32F7_TIM16_PWM
-
-if STM32F7_PWM_MULTICHAN
-
-config STM32F7_TIM16_CHANNEL1
- bool "TIM16 Channel 1"
- default n
- ---help---
- Enables channel 1.
-
-if STM32F7_TIM16_CHANNEL1
-
-config STM32F7_TIM16_CH1MODE
- int "TIM16 Channel 1 Mode"
- default 0
- range 0 1
- ---help---
- Specifies the channel mode.
-
-config STM32F7_TIM16_CH1OUT
- bool "TIM16 Channel 1 Output"
- default n
- ---help---
- Enables channel 1 output.
-
-endif # STM32F7_TIM16_CHANNEL1
-
-endif # STM32F7_PWM_MULTICHAN
-
-if !STM32F7_PWM_MULTICHAN
-
-config STM32F7_TIM16_CHANNEL
- int "TIM16 PWM Output Channel"
- default 1
- range 1 1
- ---help---
- If TIM16 is enabled for PWM usage, you also need specifies the timer output
- channel {1}
-
-config STM32F7_TIM16_CHMODE
- int "TIM16 Channel Mode"
- default 0
- range 0 1
- ---help---
- Specifies the channel mode.
-
-endif # !STM32F7_PWM_MULTICHAN
-
-endif # STM32F7_TIM16_PWM
-
-config STM32F7_TIM17_PWM
- bool "TIM17 PWM"
- default n
- depends on STM32F7_TIM17
- ---help---
- Reserve timer 17 for use by PWM
-
- Timer devices may be used for different purposes. One special purpose is
- to generate modulated outputs for such things as motor control. If STM32F7_TIM17
- is defined then THIS following may also be defined to indicate that
- the timer is intended to be used for pulsed output modulation.
-
-if STM32F7_TIM17_PWM
-
-if STM32F7_PWM_MULTICHAN
-
-config STM32F7_TIM17_CHANNEL1
- bool "TIM17 Channel 1"
- default n
- ---help---
- Enables channel 1.
-
-if STM32F7_TIM17_CHANNEL1
-
-config STM32F7_TIM17_CH1MODE
- int "TIM17 Channel 1 Mode"
- default 0
- range 0 1
- ---help---
- Specifies the channel mode.
-
-config STM32F7_TIM17_CH1OUT
- bool "TIM17 Channel 1 Output"
- default n
- ---help---
- Enables channel 1 output.
-
-endif # STM32F7_TIM17_CHANNEL1
-
-endif # STM32F7_PWM_MULTICHAN
-
-if !STM32F7_PWM_MULTICHAN
-
-config STM32F7_TIM17_CHANNEL
- int "TIM17 PWM Output Channel"
- default 1
- range 1 1
- ---help---
- If TIM17 is enabled for PWM usage, you also need specifies the timer output
- channel {1}
-
-config STM32F7_TIM17_CHMODE
- int "TIM17 Channel Mode"
- default 0
- range 0 1
- ---help---
- Specifies the channel mode.
-
-endif # !STM32F7_PWM_MULTICHAN
-
-endif # STM32F7_TIM17_PWM
-
config STM32F7_PWM_MULTICHAN
bool "PWM Multiple Output Channels"
default n
- depends on STM32F7_TIM1_PWM || STM32F7_TIM2_PWM || STM32F7_TIM3_PWM || STM32F7_TIM4_PWM || STM32F7_TIM5_PWM || STM32F7_TIM8_PWM || STM32F7_TIM9_PWM || STM32F7_TIM10_PWM || STM32F7_TIM11_PWM || STM32F7_TIM12_PWM || STM32F7_TIM13_PWM || STM32F7_TIM14_PWM || STM32F7_TIM15_PWM || STM32F7_TIM16_PWM || STM32F7_TIM17_PWM
+ depends on STM32F7_TIM1_PWM || STM32F7_TIM2_PWM || STM32F7_TIM3_PWM || STM32F7_TIM4_PWM || STM32F7_TIM5_PWM || STM32F7_TIM8_PWM || STM32F7_TIM9_PWM || STM32F7_TIM10_PWM || STM32F7_TIM11_PWM || STM32F7_TIM12_PWM || STM32F7_TIM13_PWM || STM32F7_TIM14_PWM
select ARCH_HAVE_PWM_MULTICHAN
---help---
Specifies that the PWM driver supports multiple output
diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs
index 0680d17cfbc302fe5cf74deb0f6774b63b332a38..ee6b3e0687e7ee026cd25428c71c721b9cce0aab 100644
--- a/arch/arm/src/stm32f7/Make.defs
+++ b/arch/arm/src/stm32f7/Make.defs
@@ -135,8 +135,22 @@ ifeq ($(CONFIG_STM32F7_DMA),y)
CHIP_CSRCS += stm32_dma.c
endif
-ifeq ($(CONFIG_STM32_PWR),y)
-CHIP_CSRCS += stm32_exti_pwr.c
+ifeq ($(CONFIG_STM32F7_PWR),y)
+CHIP_CSRCS += stm32_pwr.c stm32_exti_pwr.c
+endif
+
+ifeq ($(CONFIG_RTC),y)
+CHIP_CSRCS += stm32_rtc.c
+ifeq ($(CONFIG_RTC_ALARM),y)
+CHIP_CSRCS += stm32_exti_alarm.c
+endif
+ifeq ($(CONFIG_RTC_DRIVER),y)
+CHIP_CSRCS += stm32_rtc_lowerhalf.c
+endif
+endif
+
+ifeq ($(filter y,$(CONFIG_STM32F7_IWDG) $(CONFIG_STM32F7_RTC_LSICLOCK)),y)
+CHIP_CSRCS += stm32_lsi.c
endif
ifeq ($(CONFIG_STM32F7_I2C),y)
@@ -147,6 +161,18 @@ ifeq ($(CONFIG_STM32F7_SPI),y)
CHIP_CSRCS += stm32_spi.c
endif
+ifeq ($(CONFIG_STM32F7_SDMMC1),y)
+CHIP_CSRCS += stm32_sdmmc.c
+endif
+
+ifeq ($(CONFIG_USBDEV),y)
+CHIP_CSRCS += stm32_otgdev.c
+endif
+
+ifeq ($(CONFIG_USBHOST),y)
+CHIP_CSRCS += stm32_otghost.c
+endif
+
ifeq ($(CONFIG_STM32F7_TIM),y)
CHIP_CSRCS += stm32_tim.c
endif
@@ -168,3 +194,7 @@ endif
ifeq ($(CONFIG_DEBUG_FEATURES),y)
CHIP_CSRCS += stm32_dumpgpio.c
endif
+
+ifeq ($(CONFIG_STM32F7_BBSRAM),y)
+CHIP_CSRCS += stm32_bbsram.c
+endif
diff --git a/arch/arm/src/stm32f7/chip/stm32_dbgmcu.h b/arch/arm/src/stm32f7/chip/stm32_dbgmcu.h
new file mode 100644
index 0000000000000000000000000000000000000000..73fcd64dccb157d3efd0db9e13ffaf37c05327ae
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32_dbgmcu.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/chip/stm32_dbgmcu.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32_DBGMCU_H
+#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_DBGMCU_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include "chip.h"
+
+#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX)
+# include "chip/stm32f74xx75xx_dbgmcu.h"
+#elif defined(CONFIG_STM32F7_STM32F76XX) || defined(CONFIG_STM32F7_STM32F77XX)
+# include "chip/stm32f76xx77xx_dbgmcu.h"
+#else
+# error "Unsupported STM32 F7 part"
+#endif
+
+#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_DBGMCU_H */
diff --git a/arch/arm/src/stm32f7/chip/stm32_otg.h b/arch/arm/src/stm32f7/chip/stm32_otg.h
new file mode 100644
index 0000000000000000000000000000000000000000..874dd2656397497af2fb810dc06795ab42e48dde
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32_otg.h
@@ -0,0 +1,874 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32f7/chip/stm32f_otg.h
+ *
+ * Copyright (C) 2012, 2014-2016 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved.
+ * Author: Gregory Nutt
+ * Paul Alexander Patience
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32_OTG_H
+#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_OTG_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+/* General definitions */
+
+#define OTG_EPTYPE_CTRL (0) /* Control */
+#define OTG_EPTYPE_ISOC (1) /* Isochronous */
+#define OTG_EPTYPE_BULK (2) /* Bulk */
+#define OTG_EPTYPE_INTR (3) /* Interrupt */
+
+#define OTG_PID_DATA0 (0)
+#define OTG_PID_DATA2 (1)
+#define OTG_PID_DATA1 (2)
+#define OTG_PID_MDATA (3) /* Non-control */
+#define OTG_PID_SETUP (3) /* Control */
+
+/* Register Offsets *********************************************************************************/
+/* Core global control and status registers */
+
+#define STM32_OTG_GOTGCTL_OFFSET 0x0000 /* Control and status register */
+#define STM32_OTG_GOTGINT_OFFSET 0x0004 /* Interrupt register */
+#define STM32_OTG_GAHBCFG_OFFSET 0x0008 /* AHB configuration register */
+#define STM32_OTG_GUSBCFG_OFFSET 0x000c /* USB configuration register */
+#define STM32_OTG_GRSTCTL_OFFSET 0x0010 /* Reset register */
+#define STM32_OTG_GINTSTS_OFFSET 0x0014 /* Core interrupt register */
+#define STM32_OTG_GINTMSK_OFFSET 0x0018 /* Interrupt mask register */
+#define STM32_OTG_GRXSTSR_OFFSET 0x001c /* Receive status debug read/OTG status read register */
+#define STM32_OTG_GRXSTSP_OFFSET 0x0020 /* Receive status debug read/OTG status pop register */
+#define STM32_OTG_GRXFSIZ_OFFSET 0x0024 /* Receive FIFO size register */
+#define STM32_OTG_HNPTXFSIZ_OFFSET 0x0028 /* Host non-periodic transmit FIFO size register */
+#define STM32_OTG_DIEPTXF0_OFFSET 0x0028 /* Endpoint 0 Transmit FIFO size */
+#define STM32_OTG_HNPTXSTS_OFFSET 0x002c /* Non-periodic transmit FIFO/queue status register */
+#define STM32_OTG_GCCFG_OFFSET 0x0038 /* General core configuration register */
+#define STM32_OTG_CID_OFFSET 0x003c /* Core ID register */
+#define STM32_OTG_HPTXFSIZ_OFFSET 0x0100 /* Host periodic transmit FIFO size register */
+
+#define STM32_OTG_DIEPTXF_OFFSET(n) (104+(((n)-1) << 2))
+
+/* Host-mode control and status registers */
+
+#define STM32_OTG_HCFG_OFFSET 0x0400 /* Host configuration register */
+#define STM32_OTG_HFIR_OFFSET 0x0404 /* Host frame interval register */
+#define STM32_OTG_HFNUM_OFFSET 0x0408 /* Host frame number/frame time remaining register */
+#define STM32_OTG_HPTXSTS_OFFSET 0x0410 /* Host periodic transmit FIFO/queue status register */
+#define STM32_OTG_HAINT_OFFSET 0x0414 /* Host all channels interrupt register */
+#define STM32_OTG_HAINTMSK_OFFSET 0x0418 /* Host all channels interrupt mask register */
+#define STM32_OTG_HPRT_OFFSET 0x0440 /* Host port control and status register */
+
+#define STM32_OTG_CHAN_OFFSET(n) (0x500 + ((n) << 5)
+#define STM32_OTG_HCCHAR_CHOFFSET 0x0000 /* Host channel characteristics register */
+#define STM32_OTG_HCINT_CHOFFSET 0x0008 /* Host channel interrupt register */
+#define STM32_OTG_HCINTMSK_CHOFFSET 0x000c /* Host channel interrupt mask register */
+#define STM32_OTG_HCTSIZ_CHOFFSET 0x0010 /* Host channel interrupt register */
+
+#define STM32_OTG_HCCHAR_OFFSET(n) (0x500 + ((n) << 5))
+
+#define STM32_OTG_HCINT_OFFSET(n) (0x508 + ((n) << 5))
+
+#define STM32_OTG_HCINTMSK_OFFSET(n) (0x50c + ((n) << 5))
+
+#define STM32_OTG_HCTSIZ_OFFSET(n) (0x510 + ((n) << 5))
+
+/* Device-mode control and status registers */
+
+#define STM32_OTG_DCFG_OFFSET 0x0800 /* Device configuration register */
+#define STM32_OTG_DCTL_OFFSET 0x0804 /* Device control register */
+#define STM32_OTG_DSTS_OFFSET 0x0808 /* Device status register */
+#define STM32_OTG_DIEPMSK_OFFSET 0x0810 /* Device IN endpoint common interrupt mask register */
+#define STM32_OTG_DOEPMSK_OFFSET 0x0814 /* Device OUT endpoint common interrupt mask register */
+#define STM32_OTG_DAINT_OFFSET 0x0818 /* Device all endpoints interrupt register */
+#define STM32_OTG_DAINTMSK_OFFSET 0x081c /* All endpoints interrupt mask register */
+#define STM32_OTG_DVBUSDIS_OFFSET 0x0828 /* Device VBUS discharge time register */
+#define STM32_OTG_DVBUSPULSE_OFFSET 0x082c /* Device VBUS pulsing time register */
+#define STM32_OTG_DIEPEMPMSK_OFFSET 0x0834 /* Device IN endpoint FIFO empty interrupt mask register */
+
+#define STM32_OTG_DIEP_OFFSET(n) (0x0900 + ((n) << 5))
+#define STM32_OTG_DIEPCTL_EPOFFSET 0x0000 /* Device endpoint control register */
+#define STM32_OTG_DIEPINT_EPOFFSET 0x0008 /* Device endpoint interrupt register */
+#define STM32_OTG_DIEPTSIZ_EPOFFSET 0x0010 /* Device IN endpoint transfer size register */
+#define STM32_OTG_DTXFSTS_EPOFFSET 0x0018 /* Device IN endpoint transmit FIFO status register */
+
+#define STM32_OTG_DIEPCTL_OFFSET(n) (0x0900 + ((n) << 5))
+
+#define STM32_OTG_DIEPINT_OFFSET(n) (0x0908 + ((n) << 5))
+
+#define STM32_OTG_DIEPTSIZ_OFFSET(n) (0x910 + ((n) << 5))
+
+#define STM32_OTG_DTXFSTS_OFFSET(n) (0x0918 + ((n) << 5))
+
+#define STM32_OTG_DOEP_OFFSET(n) (0x0b00 + ((n) << 5))
+#define STM32_OTG_DOEPCTL_EPOFFSET 0x0000 /* Device control OUT endpoint 0 control register */
+#define STM32_OTG_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */
+
+#define STM32_OTG_DOEPCTL_OFFSET(n) (0x0b00 + ((n) << 5))
+
+#define STM32_OTG_DOEPINT_OFFSET(n) (0x0b08 + ((n) << 5))
+
+#define STM32_OTG_DOEPTSIZ_OFFSET(n) (0x0b10 + ((n) << 5))
+
+/* Power and clock gating registers */
+
+#define STM32_OTG_PCGCCTL_OFFSET 0x0e00 /* Power and clock gating control register */
+
+/* Data FIFO (DFIFO) access registers */
+
+#define STM32_OTG_DFIFO_DEP_OFFSET(n) (0x1000 + ((n) << 12))
+#define STM32_OTG_DFIFO_HCH_OFFSET(n) (0x1000 + ((n) << 12))
+
+
+/* Register Addresses *******************************************************************************/
+
+#define STM32_OTG_GOTGCTL (STM32_OTG_BASE+STM32_OTG_GOTGCTL_OFFSET)
+#define STM32_OTG_GOTGINT (STM32_OTG_BASE+STM32_OTG_GOTGINT_OFFSET)
+#define STM32_OTG_GAHBCFG (STM32_OTG_BASE+STM32_OTG_GAHBCFG_OFFSET)
+#define STM32_OTG_GUSBCFG (STM32_OTG_BASE+STM32_OTG_GUSBCFG_OFFSET)
+#define STM32_OTG_GRSTCTL (STM32_OTG_BASE+STM32_OTG_GRSTCTL_OFFSET)
+#define STM32_OTG_GINTSTS (STM32_OTG_BASE+STM32_OTG_GINTSTS_OFFSET)
+#define STM32_OTG_GINTMSK (STM32_OTG_BASE+STM32_OTG_GINTMSK_OFFSET)
+#define STM32_OTG_GRXSTSR (STM32_OTG_BASE+STM32_OTG_GRXSTSR_OFFSET)
+#define STM32_OTG_GRXSTSP (STM32_OTG_BASE+STM32_OTG_GRXSTSP_OFFSET)
+#define STM32_OTG_GRXFSIZ (STM32_OTG_BASE+STM32_OTG_GRXFSIZ_OFFSET)
+#define STM32_OTG_HNPTXFSIZ (STM32_OTG_BASE+STM32_OTG_HNPTXFSIZ_OFFSET)
+#define STM32_OTG_DIEPTXF0 (STM32_OTG_BASE+STM32_OTG_DIEPTXF0_OFFSET)
+#define STM32_OTG_HNPTXSTS (STM32_OTG_BASE+STM32_OTG_HNPTXSTS_OFFSET)
+#define STM32_OTG_GCCFG (STM32_OTG_BASE+STM32_OTG_GCCFG_OFFSET)
+#define STM32_OTG_CID (STM32_OTG_BASE+STM32_OTG_CID_OFFSET)
+#define STM32_OTG_HPTXFSIZ (STM32_OTG_BASE+STM32_OTG_HPTXFSIZ_OFFSET)
+
+#define STM32_OTG_DIEPTXF(n) (STM32_OTG_BASE+STM32_OTG_DIEPTXF_OFFSET(n))
+
+/* Host-mode control and status registers */
+
+#define STM32_OTG_HCFG (STM32_OTG_BASE+STM32_OTG_HCFG_OFFSET)
+#define STM32_OTG_HFIR (STM32_OTG_BASE+STM32_OTG_HFIR_OFFSET)
+#define STM32_OTG_HFNUM (STM32_OTG_BASE+STM32_OTG_HFNUM_OFFSET)
+#define STM32_OTG_HPTXSTS (STM32_OTG_BASE+STM32_OTG_HPTXSTS_OFFSET)
+#define STM32_OTG_HAINT (STM32_OTG_BASE+STM32_OTG_HAINT_OFFSET)
+#define STM32_OTG_HAINTMSK (STM32_OTG_BASE+STM32_OTG_HAINTMSK_OFFSET)
+#define STM32_OTG_HPRT (STM32_OTG_BASE+STM32_OTG_HPRT_OFFSET)
+
+#define STM32_OTG_CHAN(n) (STM32_OTG_BASE+STM32_OTG_CHAN_OFFSET(n))
+
+#define STM32_OTG_HCCHAR(n) (STM32_OTG_BASE+STM32_OTG_HCCHAR_OFFSET(n))
+
+#define STM32_OTG_HCINT(n) (STM32_OTG_BASE+STM32_OTG_HCINT_OFFSET(n))
+
+#define STM32_OTG_HCINTMSK(n) (STM32_OTG_BASE+STM32_OTG_HCINTMSK_OFFSET(n))
+
+#define STM32_OTG_HCTSIZ(n) (STM32_OTG_BASE+STM32_OTG_HCTSIZ_OFFSET(n))
+
+/* Device-mode control and status registers */
+
+#define STM32_OTG_DCFG (STM32_OTG_BASE+STM32_OTG_DCFG_OFFSET)
+#define STM32_OTG_DCTL (STM32_OTG_BASE+STM32_OTG_DCTL_OFFSET)
+#define STM32_OTG_DSTS (STM32_OTG_BASE+STM32_OTG_DSTS_OFFSET)
+#define STM32_OTG_DIEPMSK (STM32_OTG_BASE+STM32_OTG_DIEPMSK_OFFSET)
+#define STM32_OTG_DOEPMSK (STM32_OTG_BASE+STM32_OTG_DOEPMSK_OFFSET)
+#define STM32_OTG_DAINT (STM32_OTG_BASE+STM32_OTG_DAINT_OFFSET)
+#define STM32_OTG_DAINTMSK (STM32_OTG_BASE+STM32_OTG_DAINTMSK_OFFSET)
+#define STM32_OTG_DVBUSDIS (STM32_OTG_BASE+STM32_OTG_DVBUSDIS_OFFSET)
+#define STM32_OTG_DVBUSPULSE (STM32_OTG_BASE+STM32_OTG_DVBUSPULSE_OFFSET)
+#define STM32_OTG_DIEPEMPMSK (STM32_OTG_BASE+STM32_OTG_DIEPEMPMSK_OFFSET)
+
+#define STM32_OTG_DIEP(n) (STM32_OTG_BASE+STM32_OTG_DIEP_OFFSET(n))
+
+#define STM32_OTG_DIEPCTL(n) (STM32_OTG_BASE+STM32_OTG_DIEPCTL_OFFSET(n))
+
+#define STM32_OTG_DIEPINT(n) (STM32_OTG_BASE+STM32_OTG_DIEPINT_OFFSET(n))
+
+#define STM32_OTG_DIEPTSIZ(n) (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ_OFFSET(n))
+
+#define STM32_OTG_DTXFSTS(n) (STM32_OTG_BASE+STM32_OTG_DTXFSTS_OFFSET(n))
+
+#define STM32_OTG_DOEP(n) (STM32_OTG_BASE+STM32_OTG_DOEP_OFFSET(n))
+
+#define STM32_OTG_DOEPCTL(n) (STM32_OTG_BASE+STM32_OTG_DOEPCTL_OFFSET(n))
+
+#define STM32_OTG_DOEPINT(n) (STM32_OTG_BASE+STM32_OTG_DOEPINT_OFFSET(n))
+
+#define STM32_OTG_DOEPTSIZ(n) (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ_OFFSET(n))
+
+/* Power and clock gating registers */
+
+#define STM32_OTG_PCGCCTL (STM32_OTG_BASE+STM32_OTG_PCGCCTL_OFFSET)
+
+/* Data FIFO (DFIFO) access registers */
+
+#define STM32_OTG_DFIFO_DEP(n) (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP_OFFSET(n))
+#define STM32_OTG_DFIFO_HCH(n) (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH_OFFSET(n))
+
+
+/* Register Bitfield Definitions ********************************************************************/
+/* Core global control and status registers */
+
+/* Control and status register */
+
+#define OTG_GOTGCTL_SRQSCS (1 << 0) /* Bit 0: Session request success */
+#define OTG_GOTGCTL_SRQ (1 << 1) /* Bit 1: Session request */
+#define OTG_GOTGCTL_VBVALOEN (1 << 2) /* Bit 2: VBUS valid override enable */
+#define OTG_GOTGCTL_VBVALOVAL (1 << 3) /* Bit 3: VBUS valid override value */
+#define OTG_GOTGCTL_AVALOEN (1 << 4) /* Bit 4: A-peripheral session valid override enable */
+#define OTG_GOTGCTL_AVALOVAL (1 << 5) /* Bit 5: A-peripheral session valid override value */
+#define OTG_GOTGCTL_BVALOEN (1 << 6) /* Bit 6: B-peripheral session valid override enable */
+#define OTG_GOTGCTL_BVALOVAL (1 << 7) /* Bit 7: B-peripheral session valid override value */
+#define OTG_GOTGCTL_HNGSCS (1 << 8) /* Bit 8: Host negotiation success */
+#define OTG_GOTGCTL_HNPRQ (1 << 9) /* Bit 9: HNP request */
+#define OTG_GOTGCTL_HSHNPEN (1 << 10) /* Bit 10: host set HNP enable */
+#define OTG_GOTGCTL_DHNPEN (1 << 11) /* Bit 11: Device HNP enabled */
+#define OTG_GOTGCTL_EHEN (1 << 12) /* Bit 12: Embedded host enable */
+ /* Bits 13-15: Reserved, must be kept at reset value */
+#define OTG_GOTGCTL_CIDSTS (1 << 16) /* Bit 16: Connector ID status */
+#define OTG_GOTGCTL_DBCT (1 << 17) /* Bit 17: Long/short debounce time */
+#define OTG_GOTGCTL_ASVLD (1 << 18) /* Bit 18: A-session valid */
+#define OTG_GOTGCTL_BSVLD (1 << 19) /* Bit 19: B-session valid */
+#define OTG_GOTGCTL_OTGVER (1 << 20) /* Bit 20: OTG version */
+ /* Bits 21-31: Reserved, must be kept at reset value */
+/* Interrupt register */
+ /* Bits 1:0 Reserved, must be kept at reset value */
+#define OTG_GOTGINT_SEDET (1 << 2) /* Bit 2: Session end detected */
+ /* Bits 3-7: Reserved, must be kept at reset value */
+#define OTG_GOTGINT_SRSSCHG (1 << 8) /* Bit 8: Session request success status change */
+#define OTG_GOTGINT_HNSSCHG (1 << 9) /* Bit 9: Host negotiation success status change */
+ /* Bits 16:10 Reserved, must be kept at reset value */
+#define OTG_GOTGINT_HNGDET (1 << 17) /* Bit 17: Host negotiation detected */
+#define OTG_GOTGINT_ADTOCHG (1 << 18) /* Bit 18: A-device timeout change */
+#define OTG_GOTGINT_DBCDNE (1 << 19) /* Bit 19: Debounce done */
+#define OTG_GOTGINT_IDCHNG (1 << 20) /* Bit 20: Change in ID pin input value */
+ /* Bits 21-31: Reserved, must be kept at reset value */
+
+/* AHB configuration register */
+
+#define OTG_GAHBCFG_GINTMSK (1 << 0) /* Bit 0: Global interrupt mask */
+ /* Bits 1-6: Reserved, must be kept at reset value */
+#define OTG_GAHBCFG_TXFELVL (1 << 7) /* Bit 7: TxFIFO empty level */
+#define OTG_GAHBCFG_PTXFELVL (1 << 8) /* Bit 8: Periodic TxFIFO empty level */
+ /* Bits 20-31: Reserved, must be kept at reset value */
+/* USB configuration register */
+
+#define OTG_GUSBCFG_TOCAL_SHIFT (0) /* Bits 0-2: FS timeout calibration */
+#define OTG_GUSBCFG_TOCAL_MASK (7 << OTG_GUSBCFG_TOCAL_SHIFT)
+ /* Bits 3-5: Reserved, must be kept at reset value */
+#define OTG_GUSBCFG_PHYSEL (1 << 6) /* Bit 6: Full Speed serial transceiver select */
+ /* Bit 7: Reserved, must be kept at reset value */
+#define OTG_GUSBCFG_SRPCAP (1 << 8) /* Bit 8: SRP-capable */
+#define OTG_GUSBCFG_HNPCAP (1 << 9) /* Bit 9: HNP-capable */
+#define OTG_GUSBCFG_TRDT_SHIFT (10) /* Bits 10-13: USB turnaround time */
+#define OTG_GUSBCFG_TRDT_MASK (15 << OTG_GUSBCFG_TRDT_SHIFT)
+# define OTG_GUSBCFG_TRDT(n) ((n) << OTG_GUSBCFG_TRDT_SHIFT)
+ /* Bits 14-28: Reserved, must be kept at reset value */
+#define OTG_GUSBCFG_FHMOD (1 << 29) /* Bit 29: Force host mode */
+#define OTG_GUSBCFG_FDMOD (1 << 30) /* Bit 30: Force device mode */
+#define OTG_GUSBCFG_CTXPKT (1 << 31) /* Bit 31: Corrupt Tx packet */
+ /* Bits 20-31: Reserved, must be kept at reset value */
+/* Reset register */
+
+#define OTG_GRSTCTL_CSRST (1 << 0) /* Bit 0: Core soft reset */
+#define OTG_GRSTCTL_HSRST (1 << 1) /* Bit 1: HCLK soft reset */
+#define OTG_GRSTCTL_FCRST (1 << 2) /* Bit 2: Host frame counter reset */
+ /* Bit 3 Reserved, must be kept at reset value */
+#define OTG_GRSTCTL_RXFFLSH (1 << 4) /* Bit 4: RxFIFO flush */
+#define OTG_GRSTCTL_TXFFLSH (1 << 5) /* Bit 5: TxFIFO flush */
+#define OTG_GRSTCTL_TXFNUM_SHIFT (6) /* Bits 6-10: TxFIFO number */
+#define OTG_GRSTCTL_TXFNUM_MASK (31 << OTG_GRSTCTL_TXFNUM_SHIFT)
+# define OTG_GRSTCTL_TXFNUM_HNONPER (0 << OTG_GRSTCTL_TXFNUM_SHIFT) /* Non-periodic TxFIFO flush in host mode */
+# define OTG_GRSTCTL_TXFNUM_HPER (1 << OTG_GRSTCTL_TXFNUM_SHIFT) /* Periodic TxFIFO flush in host mode */
+# define OTG_GRSTCTL_TXFNUM_HALL (16 << OTG_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in host mode.*/
+# define OTG_GRSTCTL_TXFNUM_D(n) ((n) << OTG_GRSTCTL_TXFNUM_SHIFT) /* TXFIFO n flush in device mode, n=0-15 */
+# define OTG_GRSTCTL_TXFNUM_DALL (16 << OTG_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in device mode.*/
+ /* Bits 11-31: Reserved, must be kept at reset value */
+#define OTG_GRSTCTL_AHBIDL (1 << 31) /* Bit 31: AHB master idle */
+
+/* Core interrupt and Interrupt mask registers */
+
+#define OTG_GINTSTS_CMOD (1 << 0) /* Bit 0: Current mode of operation */
+# define OTG_GINTSTS_DEVMODE (0)
+# define OTG_GINTSTS_HOSTMODE (OTG_GINTSTS_CMOD)
+#define OTG_GINT_MMIS (1 << 1) /* Bit 1: Mode mismatch interrupt */
+#define OTG_GINT_OTG (1 << 2) /* Bit 2: OTG interrupt */
+#define OTG_GINT_SOF (1 << 3) /* Bit 3: Start of frame */
+#define OTG_GINT_RXFLVL (1 << 4) /* Bit 4: RxFIFO non-empty */
+#define OTG_GINT_NPTXFE (1 << 5) /* Bit 5: Non-periodic TxFIFO empty */
+#define OTG_GINT_GINAKEFF (1 << 6) /* Bit 6: Global IN non-periodic NAK effective */
+#define OTG_GINT_GONAKEFF (1 << 7) /* Bit 7: Global OUT NAK effective */
+ /* Bits 8-9: Reserved, must be kept at reset value */
+#define OTG_GINT_ESUSP (1 << 10) /* Bit 10: Early suspend */
+#define OTG_GINT_USBSUSP (1 << 11) /* Bit 11: USB suspend */
+#define OTG_GINT_USBRST (1 << 12) /* Bit 12: USB reset */
+#define OTG_GINT_ENUMDNE (1 << 13) /* Bit 13: Enumeration done */
+#define OTG_GINT_ISOODRP (1 << 14) /* Bit 14: Isochronous OUT packet dropped interrupt */
+#define OTG_GINT_EOPF (1 << 15) /* Bit 15: End of periodic frame interrupt */
+ /* Bits 16 Reserved, must be kept at reset value */
+#define OTG_GINTMSK_EPMISM (1 << 17) /* Bit 17: Endpoint mismatch interrupt mask */
+#define OTG_GINT_IEP (1 << 18) /* Bit 18: IN endpoint interrupt */
+#define OTG_GINT_OEP (1 << 19) /* Bit 19: OUT endpoint interrupt */
+#define OTG_GINT_IISOIXFR (1 << 20) /* Bit 20: Incomplete isochronous IN transfer */
+#define OTG_GINT_IISOOXFR (1 << 21) /* Bit 21: Incomplete isochronous OUT transfer (device) */
+#define OTG_GINT_IPXFR (1 << 21) /* Bit 21: Incomplete periodic transfer (host) */
+ /* Bit 22: Reserved, must be kept at reset value */
+#define OTG_GINT_RSTDET (1 << 23) /* Bit 23: Reset detected interrupt */
+#define OTG_GINT_HPRT (1 << 24) /* Bit 24: Host port interrupt */
+#define OTG_GINT_HC (1 << 25) /* Bit 25: Host channels interrupt */
+#define OTG_GINT_PTXFE (1 << 26) /* Bit 26: Periodic TxFIFO empty */
+#define OTG_GINT_LPMINT (1 << 27) /* Bit 27: LPM interrupt */
+#define OTG_GINT_CIDSCHG (1 << 28) /* Bit 28: Connector ID status change */
+#define OTG_GINT_DISC (1 << 29) /* Bit 29: Disconnect detected interrupt */
+#define OTG_GINT_SRQ (1 << 30) /* Bit 30: Session request/new session detected interrupt */
+#define OTG_GINT_WKUP (1 << 31) /* Bit 31: Resume/remote wakeup detected interrupt */
+
+/* Receive status debug read/OTG status read and pop registers (host mode) */
+
+#define OTG_GRXSTSH_CHNUM_SHIFT (0) /* Bits 0-3: Channel number */
+#define OTG_GRXSTSH_CHNUM_MASK (15 << OTG_GRXSTSH_CHNUM_SHIFT)
+#define OTG_GRXSTSH_BCNT_SHIFT (4) /* Bits 4-14: Byte count */
+#define OTG_GRXSTSH_BCNT_MASK (0x7ff << OTG_GRXSTSH_BCNT_SHIFT)
+#define OTG_GRXSTSH_DPID_SHIFT (15) /* Bits 15-16: Data PID */
+#define OTG_GRXSTSH_DPID_MASK (3 << OTG_GRXSTSH_DPID_SHIFT)
+# define OTG_GRXSTSH_DPID_DATA0 (0 << OTG_GRXSTSH_DPID_SHIFT)
+# define OTG_GRXSTSH_DPID_DATA2 (1 << OTG_GRXSTSH_DPID_SHIFT)
+# define OTG_GRXSTSH_DPID_DATA1 (2 << OTG_GRXSTSH_DPID_SHIFT)
+# define OTG_GRXSTSH_DPID_MDATA (3 << OTG_GRXSTSH_DPID_SHIFT)
+#define OTG_GRXSTSH_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */
+#define OTG_GRXSTSH_PKTSTS_MASK (15 << OTG_GRXSTSH_PKTSTS_SHIFT)
+# define OTG_GRXSTSH_PKTSTS_INRECVD (2 << OTG_GRXSTSH_PKTSTS_SHIFT) /* IN data packet received */
+# define OTG_GRXSTSH_PKTSTS_INDONE (3 << OTG_GRXSTSH_PKTSTS_SHIFT) /* IN transfer completed */
+# define OTG_GRXSTSH_PKTSTS_DTOGERR (5 << OTG_GRXSTSH_PKTSTS_SHIFT) /* Data toggle error */
+# define OTG_GRXSTSH_PKTSTS_HALTED (7 << OTG_GRXSTSH_PKTSTS_SHIFT) /* Channel halted */
+ /* Bits 21-31: Reserved, must be kept at reset value */
+/* Receive status debug read/OTG status read and pop registers (device mode) */
+
+#define OTG_GRXSTSD_EPNUM_SHIFT (0) /* Bits 0-3: Endpoint number */
+#define OTG_GRXSTSD_EPNUM_MASK (15 << OTG_GRXSTSD_EPNUM_SHIFT)
+#define OTG_GRXSTSD_BCNT_SHIFT (4) /* Bits 4-14: Byte count */
+#define OTG_GRXSTSD_BCNT_MASK (0x7ff << OTG_GRXSTSD_BCNT_SHIFT)
+#define OTG_GRXSTSD_DPID_SHIFT (15) /* Bits 15-16: Data PID */
+#define OTG_GRXSTSD_DPID_MASK (3 << OTG_GRXSTSD_DPID_SHIFT)
+# define OTG_GRXSTSD_DPID_DATA0 (0 << OTG_GRXSTSD_DPID_SHIFT)
+# define OTG_GRXSTSD_DPID_DATA2 (1 << OTG_GRXSTSD_DPID_SHIFT)
+# define OTG_GRXSTSD_DPID_DATA1 (2 << OTG_GRXSTSD_DPID_SHIFT)
+# define OTG_GRXSTSD_DPID_MDATA (3 << OTG_GRXSTSD_DPID_SHIFT)
+#define OTG_GRXSTSD_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */
+#define OTG_GRXSTSD_PKTSTS_MASK (15 << OTG_GRXSTSD_PKTSTS_SHIFT)
+# define OTG_GRXSTSD_PKTSTS_OUTNAK (1 << OTG_GRXSTSD_PKTSTS_SHIFT) /* Global OUT NAK */
+# define OTG_GRXSTSD_PKTSTS_OUTRECVD (2 << OTG_GRXSTSD_PKTSTS_SHIFT) /* OUT data packet received */
+# define OTG_GRXSTSD_PKTSTS_OUTDONE (3 << OTG_GRXSTSD_PKTSTS_SHIFT) /* OUT transfer completed */
+# define OTG_GRXSTSD_PKTSTS_SETUPDONE (4 << OTG_GRXSTSD_PKTSTS_SHIFT) /* SETUP transaction completed */
+# define OTG_GRXSTSD_PKTSTS_SETUPRECVD (6 << OTG_GRXSTSD_PKTSTS_SHIFT) /* SETUP data packet received */
+#define OTG_GRXSTSD_FRMNUM_SHIFT (21) /* Bits 21-24: Frame number */
+#define OTG_GRXSTSD_FRMNUM_MASK (15 << OTG_GRXSTSD_FRMNUM_SHIFT)
+ /* Bits 25-31: Reserved, must be kept at reset value */
+/* Receive FIFO size register */
+
+#define OTG_GRXFSIZ_MASK (0xffff)
+
+/* Host non-periodic transmit FIFO size register */
+
+#define OTG_HNPTXFSIZ_NPTXFSA_SHIFT (0) /* Bits 0-15: Non-periodic transmit RAM start address */
+#define OTG_HNPTXFSIZ_NPTXFSA_MASK (0xffff << OTG_HNPTXFSIZ_NPTXFSA_SHIFT)
+#define OTG_HNPTXFSIZ_NPTXFD_SHIFT (16) /* Bits 16-31: Non-periodic TxFIFO depth */
+#define OTG_HNPTXFSIZ_NPTXFD_MASK (0xffff << OTG_HNPTXFSIZ_NPTXFD_SHIFT)
+# define OTG_HNPTXFSIZ_NPTXFD_MIN (16 << OTG_HNPTXFSIZ_NPTXFD_SHIFT)
+# define OTG_HNPTXFSIZ_NPTXFD_MAX (256 << OTG_HNPTXFSIZ_NPTXFD_SHIFT)
+
+/* Endpoint 0 Transmit FIFO size */
+
+#define OTG_DIEPTXF0_TX0FD_SHIFT (0) /* Bits 0-15: Endpoint 0 transmit RAM start address */
+#define OTG_DIEPTXF0_TX0FD_MASK (0xffff << OTG_DIEPTXF0_TX0FD_SHIFT)
+#define OTG_DIEPTXF0_TX0FSA_SHIFT (16) /* Bits 16-31: Endpoint 0 TxFIFO depth */
+#define OTG_DIEPTXF0_TX0FSA_MASK (0xffff << OTG_DIEPTXF0_TX0FSA_SHIFT)
+# define OTG_DIEPTXF0_TX0FSA_MIN (16 << OTG_DIEPTXF0_TX0FSA_SHIFT)
+# define OTG_DIEPTXF0_TX0FSA_MAX (256 << OTG_DIEPTXF0_TX0FSA_SHIFT)
+
+/* Non-periodic transmit FIFO/queue status register */
+
+#define OTG_HNPTXSTS_NPTXFSAV_SHIFT (0) /* Bits 0-15: Non-periodic TxFIFO space available */
+#define OTG_HNPTXSTS_NPTXFSAV_MASK (0xffff << OTG_HNPTXSTS_NPTXFSAV_SHIFT)
+# define OTG_HNPTXSTS_NPTXFSAV_FULL (0 << OTG_HNPTXSTS_NPTXFSAV_SHIFT)
+#define OTG_HNPTXSTS_NPTQXSAV_SHIFT (16) /* Bits 16-23: Non-periodic transmit request queue space available */
+#define OTG_HNPTXSTS_NPTQXSAV_MASK (0xff << OTG_HNPTXSTS_NPTQXSAV_SHIFT)
+# define OTG_HNPTXSTS_NPTQXSAV_FULL (0 << OTG_HNPTXSTS_NPTQXSAV_SHIFT)
+#define OTG_HNPTXSTS_NPTXQTOP_SHIFT (24) /* Bits 24-30: Top of the non-periodic transmit request queue */
+#define OTG_HNPTXSTS_NPTXQTOP_MASK (0x7f << OTG_HNPTXSTS_NPTXQTOP_SHIFT)
+# define OTG_HNPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */
+# define OTG_HNPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Status */
+# define OTG_HNPTXSTS_TYPE_MASK (3 << OTG_HNPTXSTS_TYPE_SHIFT)
+# define OTG_HNPTXSTS_TYPE_INOUT (0 << OTG_HNPTXSTS_TYPE_SHIFT) /* IN/OUT token */
+# define OTG_HNPTXSTS_TYPE_ZLP (1 << OTG_HNPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet (device IN/host OUT) */
+# define OTG_HNPTXSTS_TYPE_HALT (3 << OTG_HNPTXSTS_TYPE_SHIFT) /* Channel halt command */
+# define OTG_HNPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */
+# define OTG_HNPTXSTS_CHNUM_MASK (15 << OTG_HNPTXSTS_CHNUM_SHIFT)
+# define OTG_HNPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */
+# define OTG_HNPTXSTS_EPNUM_MASK (15 << OTG_HNPTXSTS_EPNUM_SHIFT)
+ /* Bit 31 Reserved, must be kept at reset value */
+/* General core configuration register */
+ /* Bits 0-15: Reserved, must be kept at reset value */
+#define OTG_GCCFG_PWRDWN (1 << 16) /* Bit 16: Power down */
+ /* Bit 17 Reserved, must be kept at reset value */
+#define OTG_GCCFG_VBDEN (1 << 21) /* Bit 21: USB VBUS detection enable */
+ /* Bits 22-31: Reserved, must be kept at reset value */
+/* Core ID register (32-bit product ID) */
+
+/* Host periodic transmit FIFO size register */
+
+#define OTG_HPTXFSIZ_PTXSA_SHIFT (0) /* Bits 0-15: Host periodic TxFIFO start address */
+#define OTG_HPTXFSIZ_PTXSA_MASK (0xffff << OTG_HPTXFSIZ_PTXSA_SHIFT)
+#define OTG_HPTXFSIZ_PTXFD_SHIFT (16) /* Bits 16-31: Host periodic TxFIFO depth */
+#define OTG_HPTXFSIZ_PTXFD_MASK (0xffff << OTG_HPTXFSIZ_PTXFD_SHIFT)
+
+/* Device IN endpoint transmit FIFOn size register */
+
+#define OTG_DIEPTXF_INEPTXSA_SHIFT (0) /* Bits 0-15: IN endpoint FIFOx transmit RAM start address */
+#define OTG_DIEPTXF_INEPTXSA_MASK (0xffff << OTG_DIEPTXF_INEPTXSA_SHIFT)
+#define OTG_DIEPTXF_INEPTXFD_SHIFT (16) /* Bits 16-31: IN endpoint TxFIFO depth */
+#define OTG_DIEPTXF_INEPTXFD_MASK (0xffff << OTG_DIEPTXF_INEPTXFD_SHIFT)
+# define OTG_DIEPTXF_INEPTXFD_MIN (16 << OTG_DIEPTXF_INEPTXFD_MASK)
+
+/* Host-mode control and status registers */
+
+/* Host configuration register */
+
+#define OTG_HCFG_FSLSPCS_SHIFT (0) /* Bits 0-1: FS/LS PHY clock select */
+#define OTG_HCFG_FSLSPCS_MASK (3 << OTG_HCFG_FSLSPCS_SHIFT)
+# define OTG_HCFG_FSLSPCS_FS48MHz (1 << OTG_HCFG_FSLSPCS_SHIFT) /* FS host mode, PHY clock is running at 48 MHz */
+# define OTG_HCFG_FSLSPCS_LS48MHz (1 << OTG_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 48 MHz PHY clock frequency */
+# define OTG_HCFG_FSLSPCS_LS6MHz (2 << OTG_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 6 MHz PHY clock frequency */
+#define OTG_HCFG_FSLSS (1 << 2) /* Bit 2: FS- and LS-only support */
+ /* Bits 31:3 Reserved, must be kept at reset value */
+/* Host frame interval register */
+
+#define OTG_HFIR_MASK (0xffff)
+
+/* Host frame number/frame time remaining register */
+
+#define OTG_HFNUM_FRNUM_SHIFT (0) /* Bits 0-15: Frame number */
+#define OTG_HFNUM_FRNUM_MASK (0xffff << OTG_HFNUM_FRNUM_SHIFT)
+#define OTG_HFNUM_FTREM_SHIFT (16) /* Bits 16-31: Frame time remaining */
+#define OTG_HFNUM_FTREM_MASK (0xffff << OTG_HFNUM_FTREM_SHIFT)
+
+/* Host periodic transmit FIFO/queue status register */
+
+#define OTG_HPTXSTS_PTXFSAVL_SHIFT (0) /* Bits 0-15: Periodic transmit data FIFO space available */
+#define OTG_HPTXSTS_PTXFSAVL_MASK (0xffff << OTG_HPTXSTS_PTXFSAVL_SHIFT)
+# define OTG_HPTXSTS_PTXFSAVL_FULL (0 << OTG_HPTXSTS_PTXFSAVL_SHIFT)
+#define OTG_HPTXSTS_PTXQSAV_SHIFT (16) /* Bits 16-23: Periodic transmit request queue space available */
+#define OTG_HPTXSTS_PTXQSAV_MASK (0xff << OTG_HPTXSTS_PTXQSAV_SHIFT)
+# define OTG_HPTXSTS_PTXQSAV_FULL (0 << OTG_HPTXSTS_PTXQSAV_SHIFT)
+#define OTG_HPTXSTS_PTXQTOP_SHIFT (24) /* Bits 24-31: Top of the periodic transmit request queue */
+#define OTG_HPTXSTS_PTXQTOP_MASK (0x7f << OTG_HPTXSTS_PTXQTOP_SHIFT)
+# define OTG_HPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */
+# define OTG_HPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Type */
+# define OTG_HPTXSTS_TYPE_MASK (3 << OTG_HPTXSTS_TYPE_SHIFT)
+# define OTG_HPTXSTS_TYPE_INOUT (0 << OTG_HPTXSTS_TYPE_SHIFT) /* IN/OUT token */
+# define OTG_HPTXSTS_TYPE_ZLP (1 << OTG_HPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet */
+# define OTG_HPTXSTS_TYPE_HALT (3 << OTG_HPTXSTS_TYPE_SHIFT) /* Disable channel command */
+# define OTG_HPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */
+# define OTG_HPTXSTS_EPNUM_MASK (15 << OTG_HPTXSTS_EPNUM_SHIFT)
+# define OTG_HPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */
+# define OTG_HPTXSTS_CHNUM_MASK (15 << OTG_HPTXSTS_CHNUM_SHIFT)
+# define OTG_HPTXSTS_ODD (1 << 24) /* Bit 31: Send in odd (vs even) frame */
+
+/* Host all channels interrupt and all channels interrupt mask registers */
+
+#define OTG_HAINT(n) (1 << (n)) /* Bits 15:0 HAINTM: Channel interrupt */
+
+/* Host port control and status register */
+
+#define OTG_HPRT_PCSTS (1 << 0) /* Bit 0: Port connect status */
+#define OTG_HPRT_PCDET (1 << 1) /* Bit 1: Port connect detected */
+#define OTG_HPRT_PENA (1 << 2) /* Bit 2: Port enable */
+#define OTG_HPRT_PENCHNG (1 << 3) /* Bit 3: Port enable/disable change */
+#define OTG_HPRT_POCA (1 << 4) /* Bit 4: Port overcurrent active */
+#define OTG_HPRT_POCCHNG (1 << 5) /* Bit 5: Port overcurrent change */
+#define OTG_HPRT_PRES (1 << 6) /* Bit 6: Port resume */
+#define OTG_HPRT_PSUSP (1 << 7) /* Bit 7: Port suspend */
+#define OTG_HPRT_PRST (1 << 8) /* Bit 8: Port reset */
+ /* Bit 9: Reserved, must be kept at reset value */
+#define OTG_HPRT_PLSTS_SHIFT (10) /* Bits 10-11: Port line status */
+#define OTG_HPRT_PLSTS_MASK (3 << OTG_HPRT_PLSTS_SHIFT)
+# define OTG_HPRT_PLSTS_DP (1 << 10) /* Bit 10: Logic level of OTG_FS_FS_DP */
+# define OTG_HPRT_PLSTS_DM (1 << 11) /* Bit 11: Logic level of OTG_FS_FS_DM */
+#define OTG_HPRT_PPWR (1 << 12) /* Bit 12: Port power */
+#define OTG_HPRT_PTCTL_SHIFT (13) /* Bits 13-16: Port test control */
+#define OTG_HPRT_PTCTL_MASK (15 << OTG_HPRT_PTCTL_SHIFT)
+# define OTG_HPRT_PTCTL_DISABLED (0 << OTG_HPRT_PTCTL_SHIFT) /* Test mode disabled */
+# define OTG_HPRT_PTCTL_J (1 << OTG_HPRT_PTCTL_SHIFT) /* Test_J mode */
+# define OTG_HPRT_PTCTL_L (2 << OTG_HPRT_PTCTL_SHIFT) /* Test_K mode */
+# define OTG_HPRT_PTCTL_SE0_NAK (3 << OTG_HPRT_PTCTL_SHIFT) /* Test_SE0_NAK mode */
+# define OTG_HPRT_PTCTL_PACKET (4 << OTG_HPRT_PTCTL_SHIFT) /* Test_Packet mode */
+# define OTG_HPRT_PTCTL_FORCE (5 << OTG_HPRT_PTCTL_SHIFT) /* Test_Force_Enable */
+#define OTG_HPRT_PSPD_SHIFT (17) /* Bits 17-18: Port speed */
+#define OTG_HPRT_PSPD_MASK (3 << OTG_HPRT_PSPD_SHIFT)
+# define OTG_HPRT_PSPD_FS (1 << OTG_HPRT_PSPD_SHIFT) /* Full speed */
+# define OTG_HPRT_PSPD_LS (2 << OTG_HPRT_PSPD_SHIFT) /* Low speed */
+ /* Bits 19-31: Reserved, must be kept at reset value */
+
+/* Host channel-n characteristics register */
+
+#define OTG_HCCHAR_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */
+#define OTG_HCCHAR_MPSIZ_MASK (0x7ff << OTG_HCCHAR_MPSIZ_SHIFT)
+#define OTG_HCCHAR_EPNUM_SHIFT (11) /* Bits 11-14: Endpoint number */
+#define OTG_HCCHAR_EPNUM_MASK (15 << OTG_HCCHAR_EPNUM_SHIFT)
+#define OTG_HCCHAR_EPDIR (1 << 15) /* Bit 15: Endpoint direction */
+# define OTG_HCCHAR_EPDIR_OUT (0)
+# define OTG_HCCHAR_EPDIR_IN OTG_HCCHAR_EPDIR
+ /* Bit 16 Reserved, must be kept at reset value */
+#define OTG_HCCHAR_LSDEV (1 << 17) /* Bit 17: Low-speed device */
+#define OTG_HCCHAR_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */
+#define OTG_HCCHAR_EPTYP_MASK (3 << OTG_HCCHAR_EPTYP_SHIFT)
+# define OTG_HCCHAR_EPTYP_CTRL (0 << OTG_HCCHAR_EPTYP_SHIFT) /* Control */
+# define OTG_HCCHAR_EPTYP_ISOC (1 << OTG_HCCHAR_EPTYP_SHIFT) /* Isochronous */
+# define OTG_HCCHAR_EPTYP_BULK (2 << OTG_HCCHAR_EPTYP_SHIFT) /* Bulk */
+# define OTG_HCCHAR_EPTYP_INTR (3 << OTG_HCCHAR_EPTYP_SHIFT) /* Interrupt */
+#define OTG_HCCHAR_MCNT_SHIFT (20) /* Bits 20-21: Multicount */
+#define OTG_HCCHAR_MCNT_MASK (3 << OTG_HCCHAR_MCNT_SHIFT)
+#define OTG_HCCHAR_DAD_SHIFT (22) /* Bits 22-28: Device address */
+#define OTG_HCCHAR_DAD_MASK (0x7f << OTG_HCCHAR_DAD_SHIFT)
+#define OTG_HCCHAR_ODDFRM (1 << 29) /* Bit 29: Odd frame */
+#define OTG_HCCHAR_CHDIS (1 << 30) /* Bit 30: Channel disable */
+#define OTG_HCCHAR_CHENA (1 << 31) /* Bit 31: Channel enable */
+
+/* Host channel-n interrupt and Host channel-0 interrupt mask registers */
+
+#define OTG_HCINT_XFRC (1 << 0) /* Bit 0: Transfer completed */
+#define OTG_HCINT_CHH (1 << 1) /* Bit 1: Channel halted */
+ /* Bit 2: Reserved, must be kept at reset value */
+#define OTG_HCINT_STALL (1 << 3) /* Bit 3: STALL response received interrupt */
+#define OTG_HCINT_NAK (1 << 4) /* Bit 4: NAK response received interrupt */
+#define OTG_HCINT_ACK (1 << 5) /* Bit 5: ACK response received/transmitted interrupt */
+#define OTG_HCINT_NYET (1 << 6) /* Bit 6: Response received interrupt */
+#define OTG_HCINT_TXERR (1 << 7) /* Bit 7: Transaction error */
+#define OTG_HCINT_BBERR (1 << 8) /* Bit 8: Babble error */
+#define OTG_HCINT_FRMOR (1 << 9) /* Bit 9: Frame overrun */
+#define OTG_HCINT_DTERR (1 << 10) /* Bit 10: Data toggle error */
+ /* Bits 11-31 Reserved, must be kept at reset value */
+/* Host channel-n interrupt register */
+
+#define OTG_HCTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */
+#define OTG_HCTSIZ_XFRSIZ_MASK (0x7ffff << OTG_HCTSIZ_XFRSIZ_SHIFT)
+#define OTG_HCTSIZ_PKTCNT_SHIFT (19) /* Bits 19-28: Packet count */
+#define OTG_HCTSIZ_PKTCNT_MASK (0x3ff << OTG_HCTSIZ_PKTCNT_SHIFT)
+#define OTG_HCTSIZ_DPID_SHIFT (29) /* Bits 29-30: Data PID */
+#define OTG_HCTSIZ_DPID_MASK (3 << OTG_HCTSIZ_DPID_SHIFT)
+# define OTG_HCTSIZ_DPID_DATA0 (0 << OTG_HCTSIZ_DPID_SHIFT)
+# define OTG_HCTSIZ_DPID_DATA2 (1 << OTG_HCTSIZ_DPID_SHIFT)
+# define OTG_HCTSIZ_DPID_DATA1 (2 << OTG_HCTSIZ_DPID_SHIFT)
+# define OTG_HCTSIZ_DPID_MDATA (3 << OTG_HCTSIZ_DPID_SHIFT) /* Non-control */
+# define OTG_HCTSIZ_PID_SETUP (3 << OTG_HCTSIZ_DPID_SHIFT) /* Control */
+ /* Bit 31 Reserved, must be kept at reset value */
+/* Device-mode control and status registers */
+
+/* Device configuration register */
+
+#define OTG_DCFG_DSPD_SHIFT (0) /* Bits 0-1: Device speed */
+#define OTG_DCFG_DSPD_MASK (3 << OTG_DCFG_DSPD_SHIFT)
+# define OTG_DCFG_DSPD_FS (3 << OTG_DCFG_DSPD_SHIFT) /* Full speed */
+#define OTG_DCFG_NZLSOHSK (1 << 2) /* Bit 2: Non-zero-length status OUT handshake */
+ /* Bit 3: Reserved, must be kept at reset value */
+#define OTG_DCFG_DAD_SHIFT (4) /* Bits 4-10: Device address */
+#define OTG_DCFG_DAD_MASK (0x7f << OTG_DCFG_DAD_SHIFT)
+#define OTG_DCFG_PFIVL_SHIFT (11) /* Bits 11-12: Periodic frame interval */
+#define OTG_DCFG_PFIVL_MASK (3 << OTG_DCFG_PFIVL_SHIFT)
+# define OTG_DCFG_PFIVL_80PCT (0 << OTG_DCFG_PFIVL_SHIFT) /* 80% of the frame interval */
+# define OTG_DCFG_PFIVL_85PCT (1 << OTG_DCFG_PFIVL_SHIFT) /* 85% of the frame interval */
+# define OTG_DCFG_PFIVL_90PCT (2 << OTG_DCFG_PFIVL_SHIFT) /* 90% of the frame interval */
+# define OTG_DCFG_PFIVL_95PCT (3 << OTG_DCFG_PFIVL_SHIFT) /* 95% of the frame interval */
+ /* Bits 13-31 Reserved, must be kept at reset value */
+/* Device control register */
+
+#define OTG_TESTMODE_DISABLED (0) /* Test mode disabled */
+#define OTG_TESTMODE_J (1) /* Test_J mode */
+#define OTG_TESTMODE_K (2) /* Test_K mode */
+#define OTG_TESTMODE_SE0_NAK (3) /* Test_SE0_NAK mode */
+#define OTG_TESTMODE_PACKET (4) /* Test_Packet mode */
+#define OTG_TESTMODE_FORCE (5) /* Test_Force_Enable */
+
+#define OTG_DCTL_RWUSIG (1 << 0) /* Bit 0: Remote wakeup signaling */
+#define OTG_DCTL_SDIS (1 << 1) /* Bit 1: Soft disconnect */
+#define OTG_DCTL_GINSTS (1 << 2) /* Bit 2: Global IN NAK status */
+#define OTG_DCTL_GONSTS (1 << 3) /* Bit 3: Global OUT NAK status */
+#define OTG_DCTL_TCTL_SHIFT (4) /* Bits 4-6: Test control */
+#define OTG_DCTL_TCTL_MASK (7 << OTG_DCTL_TCTL_SHIFT)
+# define OTG_DCTL_TCTL_DISABLED (0 << OTG_DCTL_TCTL_SHIFT) /* Test mode disabled */
+# define OTG_DCTL_TCTL_J (1 << OTG_DCTL_TCTL_SHIFT) /* Test_J mode */
+# define OTG_DCTL_TCTL_K (2 << OTG_DCTL_TCTL_SHIFT) /* Test_K mode */
+# define OTG_DCTL_TCTL_SE0_NAK (3 << OTG_DCTL_TCTL_SHIFT) /* Test_SE0_NAK mode */
+# define OTG_DCTL_TCTL_PACKET (4 << OTG_DCTL_TCTL_SHIFT) /* Test_Packet mode */
+# define OTG_DCTL_TCTL_FORCE (5 << OTG_DCTL_TCTL_SHIFT) /* Test_Force_Enable */
+#define OTG_DCTL_SGINAK (1 << 7) /* Bit 7: Set global IN NAK */
+#define OTG_DCTL_CGINAK (1 << 8) /* Bit 8: Clear global IN NAK */
+#define OTG_DCTL_SGONAK (1 << 9) /* Bit 9: Set global OUT NAK */
+#define OTG_DCTL_CGONAK (1 << 10) /* Bit 10: Clear global OUT NAK */
+#define OTG_DCTL_POPRGDNE (1 << 11) /* Bit 11: Power-on programming done */
+ /* Bits 12-31: Reserved, must be kept at reset value */
+/* Device status register */
+
+#define OTG_DSTS_SUSPSTS (1 << 0) /* Bit 0: Suspend status */
+#define OTG_DSTS_ENUMSPD_SHIFT (1) /* Bits 1-2: Enumerated speed */
+#define OTG_DSTS_ENUMSPD_MASK (3 << OTG_DSTS_ENUMSPD_SHIFT)
+# define OTG_DSTS_ENUMSPD_FS (3 << OTG_DSTS_ENUMSPD_MASK) /* Full speed */
+ /* Bits 4-7: Reserved, must be kept at reset value */
+#define OTG_DSTS_EERR (1 << 3) /* Bit 3: Erratic error */
+#define OTG_DSTS_SOFFN_SHIFT (8) /* Bits 8-21: Frame number of the received SOF */
+#define OTG_DSTS_SOFFN_MASK (0x3fff << OTG_DSTS_SOFFN_SHIFT)
+#define OTG_DSTS_SOFFN0 (1 << 8) /* Bits 8: Frame number even/odd bit */
+#define OTG_DSTS_SOFFN_EVEN 0
+#define OTG_DSTS_SOFFN_ODD OTG_DSTS_SOFFN0
+ /* Bits 22-31: Reserved, must be kept at reset value */
+/* Device IN endpoint common interrupt mask register */
+
+#define OTG_DIEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */
+#define OTG_DIEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */
+ /* Bit 2: Reserved, must be kept at reset value */
+#define OTG_DIEPMSK_TOM (1 << 3) /* Bit 3: Timeout condition mask (Non-isochronous endpoints) */
+#define OTG_DIEPMSK_ITTXFEMSK (1 << 4) /* Bit 4: IN token received when TxFIFO empty mask */
+#define OTG_DIEPMSK_INEPNMM (1 << 5) /* Bit 5: IN token received with EP mismatch mask */
+#define OTG_DIEPMSK_INEPNEM (1 << 6) /* Bit 6: IN endpoint NAK effective mask */
+ /* Bits 7-31: Reserved, must be kept at reset value */
+/* Device OUT endpoint common interrupt mask register */
+
+#define OTG_DOEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */
+#define OTG_DOEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */
+ /* Bit 2: Reserved, must be kept at reset value */
+#define OTG_DOEPMSK_STUPM (1 << 3) /* Bit 3: SETUP phase done mask */
+#define OTG_DOEPMSK_OTEPDM (1 << 4) /* Bit 4: OUT token received when endpoint disabled mask */
+ /* Bits 5-31: Reserved, must be kept at reset value */
+/* Device all endpoints interrupt and All endpoints interrupt mask registers */
+
+#define OTG_DAINT_IEP_SHIFT (0) /* Bits 0-15: IN endpoint interrupt bits */
+#define OTG_DAINT_IEP_MASK (0xffff << OTG_DAINT_IEP_SHIFT)
+# define OTG_DAINT_IEP(n) (1 << (n))
+#define OTG_DAINT_OEP_SHIFT (16) /* Bits 16-31: OUT endpoint interrupt bits */
+#define OTG_DAINT_OEP_MASK (0xffff << OTG_DAINT_OEP_SHIFT)
+# define OTG_DAINT_OEP(n) (1 << ((n)+16))
+
+/* Device VBUS discharge time register */
+
+#define OTG_DVBUSDIS_MASK (0xffff)
+
+/* Device VBUS pulsing time register */
+
+#define OTG_DVBUSPULSE_MASK (0xfff)
+
+/* Device IN endpoint FIFO empty interrupt mask register */
+
+#define OTG_DIEPEMPMSK(n) (1 << (n))
+
+/* Device control IN endpoint 0 control register */
+
+#define OTG_DIEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */
+#define OTG_DIEPCTL0_MPSIZ_MASK (3 << OTG_DIEPCTL0_MPSIZ_SHIFT)
+# define OTG_DIEPCTL0_MPSIZ_64 (0 << OTG_DIEPCTL0_MPSIZ_SHIFT) /* 64 bytes */
+# define OTG_DIEPCTL0_MPSIZ_32 (1 << OTG_DIEPCTL0_MPSIZ_SHIFT) /* 32 bytes */
+# define OTG_DIEPCTL0_MPSIZ_16 (2 << OTG_DIEPCTL0_MPSIZ_SHIFT) /* 16 bytes */
+# define OTG_DIEPCTL0_MPSIZ_8 (3 << OTG_DIEPCTL0_MPSIZ_SHIFT) /* 8 bytes */
+ /* Bits 2-14: Reserved, must be kept at reset value */
+#define OTG_DIEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */
+ /* Bit 16: Reserved, must be kept at reset value */
+#define OTG_DIEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */
+#define OTG_DIEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */
+#define OTG_DIEPCTL0_EPTYP_MASK (3 << OTG_DIEPCTL0_EPTYP_SHIFT)
+# define OTG_DIEPCTL0_EPTYP_CTRL (0 << OTG_DIEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */
+ /* Bit 20: Reserved, must be kept at reset value */
+#define OTG_DIEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */
+#define OTG_DIEPCTL0_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */
+#define OTG_DIEPCTL0_TXFNUM_MASK (15 << OTG_DIEPCTL0_TXFNUM_SHIFT)
+#define OTG_DIEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */
+#define OTG_DIEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */
+ /* Bits 28-29: Reserved, must be kept at reset value */
+#define OTG_DIEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */
+#define OTG_DIEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */
+
+/* Device control IN endpoint n control register */
+
+#define OTG_DIEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */
+#define OTG_DIEPCTL_MPSIZ_MASK (0x7ff << OTG_DIEPCTL_MPSIZ_SHIFT)
+ /* Bits 11-14: Reserved, must be kept at reset value */
+#define OTG_DIEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */
+#define OTG_DIEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame */
+# define OTG_DIEPCTL_EVEN (0)
+# define OTG_DIEPCTL_ODD OTG_DIEPCTL_EONUM
+# define OTG_DIEPCTL_DATA0 (0)
+# define OTG_DIEPCTL_DATA1 OTG_DIEPCTL_EONUM
+#define OTG_DIEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */
+#define OTG_DIEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */
+#define OTG_DIEPCTL_EPTYP_MASK (3 << OTG_DIEPCTL_EPTYP_SHIFT)
+# define OTG_DIEPCTL_EPTYP_CTRL (0 << OTG_DIEPCTL_EPTYP_SHIFT) /* Control */
+# define OTG_DIEPCTL_EPTYP_ISOC (1 << OTG_DIEPCTL_EPTYP_SHIFT) /* Isochronous */
+# define OTG_DIEPCTL_EPTYP_BULK (2 << OTG_DIEPCTL_EPTYP_SHIFT) /* Bulk */
+# define OTG_DIEPCTL_EPTYP_INTR (3 << OTG_DIEPCTL_EPTYP_SHIFT) /* Interrupt */
+ /* Bit 20: Reserved, must be kept at reset value */
+#define OTG_DIEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */
+#define OTG_DIEPCTL_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */
+#define OTG_DIEPCTL_TXFNUM_MASK (15 << OTG_DIEPCTL_TXFNUM_SHIFT)
+#define OTG_DIEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */
+#define OTG_DIEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */
+#define OTG_DIEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */
+#define OTG_DIEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous)) */
+#define OTG_DIEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous) */
+#define OTG_DIEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */
+#define OTG_DIEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */
+
+/* Device endpoint-n interrupt register */
+
+#define OTG_DIEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */
+#define OTG_DIEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */
+ /* Bit 2: Reserved, must be kept at reset value */
+#define OTG_DIEPINT_TOC (1 << 3) /* Bit 3: Timeout condition */
+#define OTG_DIEPINT_ITTXFE (1 << 4) /* Bit 4: IN token received when TxFIFO is empty */
+ /* Bit 5: Reserved, must be kept at reset value */
+#define OTG_DIEPINT_INEPNE (1 << 6) /* Bit 6: IN endpoint NAK effective */
+#define OTG_DIEPINT_TXFE (1 << 7) /* Bit 7: Transmit FIFO empty */
+ /* Bits 8-31: Reserved, must be kept at reset value */
+/* Device IN endpoint 0 transfer size register */
+
+#define OTG_DIEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */
+#define OTG_DIEPTSIZ0_XFRSIZ_MASK (0x7f << OTG_DIEPTSIZ0_XFRSIZ_SHIFT)
+ /* Bits 7-18: Reserved, must be kept at reset value */
+#define OTG_DIEPTSIZ0_PKTCNT_SHIFT (19) /* Bits 19-20: Packet count */
+#define OTG_DIEPTSIZ0_PKTCNT_MASK (3 << OTG_DIEPTSIZ0_PKTCNT_SHIFT)
+ /* Bits 21-31: Reserved, must be kept at reset value */
+/* Device IN endpoint n transfer size register */
+
+#define OTG_DIEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */
+#define OTG_DIEPTSIZ_XFRSIZ_MASK (0x7ffff << OTG_DIEPTSIZ_XFRSIZ_SHIFT)
+#define OTG_DIEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */
+#define OTG_DIEPTSIZ_PKTCNT_MASK (0x3ff << OTG_DIEPTSIZ_PKTCNT_SHIFT)
+#define OTG_DIEPTSIZ_MCNT_SHIFT (29) /* Bits 29-30: Multi count */
+#define OTG_DIEPTSIZ_MCNT_MASK (3 << OTG_DIEPTSIZ_MCNT_SHIFT)
+ /* Bit 31: Reserved, must be kept at reset value */
+/* Device OUT endpoint TxFIFO status register */
+
+#define OTG_DTXFSTS_MASK (0xffff)
+
+/* Device OUT endpoint 0 control register */
+
+#define OTG_DOEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */
+#define OTG_DOEPCTL0_MPSIZ_MASK (3 << OTG_DOEPCTL0_MPSIZ_SHIFT)
+# define OTG_DOEPCTL0_MPSIZ_64 (0 << OTG_DOEPCTL0_MPSIZ_SHIFT) /* 64 bytes */
+# define OTG_DOEPCTL0_MPSIZ_32 (1 << OTG_DOEPCTL0_MPSIZ_SHIFT) /* 32 bytes */
+# define OTG_DOEPCTL0_MPSIZ_16 (2 << OTG_DOEPCTL0_MPSIZ_SHIFT) /* 16 bytes */
+# define OTG_DOEPCTL0_MPSIZ_8 (3 << OTG_DOEPCTL0_MPSIZ_SHIFT) /* 8 bytes */
+ /* Bits 2-14: Reserved, must be kept at reset value */
+#define OTG_DOEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */
+ /* Bit 16: Reserved, must be kept at reset value */
+#define OTG_DOEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */
+#define OTG_DOEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */
+#define OTG_DOEPCTL0_EPTYP_MASK (3 << OTG_DOEPCTL0_EPTYP_SHIFT)
+# define OTG_DOEPCTL0_EPTYP_CTRL (0 << OTG_DOEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */
+#define OTG_DOEPCTL0_SNPM (1 << 20) /* Bit 20: Snoop mode */
+#define OTG_DOEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */
+ /* Bits 22-25: Reserved, must be kept at reset value */
+#define OTG_DOEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */
+#define OTG_DOEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */
+ /* Bits 28-29: Reserved, must be kept at reset value */
+#define OTG_DOEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */
+#define OTG_DOEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */
+
+/* Device OUT endpoint n control register */
+
+#define OTG_DOEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */
+#define OTG_DOEPCTL_MPSIZ_MASK (0x7ff << OTG_DOEPCTL_MPSIZ_SHIFT)
+ /* Bits 11-14: Reserved, must be kept at reset value */
+#define OTG_DOEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */
+#define OTG_DOEPCTL_DPID (1 << 16) /* Bit 16: Endpoint data PID (interrupt/buld) */
+# define OTG_DOEPCTL_DATA0 (0)
+# define OTG_DOEPCTL_DATA1 OTG_DOEPCTL_DPID
+#define OTG_DOEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame (isochronous) */
+# define OTG_DOEPCTL_EVEN (0)
+# define OTG_DOEPCTL_ODD OTG_DOEPCTL_EONUM
+#define OTG_DOEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */
+#define OTG_DOEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */
+#define OTG_DOEPCTL_EPTYP_MASK (3 << OTG_DOEPCTL_EPTYP_SHIFT)
+# define OTG_DOEPCTL_EPTYP_CTRL (0 << OTG_DOEPCTL_EPTYP_SHIFT) /* Control */
+# define OTG_DOEPCTL_EPTYP_ISOC (1 << OTG_DOEPCTL_EPTYP_SHIFT) /* Isochronous */
+# define OTG_DOEPCTL_EPTYP_BULK (2 << OTG_DOEPCTL_EPTYP_SHIFT) /* Bulk */
+# define OTG_DOEPCTL_EPTYP_INTR (3 << OTG_DOEPCTL_EPTYP_SHIFT) /* Interrupt */
+#define OTG_DOEPCTL_SNPM (1 << 20) /* Bit 20: Snoop mode */
+#define OTG_DOEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */
+ /* Bits 22-25: Reserved, must be kept at reset value */
+#define OTG_DOEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */
+#define OTG_DOEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */
+#define OTG_DOEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */
+#define OTG_DOEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous) */
+#define OTG_DOEPCTL_SD1PID (1 << 29) /* Bit 29: Set DATA1 PID (interrupt/bulk) */
+#define OTG_DOEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous */
+#define OTG_DOEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */
+#define OTG_DOEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */
+
+/* Device endpoint-n interrupt register */
+
+#define OTG_DOEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */
+#define OTG_DOEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */
+ /* Bit 2: Reserved, must be kept at reset value */
+#define OTG_DOEPINT_SETUP (1 << 3) /* Bit 3: SETUP phase done */
+#define OTG_DOEPINT_OTEPDIS (1 << 4) /* Bit 4: OUT token received when endpoint disabled */
+ /* Bit 5: Reserved, must be kept at reset value */
+#define OTG_DOEPINT_B2BSTUP (1 << 6) /* Bit 6: Back-to-back SETUP packets received */
+ /* Bits 7-31: Reserved, must be kept at reset value */
+/* Device OUT endpoint-0 transfer size register */
+
+#define OTG_DOEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */
+#define OTG_DOEPTSIZ0_XFRSIZ_MASK (0x7f << OTG_DOEPTSIZ0_XFRSIZ_SHIFT)
+ /* Bits 7-18: Reserved, must be kept at reset value */
+#define OTG_DOEPTSIZ0_PKTCNT (1 << 19) /* Bit 19 PKTCNT: Packet count */
+ /* Bits 20-28: Reserved, must be kept at reset value */
+#define OTG_DOEPTSIZ0_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */
+#define OTG_DOEPTSIZ0_STUPCNT_MASK (3 << OTG_DOEPTSIZ0_STUPCNT_SHIFT)
+ /* Bit 31: Reserved, must be kept at reset value */
+/* Device OUT endpoint-n transfer size register */
+
+#define OTG_DOEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */
+#define OTG_DOEPTSIZ_XFRSIZ_MASK (0x7ffff << OTG_DOEPTSIZ_XFRSIZ_SHIFT)
+#define OTG_DOEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */
+#define OTG_DOEPTSIZ_PKTCNT_MASK (0x3ff << OTG_DOEPTSIZ_PKTCNT_SHIFT)
+#define OTG_DOEPTSIZ_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */
+#define OTG_DOEPTSIZ_STUPCNT_MASK (3 << OTG_DOEPTSIZ_STUPCNT_SHIFT)
+#define OTG_DOEPTSIZ_RXDPID_SHIFT (29) /* Bits 29-30: Received data PID */
+#define OTG_DOEPTSIZ_RXDPID_MASK (3 << OTG_DOEPTSIZ_RXDPID_SHIFT)
+# define OTG_DOEPTSIZ_RXDPID_DATA0 (0 << OTG_DOEPTSIZ_RXDPID_SHIFT)
+# define OTG_DOEPTSIZ_RXDPID_DATA2 (1 << OTG_DOEPTSIZ_RXDPID_SHIFT)
+# define OTG_DOEPTSIZ_RXDPID_DATA1 (2 << OTG_DOEPTSIZ_RXDPID_SHIFT)
+# define OTG_DOEPTSIZ_RXDPID_MDATA (3 << OTG_DOEPTSIZ_RXDPID_SHIFT)
+ /* Bit 31: Reserved, must be kept at reset value */
+/* Power and clock gating control register */
+
+#define OTG_PCGCCTL_STPPCLK (1 << 0) /* Bit 0: Stop PHY clock */
+#define OTG_PCGCCTL_GATEHCLK (1 << 1) /* Bit 1: Gate HCLK */
+ /* Bits 2-3: Reserved, must be kept at reset value */
+#define OTG_PCGCCTL_PHYSUSP (1 << 4) /* Bit 4: PHY Suspended */
+ /* Bits 5-31: Reserved, must be kept at reset value */
+
+#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_OTG_H */
diff --git a/arch/arm/src/stm32f7/chip/stm32_rtcc.h b/arch/arm/src/stm32f7/chip/stm32_rtcc.h
new file mode 100644
index 0000000000000000000000000000000000000000..262a48633cbbafd8b4502f9490030ca6d560876b
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32_rtcc.h
@@ -0,0 +1,405 @@
+/************************************************************************************
+ * arch/arm/src/stm32f7/chip/stm32_rtcc.h
+ *
+ * Copyright (C) 2011-2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32_RTCC_H
+#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_RTCC_H
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Register Offsets *****************************************************************/
+
+#define STM32_RTC_TR_OFFSET 0x0000 /* RTC time register */
+#define STM32_RTC_DR_OFFSET 0x0004 /* RTC date register */
+#define STM32_RTC_CR_OFFSET 0x0008 /* RTC control register */
+#define STM32_RTC_ISR_OFFSET 0x000c /* RTC initialization and status register */
+#define STM32_RTC_PRER_OFFSET 0x0010 /* RTC prescaler register */
+#define STM32_RTC_WUTR_OFFSET 0x0014 /* RTC wakeup timer register */
+#define STM32_RTC_ALRMAR_OFFSET 0x001c /* RTC alarm A register */
+#define STM32_RTC_ALRMBR_OFFSET 0x0020 /* RTC alarm B register */
+#define STM32_RTC_WPR_OFFSET 0x0024 /* RTC write protection register */
+#define STM32_RTC_SSR_OFFSET 0x0028 /* RTC sub second register */
+#define STM32_RTC_SHIFTR_OFFSET 0x002c /* RTC shift control register */
+#define STM32_RTC_TSTR_OFFSET 0x0030 /* RTC time stamp time register */
+#define STM32_RTC_TSDR_OFFSET 0x0034 /* RTC time stamp date register */
+#define STM32_RTC_TSSSR_OFFSET 0x0038 /* RTC timestamp sub second register */
+#define STM32_RTC_CALR_OFFSET 0x003c /* RTC calibration register */
+#define STM32_RTC_TAMPCR_OFFSET 0x0040 /* RTC tamper configuration register */
+#define STM32_RTC_ALRMASSR_OFFSET 0x0044 /* RTC alarm A sub second register */
+#define STM32_RTC_ALRMBSSR_OFFSET 0x0048 /* RTC alarm B sub second register */
+#define STM32_RTC_OR_OFFSET 0x004c /* RTC option register */
+
+#define STM32_RTC_BKR_OFFSET(n) (0x0050+((n)<<2))
+#define STM32_RTC_BK0R_OFFSET 0x0050 /* RTC backup register 0 */
+#define STM32_RTC_BK1R_OFFSET 0x0054 /* RTC backup register 1 */
+#define STM32_RTC_BK2R_OFFSET 0x0058 /* RTC backup register 2 */
+#define STM32_RTC_BK3R_OFFSET 0x005c /* RTC backup register 3 */
+#define STM32_RTC_BK4R_OFFSET 0x0060 /* RTC backup register 4 */
+#define STM32_RTC_BK5R_OFFSET 0x0064 /* RTC backup register 5 */
+#define STM32_RTC_BK6R_OFFSET 0x0068 /* RTC backup register 6 */
+#define STM32_RTC_BK7R_OFFSET 0x006c /* RTC backup register 7 */
+#define STM32_RTC_BK8R_OFFSET 0x0070 /* RTC backup register 8 */
+#define STM32_RTC_BK9R_OFFSET 0x0074 /* RTC backup register 9 */
+#define STM32_RTC_BK10R_OFFSET 0x0078 /* RTC backup register 10 */
+#define STM32_RTC_BK11R_OFFSET 0x007c /* RTC backup register 11 */
+#define STM32_RTC_BK12R_OFFSET 0x0080 /* RTC backup register 12 */
+#define STM32_RTC_BK13R_OFFSET 0x0084 /* RTC backup register 13 */
+#define STM32_RTC_BK14R_OFFSET 0x0088 /* RTC backup register 14 */
+#define STM32_RTC_BK15R_OFFSET 0x008c /* RTC backup register 15 */
+#define STM32_RTC_BK16R_OFFSET 0x0090 /* RTC backup register 16 */
+#define STM32_RTC_BK17R_OFFSET 0x0094 /* RTC backup register 17 */
+#define STM32_RTC_BK18R_OFFSET 0x0098 /* RTC backup register 18 */
+#define STM32_RTC_BK19R_OFFSET 0x009c /* RTC backup register 19 */
+#define STM32_RTC_BK20R_OFFSET 0x00a0 /* RTC backup register 20 */
+#define STM32_RTC_BK21R_OFFSET 0x00a4 /* RTC backup register 21 */
+#define STM32_RTC_BK22R_OFFSET 0x00a8 /* RTC backup register 22 */
+#define STM32_RTC_BK23R_OFFSET 0x00ac /* RTC backup register 23 */
+#define STM32_RTC_BK24R_OFFSET 0x00b0 /* RTC backup register 24 */
+#define STM32_RTC_BK25R_OFFSET 0x00b4 /* RTC backup register 25 */
+#define STM32_RTC_BK26R_OFFSET 0x00b8 /* RTC backup register 26 */
+#define STM32_RTC_BK27R_OFFSET 0x00bc /* RTC backup register 27 */
+#define STM32_RTC_BK28R_OFFSET 0x00c0 /* RTC backup register 28 */
+#define STM32_RTC_BK29R_OFFSET 0x00c4 /* RTC backup register 29 */
+#define STM32_RTC_BK30R_OFFSET 0x00c8 /* RTC backup register 30 */
+#define STM32_RTC_BK31R_OFFSET 0x00cc /* RTC backup register 31 */
+
+/* Register Addresses ***************************************************************/
+
+#define STM32_RTC_TR (STM32_RTC_BASE+STM32_RTC_TR_OFFSET)
+#define STM32_RTC_DR (STM32_RTC_BASE+STM32_RTC_DR_OFFSET)
+#define STM32_RTC_CR (STM32_RTC_BASE+STM32_RTC_CR_OFFSET)
+#define STM32_RTC_ISR (STM32_RTC_BASE+STM32_RTC_ISR_OFFSET)
+#define STM32_RTC_PRER (STM32_RTC_BASE+STM32_RTC_PRER_OFFSET)
+#define STM32_RTC_WUTR (STM32_RTC_BASE+STM32_RTC_WUTR_OFFSET)
+#define STM32_RTC_ALRMAR (STM32_RTC_BASE+STM32_RTC_ALRMAR_OFFSET)
+#define STM32_RTC_ALRMBR (STM32_RTC_BASE+STM32_RTC_ALRMBR_OFFSET)
+#define STM32_RTC_WPR (STM32_RTC_BASE+STM32_RTC_WPR_OFFSET)
+#define STM32_RTC_SSR (STM32_RTC_BASE+STM32_RTC_SSR_OFFSET)
+#define STM32_RTC_SHIFTR (STM32_RTC_BASE+STM32_RTC_SHIFTR_OFFSET)
+#define STM32_RTC_TSTR (STM32_RTC_BASE+STM32_RTC_TSTR_OFFSET)
+#define STM32_RTC_TSDR (STM32_RTC_BASE+STM32_RTC_TSDR_OFFSET)
+#define STM32_RTC_TSSSR (STM32_RTC_BASE+STM32_RTC_TSSSR_OFFSET)
+#define STM32_RTC_CALR (STM32_RTC_BASE+STM32_RTC_CALR_OFFSET)
+#define STM32_RTC_TAMPCR (STM32_RTC_BASE+STM32_RTC_TAMPCR_OFFSET)
+#define STM32_RTC_ALRMASSR (STM32_RTC_BASE+STM32_RTC_ALRMASSR_OFFSET)
+#define STM32_RTC_ALRMBSSR (STM32_RTC_BASE+STM32_RTC_ALRMBSSR_OFFSET)
+
+#define STM32_RTC_BKR(n) (STM32_RTC_BASE+STM32_RTC_BKR_OFFSET(n))
+#define STM32_RTC_BK0R (STM32_RTC_BASE+STM32_RTC_BK0R_OFFSET)
+#define STM32_RTC_BK1R (STM32_RTC_BASE+STM32_RTC_BK1R_OFFSET)
+#define STM32_RTC_BK2R (STM32_RTC_BASE+STM32_RTC_BK2R_OFFSET)
+#define STM32_RTC_BK3R (STM32_RTC_BASE+STM32_RTC_BK3R_OFFSET)
+#define STM32_RTC_BK4R (STM32_RTC_BASE+STM32_RTC_BK4R_OFFSET)
+#define STM32_RTC_BK5R (STM32_RTC_BASE+STM32_RTC_BK5R_OFFSET)
+#define STM32_RTC_BK6R (STM32_RTC_BASE+STM32_RTC_BK6R_OFFSET)
+#define STM32_RTC_BK7R (STM32_RTC_BASE+STM32_RTC_BK7R_OFFSET)
+#define STM32_RTC_BK8R (STM32_RTC_BASE+STM32_RTC_BK8R_OFFSET)
+#define STM32_RTC_BK9R (STM32_RTC_BASE+STM32_RTC_BK9R_OFFSET)
+#define STM32_RTC_BK10R (STM32_RTC_BASE+STM32_RTC_BK10R_OFFSET)
+#define STM32_RTC_BK11R (STM32_RTC_BASE+STM32_RTC_BK11R_OFFSET)
+#define STM32_RTC_BK12R (STM32_RTC_BASE+STM32_RTC_BK12R_OFFSET)
+#define STM32_RTC_BK13R (STM32_RTC_BASE+STM32_RTC_BK13R_OFFSET)
+#define STM32_RTC_BK14R (STM32_RTC_BASE+STM32_RTC_BK14R_OFFSET)
+#define STM32_RTC_BK15R (STM32_RTC_BASE+STM32_RTC_BK15R_OFFSET)
+#define STM32_RTC_BK16R (STM32_RTC_BASE+STM32_RTC_BK16R_OFFSET)
+#define STM32_RTC_BK17R (STM32_RTC_BASE+STM32_RTC_BK17R_OFFSET)
+#define STM32_RTC_BK18R (STM32_RTC_BASE+STM32_RTC_BK18R_OFFSET)
+#define STM32_RTC_BK19R (STM32_RTC_BASE+STM32_RTC_BK19R_OFFSET)
+#define STM32_RTC_BK20R (STM32_RTC_BASE+STM32_RTC_BK20R_OFFSET)
+#define STM32_RTC_BK21R (STM32_RTC_BASE+STM32_RTC_BK21R_OFFSET)
+#define STM32_RTC_BK22R (STM32_RTC_BASE+STM32_RTC_BK22R_OFFSET)
+#define STM32_RTC_BK23R (STM32_RTC_BASE+STM32_RTC_BK23R_OFFSET)
+#define STM32_RTC_BK24R (STM32_RTC_BASE+STM32_RTC_BK24R_OFFSET)
+#define STM32_RTC_BK25R (STM32_RTC_BASE+STM32_RTC_BK25R_OFFSET)
+#define STM32_RTC_BK26R (STM32_RTC_BASE+STM32_RTC_BK26R_OFFSET)
+#define STM32_RTC_BK27R (STM32_RTC_BASE+STM32_RTC_BK27R_OFFSET)
+#define STM32_RTC_BK28R (STM32_RTC_BASE+STM32_RTC_BK28R_OFFSET)
+#define STM32_RTC_BK29R (STM32_RTC_BASE+STM32_RTC_BK29R_OFFSET)
+#define STM32_RTC_BK30R (STM32_RTC_BASE+STM32_RTC_BK30R_OFFSET)
+#define STM32_RTC_BK31R (STM32_RTC_BASE+STM32_RTC_BK31R_OFFSET)
+
+#define STM32_RTC_BKCOUNT 32
+
+/* Register Bitfield Definitions ****************************************************/
+
+/* RTC time register */
+
+#define RTC_TR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format */
+#define RTC_TR_SU_MASK (15 << RTC_TR_SU_SHIFT)
+#define RTC_TR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format */
+#define RTC_TR_ST_MASK (7 << RTC_TR_ST_SHIFT)
+#define RTC_TR_MNU_SHIFT (8) /* Bit 8-11: Minute units in BCD format */
+#define RTC_TR_MNU_MASK (15 << RTC_TR_MNU_SHIFT)
+#define RTC_TR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format */
+#define RTC_TR_MNT_MASK (7 << RTC_TR_MNT_SHIFT)
+#define RTC_TR_HU_SHIFT (16) /* Bit 16-19: Hour units in BCD format */
+#define RTC_TR_HU_MASK (15 << RTC_TR_HU_SHIFT)
+#define RTC_TR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format */
+#define RTC_TR_HT_MASK (3 << RTC_TR_HT_SHIFT)
+#define RTC_TR_PM (1 << 22) /* Bit 22: AM/PM notation */
+#define RTC_TR_RESERVED_BITS (0xff808080)
+
+/* RTC date register */
+
+#define RTC_DR_DU_SHIFT (0) /* Bits 0-3: Date units in BCD format */
+#define RTC_DR_DU_MASK (15 << RTC_DR_DU_SHIFT)
+#define RTC_DR_DT_SHIFT (4) /* Bits 4-5: Date tens in BCD format */
+#define RTC_DR_DT_MASK (3 << RTC_DR_DT_SHIFT)
+#define RTC_DR_MU_SHIFT (8) /* Bits 8-11: Month units in BCD format */
+#define RTC_DR_MU_MASK (15 << RTC_DR_MU_SHIFT)
+#define RTC_DR_MT (1 << 12) /* Bit 12: Month tens in BCD format */
+#define RTC_DR_WDU_SHIFT (13) /* Bits 13-15: Week day units */
+#define RTC_DR_WDU_MASK (7 << RTC_DR_WDU_SHIFT)
+# define RTC_DR_WDU_MONDAY (1 << RTC_DR_WDU_SHIFT)
+# define RTC_DR_WDU_TUESDAY (2 << RTC_DR_WDU_SHIFT)
+# define RTC_DR_WDU_WEDNESDAY (3 << RTC_DR_WDU_SHIFT)
+# define RTC_DR_WDU_THURSDAY (4 << RTC_DR_WDU_SHIFT)
+# define RTC_DR_WDU_FRIDAY (5 << RTC_DR_WDU_SHIFT)
+# define RTC_DR_WDU_SATURDAY (6 << RTC_DR_WDU_SHIFT)
+# define RTC_DR_WDU_SUNDAY (7 << RTC_DR_WDU_SHIFT)
+#define RTC_DR_YU_SHIFT (16) /* Bits 16-19: Year units in BCD format */
+#define RTC_DR_YU_MASK (15 << RTC_DR_YU_SHIFT)
+#define RTC_DR_YT_SHIFT (20) /* Bits 20-23: Year tens in BCD format */
+#define RTC_DR_YT_MASK (15 << RTC_DR_YT_SHIFT)
+#define RTC_DR_RESERVED_BITS (0xff0000c0)
+
+/* RTC control register */
+
+#define RTC_CR_WUCKSEL_SHIFT (0) /* Bits 0-2: Wakeup clock selection */
+#define RTC_CR_WUCKSEL_MASK (7 << RTC_CR_WUCKSEL_SHIFT)
+# define RTC_CR_WUCKSEL_RTCDIV16 (0 << RTC_CR_WUCKSEL_SHIFT) /* 000: RTC/16 clock is selected */
+# define RTC_CR_WUCKSEL_RTCDIV8 (1 << RTC_CR_WUCKSEL_SHIFT) /* 001: RTC/8 clock is selected */
+# define RTC_CR_WUCKSEL_RTCDIV4 (2 << RTC_CR_WUCKSEL_SHIFT) /* 010: RTC/4 clock is selected */
+# define RTC_CR_WUCKSEL_RTCDIV2 (3 << RTC_CR_WUCKSEL_SHIFT) /* 011: RTC/2 clock is selected */
+# define RTC_CR_WUCKSEL_CKSPRE (4 << RTC_CR_WUCKSEL_SHIFT) /* 10x: ck_spre clock is selected */
+# define RTC_CR_WUCKSEL_CKSPREADD (6 << RTC_CR_WUCKSEL_SHIFT) /* 11x: ck_spr clock and 216 added WUT counter */
+#define RTC_CR_TSEDGE (1 << 3) /* Bit 3: Timestamp event active edge */
+#define RTC_CR_REFCKON (1 << 4) /* Bit 4: Reference clock detection enable (50 or 60 Hz) */
+#define RTC_CR_BYPSHAD (1 << 5) /* Bit 5: Bypass the shadow registers */
+#define RTC_CR_FMT (1 << 6) /* Bit 6: Hour format */
+#define RTC_CR_ALRAE (1 << 8) /* Bit 8: Alarm A enable */
+#define RTC_CR_ALRBE (1 << 9) /* Bit 9: Alarm B enable */
+#define RTC_CR_WUTE (1 << 10) /* Bit 10: Wakeup timer enable */
+#define RTC_CR_TSE (1 << 11) /* Bit 11: Time stamp enable */
+#define RTC_CR_ALRAIE (1 << 12) /* Bit 12: Alarm A interrupt enable */
+#define RTC_CR_ALRBIE (1 << 13) /* Bit 13: Alarm B interrupt enable */
+#define RTC_CR_WUTIE (1 << 14) /* Bit 14: Wakeup timer interrupt enable */
+#define RTC_CR_TSIE (1 << 15) /* Bit 15: Timestamp interrupt enable */
+#define RTC_CR_ADD1H (1 << 16) /* Bit 16: Add 1 hour (summer time change) */
+#define RTC_CR_SUB1H (1 << 17) /* Bit 17: Subtract 1 hour (winter time change) */
+#define RTC_CR_BKP (1 << 18) /* Bit 18: Backup */
+#define RTC_CR_COSEL (1 << 19) /* Bit 19 : Calibration output selection */
+#define RTC_CR_POL (1 << 20) /* Bit 20: Output polarity */
+#define RTC_CR_OSEL_SHIFT (21) /* Bits 21-22: Output selection */
+#define RTC_CR_OSEL_MASK (3 << RTC_CR_OSEL_SHIFT)
+# define RTC_CR_OSEL_DISABLED (0 << RTC_CR_OSEL_SHIFT) /* 00: Output disabled */
+# define RTC_CR_OSEL_ALRMA (1 << RTC_CR_OSEL_SHIFT) /* 01: Alarm A output enabled */
+# define RTC_CR_OSEL_ALRMB (2 << RTC_CR_OSEL_SHIFT) /* 10: Alarm B output enabled */
+# define RTC_CR_OSEL_WUT (3 << RTC_CR_OSEL_SHIFT) /* 11: Wakeup output enabled */
+#define RTC_CR_COE (1 << 23) /* Bit 23: Calibration output enable */
+#define RTC_CR_ITSE (1 << 24) /* Bit 24: Timestamp on internal event enable */
+
+/* RTC initialization and status register */
+
+#define RTC_ISR_ALRAWF (1 << 0) /* Bit 0: Alarm A write flag */
+#define RTC_ISR_ALRBWF (1 << 1) /* Bit 1: Alarm B write flag */
+#define RTC_ISR_WUTWF (1 << 2) /* Bit 2: Wakeup timer write flag */
+#define RTC_ISR_SHPF (1 << 3) /* Bit 3: Shift operation pending */
+#define RTC_ISR_INITS (1 << 4) /* Bit 4: Initialization status flag */
+#define RTC_ISR_RSF (1 << 5) /* Bit 5: Registers synchronization flag */
+#define RTC_ISR_INITF (1 << 6) /* Bit 6: Initialization flag */
+#define RTC_ISR_INIT (1 << 7) /* Bit 7: Initialization mode */
+#define RTC_ISR_ALRAF (1 << 8) /* Bit 8: Alarm A flag */
+#define RTC_ISR_ALRBF (1 << 9) /* Bit 9: Alarm B flag */
+#define RTC_ISR_WUTF (1 << 10) /* Bit 10: Wakeup timer flag */
+#define RTC_ISR_TSF (1 << 11) /* Bit 11: Timestamp flag */
+#define RTC_ISR_TSOVF (1 << 12) /* Bit 12: Timestamp overflow flag */
+#define RTC_ISR_TAMP1F (1 << 13) /* Bit 13: Tamper detection flag */
+#define RTC_ISR_TAMP2F (1 << 14) /* Bit 14: TAMPER2 detection flag */
+#define RTC_ISR_TAMP3F (1 << 15) /* Bit 15: TAMPER3 detection flag */
+#define RTC_ISR_RECALPF (1 << 16) /* Bit 16: Recalibration pending Flag */
+#define RTC_ISR_ITSF (1 << 17) /* Bit 17:Internal tTime-stamp flagg */
+#define RTC_ISR_ALLFLAGS (0x0003ffff)
+
+/* RTC prescaler register */
+
+#define RTC_PRER_PREDIV_S_SHIFT (0) /* Bits 0-14: Synchronous prescaler factor */
+#define RTC_PRER_PREDIV_S_MASK (0x7fff << RTC_PRER_PREDIV_S_SHIFT)
+#define RTC_PRER_PREDIV_A_SHIFT (16) /* Bits 16-22: Asynchronous prescaler factor */
+#define RTC_PRER_PREDIV_A_MASK (0x7f << RTC_PRER_PREDIV_A_SHIFT)
+
+/* RTC wakeup timer register */
+
+#define RTC_WUTR_MASK (0xffff) /* Bits 15:0 Wakeup auto-reload value bits */
+
+/* RTC alarm A/B registers */
+
+#define RTC_ALRMR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format. */
+#define RTC_ALRMR_SU_MASK (15 << RTC_ALRMR_SU_SHIFT)
+#define RTC_ALRMR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format. */
+#define RTC_ALRMR_ST_MASK (7 << RTC_ALRMR_ST_SHIFT)
+#define RTC_ALRMR_MSK1 (1 << 7) /* Bit 7 : Alarm A seconds mask */
+#define RTC_ALRMR_MNU_SHIFT (8) /* Bits 8-11: Minute units in BCD format. */
+#define RTC_ALRMR_MNU_MASK (15 << RTC_ALRMR_MNU_SHIFT)
+#define RTC_ALRMR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format. */
+#define RTC_ALRMR_MNT_MASK (7 << RTC_ALRMR_MNT_SHIFT)
+#define RTC_ALRMR_MSK2 (1 << 15) /* Bit 15 : Alarm A minutes mask */
+#define RTC_ALRMR_HU_SHIFT (16) /* Bits 16-19: Hour units in BCD format. */
+#define RTC_ALRMR_HU_MASK (15 << RTC_ALRMR_HU_SHIFT)
+#define RTC_ALRMR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format. */
+#define RTC_ALRMR_HT_MASK (3 << RTC_ALRMR_HT_SHIFT)
+#define RTC_ALRMR_PM (1 << 22) /* Bit 22 : AM/PM notation */
+#define RTC_ALRMR_MSK3 (1 << 23) /* Bit 23 : Alarm A hours mask */
+#define RTC_ALRMR_DU_SHIFT (24) /* Bits 24-27: Date units or day in BCD format. */
+#define RTC_ALRMR_DU_MASK (15 << RTC_ALRMR_DU_SHIFT)
+#define RTC_ALRMR_DT_SHIFT (28) /* Bits 28-29: Date tens in BCD format. */
+#define RTC_ALRMR_DT_MASK (3 << RTC_ALRMR_DT_SHIFT)
+#define RTC_ALRMR_WDSEL (1 << 30) /* Bit 30: Week day selection */
+#define RTC_ALRMR_MSK4 (1 << 31) /* Bit 31: Alarm A date mask */
+
+/* RTC write protection register */
+
+#define RTC_WPR_MASK (0xff) /* Bits 0-7: Write protection key */
+
+/* RTC sub second register */
+
+#define RTC_SSR_MASK (0xffff) /* Bits 0-15: Sub second value */
+
+/* RTC shift control register */
+
+#define RTC_SHIFTR_SUBFS_SHIFT (0) /* Bits 0-14: Subtract a fraction of a second */
+#define RTC_SHIFTR_SUBFS_MASK (0x7ffff << RTC_SHIFTR_SUBFS_SHIFT)
+#define RTC_SHIFTR_ADD1S (1 << 31) /* Bit 31: Add one second */
+
+/* RTC time stamp time register */
+
+#define RTC_TSTR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format. */
+#define RTC_TSTR_SU_MASK (15 << RTC_TSTR_SU_SHIFT)
+#define RTC_TSTR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format. */
+#define RTC_TSTR_ST_MASK (7 << RTC_TSTR_ST_SHIFT)
+#define RTC_TSTR_MNU_SHIFT (8) /* Bits 8-11: Minute units in BCD format. */
+#define RTC_TSTR_MNU_MASK (15 << RTC_TSTR_MNU_SHIFT)
+#define RTC_TSTR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format. */
+#define RTC_TSTR_MNT_MASK (7 << RTC_TSTR_MNT_SHIFT)
+#define RTC_TSTR_HU_SHIFT (16) /* Bits 16-19: Hour units in BCD format. */
+#define RTC_TSTR_HU_MASK (15 << RTC_TSTR_HU_SHIFT)
+#define RTC_TSTR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format. */
+#define RTC_TSTR_HT_MASK (3 << RTC_TSTR_HT_SHIFT)
+#define RTC_TSTR_PM (1 << 22) /* Bit 22: AM/PM notation */
+
+/* RTC time stamp date register */
+
+#define RTC_TSDR_DU_SHIFT (0) /* Bit 0-3: Date units in BCD format */
+#define RTC_TSDR_DU_MASK (15 << RTC_TSDR_DU_SHIFT) */
+#define RTC_TSDR_DT_SHIFT (4) /* Bits 4-5: Date tens in BCD format */
+#define RTC_TSDR_DT_MASK (3 << RTC_TSDR_DT_SHIFT)
+#define RTC_TSDR_MU_SHIFT (8) /* Bits 8-11: Month units in BCD format */
+#define RTC_TSDR_MU_MASK (xx << RTC_TSDR_MU_SHIFT)
+#define RTC_TSDR_MT (1 << 12) /* Bit 12: Month tens in BCD format */
+#define RTC_TSDR_WDU_SHIFT (13) /* Bits 13-15: Week day units */
+#define RTC_TSDR_WDU_MASK (7 << RTC_TSDR_WDU_SHIFT)
+
+/* RTC timestamp sub second register */
+
+#define RTC_TSSSR_MASK (0xffff) /* Bits 0-15: Sub second value */
+
+/* RTC calibration register */
+
+#define RTC_CALR_CALM_SHIFT (0) /* Bits 0-8: Calibration minus */
+#define RTC_CALR_CALM_MASK (0x1ff << RTC_CALR_CALM_SHIFT)
+#define RTC_CALR_CALW16 (1 << 13) /* Bit 13: Use a 16-second calibration cycle period */
+#define RTC_CALR_CALW8 (1 << 14) /* Bit 14: Use an 8-second calibration cycle period */
+#define RTC_CALR_CALP (1 << 15) /* Bit 15: Increase frequency of RTC by 488.5 ppm */
+
+/* RTC tamper configuration register */
+
+#define RTC_TAMPCR_TAMP1E (1 << 0) /* Bit 0: RTC_TAMP1 input detection enable */
+#define RTC_TAMPCR_TAMP1TRG (1 << 1) /* Bit 1: Active level for RTC_TAMP1 input */
+#define RTC_TAMPCR_TAMPIE (1 << 2) /* Bit 2: Tamper interrupt enable */
+#define RTC_TAMPCR_TAMP2E (1 << 3) /* Bit 3: RTC_TAMP2 input detection enable */
+#define RTC_TAMPCR_TAMP2TRG (1 << 4) /* Bit 4: Active level for RTC_TAMP2 input */
+#define RTC_TAMPCR_TAMP3E (1 << 5) /* Bit 5: RTC_TAMP3 detection enable */
+#define RTC_TAMPCR_TAMP3TRG (1 << 6) /* Bit 6: Active level for RTC_TAMP3 input */
+#define RTC_TAMPCR_TAMPTS (1 << 7) /* Bit 7: Activate timestamp on tamper detection event */
+#define RTC_TAMPCR_TAMPFREQ_SHIFT (8) /* Bits 8-10: Tamper sampling frequency */
+#define RTC_TAMPCR_TAMPFREQ_MASK (7 << RTC_TAMPCR_TAMPFREQ_SHIFT)
+# define RTC_TAMPCR_TAMPFREQ_DIV32768 (0 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 32768 (1 Hz) */
+# define RTC_TAMPCR_TAMPFREQ_DIV16384 (1 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 16384 (2 Hz) */
+# define RTC_TAMPCR_TAMPFREQ_DIV8192 (2 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 8192 (4 Hz) */
+# define RTC_TAMPCR_TAMPFREQ_DIV4096 (3 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 4096 (8 Hz) */
+# define RTC_TAMPCR_TAMPFREQ_DIV2048 (4 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 2048 (16 Hz) */
+# define RTC_TAMPCR_TAMPFREQ_DIV1024 (5 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 1024 (32 Hz) */
+# define RTC_TAMPCR_TAMPFREQ_DIV512 (6 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 512 (64 Hz) */
+# define RTC_TAMPCR_TAMPFREQ_DIV256 (7 << RTC_TAMPCR_TAMPFREQ_SHIFT) /* RTCCLK / 256 (128 Hz) */
+#define RTC_TAMPCR_TAMPFLT_SHIFT (11) /* Bits 11-12: RTC_TAMPx filter count */
+#define RTC_TAMPCR_TAMPFLT_MASK (3 << RTC_TAMPCR_TAMPFLT_SHIFT)
+#define RTC_TAMPCR_TAMPPRCH_SHIFT (13) /* Bits 13-14: RTC_TAMPx precharge duration */
+#define RTC_TAMPCR_TAMPPRCH_MASK (3 << RTC_TAMPCR_TAMPPRCH_SHIFT)
+# define RTC_TAMPCR_TAMPPRCH_1CYCLE (0 << RTC_TAMPCR_TAMPPRCH_SHIFT) /* 1 RTCCLK cycle */
+# define RTC_TAMPCR_TAMPPRCH_2CYCLES (1 << RTC_TAMPCR_TAMPPRCH_SHIFT) /* 2 RTCCLK cycles */
+# define RTC_TAMPCR_TAMPPRCH_4CYCLES (2 << RTC_TAMPCR_TAMPPRCH_SHIFT) /* 4 RTCCLK cycles */
+# define RTC_TAMPCR_TAMPPRCH_5CYCLES (3 << RTC_TAMPCR_TAMPPRCH_SHIFT) /* 8 RTCCLK cycles */
+#define RTC_TAMPCR_TAMPPUDIS (1 << 15) /* Bit 15: RTC_TAMPx pull-up disable */
+#define RTC_TAMPCR_TAMP1IE (1 << 16) /* Bit 16: Tamper 1 interrupt enable */
+#define RTC_TAMPCR_TAMP1NOERASE (1 << 17) /* Bit 17: Tamper 1 no erase */
+#define RTC_TAMPCR_TAMP1MF (1 << 18) /* Bit 18: Tamper 1 mask flag */
+#define RTC_TAMPCR_TAMP2IE (1 << 19) /* Bit 19: Tamper 2 interrupt enable */
+#define RTC_TAMPCR_TAMP2NOERASE (1 << 20) /* Bit 20: Tamper 2 no erase */
+#define RTC_TAMPCR_TAMP2MF (1 << 21) /* Bit 21: Tamper 2 mask flag */
+#define RTC_TAMPCR_TAMP3IE (1 << 22) /* Bit 22: Tamper 3 interrupt enable */
+#define RTC_TAMPCR_TAMP3NOERASE (1 << 23) /* Bit 23: Tamper 3 no erase */
+#define RTC_TAMPCR_TAMP3MF (1 << 24) /* Bit 24: Tamper 3 mask flag */
+
+/* RTC alarm A/B sub second register */
+
+#define RTC_ALRMSSR_SS_SHIFT (0) /* Bits 0-14: Sub second value */
+#define RTC_ALRMSSR_SS_MASK (0x7fff << RTC_ALRMSSR_SS_SHIFT)
+#define RTC_ALRMSSR_MASKSS_SHIFT (24) /* Bits 24-27: Mask the most-significant bits starting at this bit */
+#define RTC_ALRMSSR_MASKSS_MASK (0xf << RTC_ALRMSSR_MASKSS_SHIFT)
+
+/* RTC option register */
+
+#define RTC_OR_TSINSEL_SHIFT (1) /* Bits 1-2: TIMESTAMP mapping */
+#define RTC_OR_TSINSEL_MASK (3 << RTC_OR_TSINSEL_SHIFT)
+# define RTC_OR_PC13 (0 << RTC_OR_TSINSEL_SHIFT) /* TIMESTAMP is mapped on PC13*/
+# define RTC_OR_PI8 (1 << RTC_OR_TSINSEL_SHIFT) /* TIMESTAMP is mapped on PI8 */
+# define RTC_OR_PC1 (2 << RTC_OR_TSINSEL_SHIFT) /* TIMESTAMP is mapped on PC1 */
+# define RTC_OR_PC1_1 (3 << RTC_OR_TSINSEL_SHIFT) /* TIMESTAMP is mapped on PC1 */
+#define RTC_OR_RTC_ALARM_TYPE (1 << 3) /* RTC_ALARM on PC13 output type */
+
+
+#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_RTCC_H */
diff --git a/arch/arm/src/stm32f7/chip/stm32_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32_sdmmc.h
new file mode 100644
index 0000000000000000000000000000000000000000..016ddb18fb9eba5cd86a35b1c4829d398354ab29
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32_sdmmc.h
@@ -0,0 +1,54 @@
+/************************************************************************************
+ * arch/arm/src/stm32f7/chip/stm32_sdmmc.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SDMMC_H
+#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SDMMC_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+#include "chip.h"
+
+#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) || \
+ defined(CONFIG_STM32F7_STM32F76XX) || defined(CONFIG_STM32F7_STM32F77XX)
+# include "stm32f74xx77xx_sdmmc.h"
+#else
+# error "Unsupported STM32 F7 part"
+#endif
+
+#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SDMMC_H */
diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_dbgmcu.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_dbgmcu.h
new file mode 100644
index 0000000000000000000000000000000000000000..33842b73410302c3d6bd587c420b79dc0e58313b
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_dbgmcu.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/chip/stm32f74xx75xx_dbgmcu.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XXDBGMCU_H
+#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XXDBGMCU_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register Addresses *******************************************************/
+
+#define STM32_DBGMCU_IDCODE 0xe0042000 /* MCU identifier */
+#define STM32_DBGMCU_CR 0xe0042004 /* MCU debug */
+#define STM32_DBGMCU_APB1_FZ 0xe0042008 /* Debug MCU APB1 freeze register */
+#define STM32_DBGMCU_APB2_FZ 0xe004200c /* Debug MCU APB2 freeze register */
+
+/* Register Bitfield Definitions ********************************************/
+
+/* MCU identifier */
+
+#define DBGMCU_IDCODE_DEVID_SHIFT (0) /* Bits 11-0: Device Identifier */
+#define DBGMCU_IDCODE_DEVID_MASK (0x0fff << DBGMCU_IDCODE_DEVID_SHIFT)
+#define DBGMCU_IDCODE_REVID_SHIFT (16) /* Bits 31-16: Revision Identifier */
+#define DBGMCU_IDCODE_REVID_MASK (0xffff << DBGMCU_IDCODE_REVID_SHIFT)
+
+/* MCU debug */
+
+#define DBGMCU_CR_SLEEP (1 << 0) /* Bit 0: Debug Sleep Mode */
+#define DBGMCU_CR_STOP (1 << 1) /* Bit 1: Debug Stop Mode */
+#define DBGMCU_CR_STANDBY (1 << 2) /* Bit 2: Debug Standby mode */
+#define DBGMCU_CR_TRACEIOEN (1 << 5) /* Bit 5: Trace enabled */
+
+#define DBGMCU_CR_TRACEMODE_SHIFT (6) /* Bits 7-6: Trace mode pin assignement */
+#define DBGMCU_CR_TRACEMODE_MASK (3 << DBGMCU_CR_TRACEMODE_SHIFT)
+#define DBGMCU_CR_ASYNCH (0 << DBGMCU_CR_TRACEMODE_SHIFT) /* Asynchronous Mode */
+#define DBGMCU_CR_SYNCH1 (1 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=1 */
+#define DBGMCU_CR_SYNCH2 (2 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=2 */
+#define DBGMCU_CR_SYNCH4 (3 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=4 */
+
+/* Debug MCU APB1 freeze register */
+
+#define DBGMCU_APB1_TIM2STOP (1 << 0) /* Bit 0: TIM2 stopped when core is halted */
+#define DBGMCU_APB1_TIM3STOP (1 << 1) /* Bit 1: TIM3 stopped when core is halted */
+#define DBGMCU_APB1_TIM4STOP (1 << 2) /* Bit 2: TIM4 stopped when core is halted */
+#define DBGMCU_APB1_TIM5STOP (1 << 3) /* Bit 3: TIM5 stopped when core is halted */
+#define DBGMCU_APB1_TIM6STOP (1 << 4) /* Bit 4: TIM6 stopped when core is halted */
+#define DBGMCU_APB1_TIM7STOP (1 << 5) /* Bit 5: TIM7 stopped when core is halted */
+#define DBGMCU_APB1_TIM12STOP (1 << 6) /* Bit 6: TIM12 stopped when core is halted */
+#define DBGMCU_APB1_TIM13STOP (1 << 7) /* Bit 7: TIM13 stopped when core is halted */
+#define DBGMCU_APB1_TIM14STOP (1 << 8) /* Bit 8: TIM14 stopped when core is halted */
+#define DBGMCU_APB1_LPTIM1STOP (1 << 9) /* Bit 9: LPTIM1 stopped when core is halted */
+#define DBGMCU_APB1_RTCSTOP (1 << 10) /* Bit 10: RTC stopped when Core is halted */
+#define DBGMCU_APB1_WWDGSTOP (1 << 11) /* Bit 11: Window Watchdog stopped when core is halted */
+#define DBGMCU_APB1_IWDGSTOP (1 << 12) /* Bit 12: Independent Watchdog stopped when core is halted */
+#define DBGMCU_APB1_I2C1STOP (1 << 21) /* Bit 21: I2C1 SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_APB1_I2C2STOP (1 << 22) /* Bit 22: I2C2 SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_APB1_I2C3STOP (1 << 23) /* Bit 23: I2C3 SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_APB1_I2C4STOP (1 << 24) /* Bit 24: I2C4 SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_APB1_CAN1STOP (1 << 25) /* Bit 25: CAN1 stopped when core is halted */
+#define DBGMCU_APB1_CAN2STOP (1 << 26) /* Bit 26: CAN2 stopped when core is halted */
+
+/* Debug MCU APB2 freeze register */
+
+#define DBGMCU_APB2_TIM1STOP (1 << 0) /* Bit 0: TIM1 stopped when core is halted */
+#define DBGMCU_APB2_TIM8STOP (1 << 1) /* Bit 1: TIM8 stopped when core is halted */
+#define DBGMCU_APB2_TIM9STOP (1 << 16) /* Bit 16: TIM9 stopped when core is halted */
+#define DBGMCU_APB2_TIM10STOP (1 << 17) /* Bit 17: TIM10 stopped when core is halted */
+#define DBGMCU_APB2_TIM11STOP (1 << 18) /* Bit 18: TIM11 stopped when core is halted */
+
+#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XXDBGMCU_H */
diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h
index b68797d00683ec158816aa976e805924e256bdb5..889cf23192e98ec539b09377de48cd48cbe1bda0 100644
--- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h
+++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h
@@ -49,7 +49,7 @@
* Pre-processor Definitions
************************************************************************************/
-/* STM32F40XXX Address Blocks *******************************************************/
+/* STM32F7XXXX STM32F75XXX Address Blocks *******************************************/
#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */
#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */
diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h
index 881f17dc560a47e47ac32e9dbdcaa8204d8d63b3..70c9a2a5aa7cdd347d72f93dfa4d0621568ccba1 100644
--- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h
+++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h
@@ -574,7 +574,7 @@
# define RCC_PLLI2SCFGR_PLLI2SN(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SN_SHIFT)
#define RCC_PLLI2SCFGR_PLLI2SP_SHIFT (16) /* Bits 16-17: PLLI2S division factor for SPDIFRX clock */
#define RCC_PLLI2SCFGR_PLLI2SP_MASK (3 << RCC_PLLI2SCFGR_PLLI2SP_SHIFT)
-# define RCC_PLLI2SCFGR_PLLI2SP(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT)
+# define RCC_PLLI2SCFGR_PLLI2SP(n) ((((n)>>1)-1) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT)
#define RCC_PLLI2SCFGR_PLLI2SQ_SHIFT (24) /* Bits 24-27: PLLI2S division factor for SAIs clock */
#define RCC_PLLI2SCFGR_PLLI2SQ_MASK (15 << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT)
# define RCC_PLLI2SCFGR_PLLI2SQ(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT)
@@ -589,7 +589,7 @@
# define RCC_PLLSAICFGR_PLLSAIN(n) ((n) << RCC_PLLSAICFGR_PLLSAIN_SHIFT)
#define RCC_PLLSAICFGR_PLLSAIP_SHIFT (16) /* Bits 16-17: PLLSAI division factor for 48MHz clock */
#define RCC_PLLSAICFGR_PLLSAIP_MASK (3 << RCC_PLLSAICFGR_PLLSAIP_SHIFT)
-# define RCC_PLLSAICFGR_PLLSAIP(n) ((n) << RCC_PLLSAICFGR_PLLSAIP_SHIFT)
+# define RCC_PLLSAICFGR_PLLSAIP(n) ((((n)>>1)-1) << RCC_PLLSAICFGR_PLLSAIP_SHIFT)
#define RCC_PLLSAICFGR_PLLSAIQ_SHIFT (24) /* Bits 24-27: PLLSAI division factor for SAI clock */
#define RCC_PLLSAICFGR_PLLSAIQ_MASK (0x0F << RCC_PLLSAICFGR_PLLSAIQ_SHIFT)
# define RCC_PLLSAICFGR_PLLSAIQ(n) ((n) << RCC_PLLSAICFGR_PLLSAIQ_SHIFT)
diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx77xx_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32f74xx77xx_sdmmc.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0d52edc4ef756e39978be194f4b12f409450301
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32f74xx77xx_sdmmc.h
@@ -0,0 +1,224 @@
+ /* arch/arm/src/stm32f7/chip/stm32f74xx77xx_sdmmc.h
+ *
+ * Copyright (C) 2009, 2011-2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX77XX_SDMMC_H
+#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX77XX_SDMMC_H
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Register Offsets *****************************************************************/
+
+#define STM32_SDMMC_POWER_OFFSET 0x0000 /* SDMMC power control register */
+#define STM32_SDMMC_CLKCR_OFFSET 0x0004 /* SDMMC clock control register */
+#define STM32_SDMMC_ARG_OFFSET 0x0008 /* SDMMC argument register */
+#define STM32_SDMMC_CMD_OFFSET 0x000c /* SDMMC command register */
+#define STM32_SDMMC_RESPCMD_OFFSET 0x0010 /* SDMMC command response register */
+#define STM32_SDMMC_RESP_OFFSET(n) (0x0010+4*(n))
+#define STM32_SDMMC_RESP1_OFFSET 0x0014 /* SDMMC response 1 register */
+#define STM32_SDMMC_RESP2_OFFSET 0x0018 /* SDMMC response 2 register */
+#define STM32_SDMMC_RESP3_OFFSET 0x001c /* SDMMC response 3 register */
+#define STM32_SDMMC_RESP4_OFFSET 0x0020 /* SDMMC response 4 register */
+#define STM32_SDMMC_DTIMER_OFFSET 0x0024 /* SDMMC data timer register */
+#define STM32_SDMMC_DLEN_OFFSET 0x0028 /* SDMMC data length register */
+#define STM32_SDMMC_DCTRL_OFFSET 0x002c /* SDMMC data control register */
+#define STM32_SDMMC_DCOUNT_OFFSET 0x0030 /* SDMMC data counter register */
+#define STM32_SDMMC_STA_OFFSET 0x0034 /* SDMMC status register */
+#define STM32_SDMMC_ICR_OFFSET 0x0038 /* SDMMC interrupt clear register */
+#define STM32_SDMMC_MASK_OFFSET 0x003c /* SDMMC mask register */
+#define STM32_SDMMC_FIFOCNT_OFFSET 0x0048 /* SDMMC FIFO counter register */
+#define STM32_SDMMC_FIFO_OFFSET 0x0080 /* SDMMC data FIFO register */
+
+
+/* Register Bitfield Definitions ****************************************************/
+
+#define STM32_SDMMC_POWER_PWRCTRL_SHIFT (0) /* Bits 0-1: Power supply control bits */
+#define STM32_SDMMC_POWER_PWRCTRL_MASK (3 << STM32_SDMMC_POWER_PWRCTRL_SHIFT)
+# define STM32_SDMMC_POWER_PWRCTRL_OFF (0 << STM32_SDMMC_POWER_PWRCTRL_SHIFT) /* 00: Power-off: card clock stopped */
+# define STM32_SDMMC_POWER_PWRCTRL_PWRUP (2 << STM32_SDMMC_POWER_PWRCTRL_SHIFT) /* 10: Reserved power-up */
+# define STM32_SDMMC_POWER_PWRCTRL_ON (3 << STM32_SDMMC_POWER_PWRCTRL_SHIFT) /* 11: Power-on: card is clocked */
+
+#define STM32_SDMMC_POWER_RESET (0) /* Reset value */
+
+#define STM32_SDMMC_CLKCR_CLKDIV_SHIFT (0) /* Bits 7-0: Clock divide factor */
+#define STM32_SDMMC_CLKCR_CLKDIV_MASK (0xff << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#define STM32_SDMMC_CLKCR_CLKEN (1 << 8) /* Bit 8: Clock enable bit */
+#define STM32_SDMMC_CLKCR_PWRSAV (1 << 9) /* Bit 9: Power saving configuration bit */
+#define STM32_SDMMC_CLKCR_BYPASS (1 << 10) /* Bit 10: Clock divider bypass enable bit */
+#define STM32_SDMMC_CLKCR_WIDBUS_SHIFT (11) /* Bits 12-11: Wide bus mode enable bits */
+#define STM32_SDMMC_CLKCR_WIDBUS_MASK (3 << STM32_SDMMC_CLKCR_WIDBUS_SHIFT)
+# define STM32_SDMMC_CLKCR_WIDBUS_D1 (0 << STM32_SDMMC_CLKCR_WIDBUS_SHIFT) /* 00: Default (STM32_SDMMC_D0) */
+# define STM32_SDMMC_CLKCR_WIDBUS_D4 (1 << STM32_SDMMC_CLKCR_WIDBUS_SHIFT) /* 01: 4-wide (STM32_SDMMC_D[3:0]) */
+# define STM32_SDMMC_CLKCR_WIDBUS_D8 (2 << STM32_SDMMC_CLKCR_WIDBUS_SHIFT) /* 10: 8-wide (STM32_SDMMC_D[7:0]) */
+#define STM32_SDMMC_CLKCR_NEGEDGE (1 << 13) /* Bit 13: STM32_SDMMC_CK dephasing selection bit */
+#define STM32_SDMMC_CLKCR_HWFC_EN (1 << 14) /* Bit 14: HW Flow Control enable */
+
+#define STM32_SDMMC_CLKCR_RESET (0) /* Reset value */
+
+#define STM32_SDMMC_ARG_RESET (0) /* Reset value */
+
+#define STM32_SDMMC_CMD_CMDINDEX_SHIFT (0)
+#define STM32_SDMMC_CMD_CMDINDEX_MASK (0x3f << STM32_SDMMC_CMD_CMDINDEX_SHIFT)
+#define STM32_SDMMC_CMD_WAITRESP_SHIFT (6) /* Bits 7-6: Wait for response bits */
+#define STM32_SDMMC_CMD_WAITRESP_MASK (3 << STM32_SDMMC_CMD_WAITRESP_SHIFT)
+# define STM32_SDMMC_CMD_NORESPONSE (0 << STM32_SDMMC_CMD_WAITRESP_SHIFT) /* 00/10: No response */
+# define STM32_SDMMC_CMD_SHORTRESPONSE (1 << STM32_SDMMC_CMD_WAITRESP_SHIFT) /* 01: Short response */
+# define STM32_SDMMC_CMD_LONGRESPONSE (3 << STM32_SDMMC_CMD_WAITRESP_SHIFT) /* 11: Long response */
+#define STM32_SDMMC_CMD_WAITINT (1 << 8) /* Bit 8: CPSM waits for interrupt request */
+#define STM32_SDMMC_CMD_WAITPEND (1 << 9) /* Bit 9: CPSM Waits for ends of data transfer */
+#define STM32_SDMMC_CMD_CPSMEN (1 << 10) /* Bit 10: Command path state machine enable */
+#define STM32_SDMMC_CMD_SUSPEND (1 << 11) /* Bit 11: SD I/O suspend command */
+#define STM32_SDMMC_CMD_ENDCMD (1 << 12) /* Bit 12: Enable CMD completion */
+#define STM32_SDMMC_CMD_NIEN (1 << 13) /* Bit 13: not Interrupt Enable */
+#define STM32_SDMMC_CMD_ATACMD (1 << 14) /* Bit 14: CE-ATA command */
+
+#define STM32_SDMMC_CMD_RESET (0) /* Reset value */
+
+#define STM32_SDMMC_RESPCMD_SHIFT (0)
+#define STM32_SDMMC_RESPCMD_MASK (0x3f << STM32_SDMMC_RESPCMD_SHIFT)
+
+#define STM32_SDMMC_DTIMER_RESET (0) /* Reset value */
+
+#define STM32_SDMMC_DLEN_SHIFT (0)
+#define STM32_SDMMC_DLEN_MASK (0x01ffffff << STM32_SDMMC_DLEN_SHIFT)
+
+#define STM32_SDMMC_DLEN_RESET (0) /* Reset value */
+
+#define STM32_SDMMC_DCTRL_DTEN (1 << 0) /* Bit 0: Data transfer enabled bit */
+#define STM32_SDMMC_DCTRL_DTDIR (1 << 1) /* Bit 1: Data transfer direction */
+#define STM32_SDMMC_DCTRL_DTMODE (1 << 2) /* Bit 2: Data transfer mode */
+#define STM32_SDMMC_DCTRL_DMAEN (1 << 3) /* Bit 3: DMA enable bit */
+#define STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT (4) /* Bits 7-4: Data block size */
+#define STM32_SDMMC_DCTRL_DBLOCKSIZE_MASK (15 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_1BYTE (0 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_2BYTES (1 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_4BYTES (2 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_8BYTES (3 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_16BYTES (4 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_32BYTES (5 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_64BYTES (6 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_128BYTES (7 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_256BYTES (8 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_512BYTES (9 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_1KBYTE (10 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_2KBYTES (11 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_4KBYTES (12 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_8KBYTES (13 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+# define STM32_SDMMC_DCTRL_16KBYTES (14 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT)
+#define STM32_SDMMC_DCTRL_RWSTART (1 << 8) /* Bit 8: Read wait start */
+#define STM32_SDMMC_DCTRL_RWSTOP (1 << 9) /* Bit 9: Read wait stop */
+#define STM32_SDMMC_DCTRL_RWMOD (1 << 10) /* Bit 10: Read wait mode */
+#define STM32_SDMMC_DCTRL_SDIOEN (1 << 11) /* Bit 11: SD I/O enable functions */
+
+#define STM32_SDMMC_DCTRL_RESET (0) /* Reset value */
+
+#define STM32_SDMMC_DCOUNT_SHIFT (0)
+#define STM32_SDMMC_DCOUNT_MASK (0x01ffffff << STM32_SDMMC_DCOUNT_SHIFT)
+
+#define STM32_SDMMC_STA_CCRCFAIL (1 << 0) /* Bit 0: Command response CRC fail */
+#define STM32_SDMMC_STA_DCRCFAIL (1 << 1) /* Bit 1: Data block CRC fail */
+#define STM32_SDMMC_STA_CTIMEOUT (1 << 2) /* Bit 2: Command response timeout */
+#define STM32_SDMMC_STA_DTIMEOUT (1 << 3) /* Bit 3: Data timeout */
+#define STM32_SDMMC_STA_TXUNDERR (1 << 4) /* Bit 4: Transmit FIFO underrun error */
+#define STM32_SDMMC_STA_RXOVERR (1 << 5) /* Bit 5: Received FIFO overrun error */
+#define STM32_SDMMC_STA_CMDREND (1 << 6) /* Bit 6: Command response received */
+#define STM32_SDMMC_STA_CMDSENT (1 << 7) /* Bit 7: Command sent */
+#define STM32_SDMMC_STA_DATAEND (1 << 8) /* Bit 8: Data end */
+#define STM32_SDMMC_STA_STBITERR (1 << 9) /* Bit 9: Start bit not detected */
+#define STM32_SDMMC_STA_DBCKEND (1 << 10) /* Bit 10: Data block sent/received */
+#define STM32_SDMMC_STA_CMDACT (1 << 11) /* Bit 11: Command transfer in progress */
+#define STM32_SDMMC_STA_TXACT (1 << 12) /* Bit 12: Data transmit in progress */
+#define STM32_SDMMC_STA_RXACT (1 << 13) /* Bit 13: Data receive in progress */
+#define STM32_SDMMC_STA_TXFIFOHE (1 << 14) /* Bit 14: Transmit FIFO half empty */
+#define STM32_SDMMC_STA_RXFIFOHF (1 << 15) /* Bit 15: Receive FIFO half full */
+#define STM32_SDMMC_STA_TXFIFOF (1 << 16) /* Bit 16: Transmit FIFO full */
+#define STM32_SDMMC_STA_RXFIFOF (1 << 17) /* Bit 17: Receive FIFO full */
+#define STM32_SDMMC_STA_TXFIFOE (1 << 18) /* Bit 18: Transmit FIFO empty */
+#define STM32_SDMMC_STA_RXFIFOE (1 << 19) /* Bit 19: Receive FIFO empty */
+#define STM32_SDMMC_STA_TXDAVL (1 << 20) /* Bit 20: Data available in transmit FIFO */
+#define STM32_SDMMC_STA_RXDAVL (1 << 21) /* Bit 21: Data available in receive FIFO */
+#define STM32_SDMMC_STA_SDIOIT (1 << 22) /* Bit 22: SDIO interrupt received */
+#define STM32_SDMMC_STA_CEATAEND (1 << 23) /* Bit 23: CMD6 CE-ATA command completion */
+
+#define STM32_SDMMC_ICR_CCRCFAILC (1 << 0) /* Bit 0: CCRCFAIL flag clear bit */
+#define STM32_SDMMC_ICR_DCRCFAILC (1 << 1) /* Bit 1: DCRCFAIL flag clear bit */
+#define STM32_SDMMC_ICR_CTIMEOUTC (1 << 2) /* Bit 2: CTIMEOUT flag clear bit */
+#define STM32_SDMMC_ICR_DTIMEOUTC (1 << 3) /* Bit 3: DTIMEOUT flag clear bit */
+#define STM32_SDMMC_ICR_TXUNDERRC (1 << 4) /* Bit 4: TXUNDERR flag clear bit */
+#define STM32_SDMMC_ICR_RXOVERRC (1 << 5) /* Bit 5: RXOVERR flag clear bit */
+#define STM32_SDMMC_ICR_CMDRENDC (1 << 6) /* Bit 6: CMDREND flag clear bit */
+#define STM32_SDMMC_ICR_CMDSENTC (1 << 7) /* Bit 7: CMDSENT flag clear bit */
+#define STM32_SDMMC_ICR_DATAENDC (1 << 8) /* Bit 8: DATAEND flag clear bit */
+#define STM32_SDMMC_ICR_STBITERRC (1 << 9) /* Bit 9: STBITERR flag clear bit */
+#define STM32_SDMMC_ICR_DBCKENDC (1 << 10) /* Bit 10: DBCKEND flag clear bit */
+#define STM32_SDMMC_ICR_SDIOITC (1 << 22) /* Bit 22: SDIOIT flag clear bit */
+#define STM32_SDMMC_ICR_CEATAENDC (1 << 23) /* Bit 23: CEATAEND flag clear bit */
+
+#define STM32_SDMMC_ICR_RESET 0x00c007ff
+#define STM32_SDMMC_ICR_STATICFLAGS 0x000005ff
+
+#define STM32_SDMMC_MASK_CCRCFAILIE (1 << 0) /* Bit 0: Command CRC fail interrupt enable */
+#define STM32_SDMMC_MASK_DCRCFAILIE (1 << 1) /* Bit 1: Data CRC fail interrupt enable */
+#define STM32_SDMMC_MASK_CTIMEOUTIE (1 << 2) /* Bit 2: Command timeout interrupt enable */
+#define STM32_SDMMC_MASK_DTIMEOUTIE (1 << 3) /* Bit 3: Data timeout interrupt enable */
+#define STM32_SDMMC_MASK_TXUNDERRIE (1 << 4) /* Bit 4: Tx FIFO underrun error interrupt enable */
+#define STM32_SDMMC_MASK_RXOVERRIE (1 << 5) /* Bit 5: Rx FIFO overrun error interrupt enable */
+#define STM32_SDMMC_MASK_CMDRENDIE (1 << 6) /* Bit 6: Command response received interrupt enable */
+#define STM32_SDMMC_MASK_CMDSENTIE (1 << 7) /* Bit 7: Command sent interrupt enable */
+#define STM32_SDMMC_MASK_DATAENDIE (1 << 8) /* Bit 8: Data end interrupt enable */
+#define STM32_SDMMC_MASK_STBITERRIE (1 << 9) /* Bit 9: Start bit error interrupt enable */
+#define STM32_SDMMC_MASK_DBCKENDIE (1 << 10) /* Bit 10: Data block end interrupt enable */
+#define STM32_SDMMC_MASK_CMDACTIE (1 << 11) /* Bit 11: Command acting interrupt enable */
+#define STM32_SDMMC_MASK_TXACTIE (1 << 12) /* Bit 12: Data transmit acting interrupt enable */
+#define STM32_SDMMC_MASK_RXACTIE (1 << 13) /* Bit 13: Data receive acting interrupt enable */
+#define STM32_SDMMC_MASK_TXFIFOHEIE (1 << 14) /* Bit 14: Tx FIFO half empty interrupt enable */
+#define STM32_SDMMC_MASK_RXFIFOHFIE (1 << 15) /* Bit 15: Rx FIFO half full interrupt enable */
+#define STM32_SDMMC_MASK_TXFIFOFIE (1 << 16) /* Bit 16: Tx FIFO full interrupt enable */
+#define STM32_SDMMC_MASK_RXFIFOFIE (1 << 17) /* Bit 17: Rx FIFO full interrupt enable */
+#define STM32_SDMMC_MASK_TXFIFOEIE (1 << 18) /* Bit 18: Tx FIFO empty interrupt enable */
+#define STM32_SDMMC_MASK_RXFIFOEIE (1 << 19) /* Bit 19: Rx FIFO empty interrupt enable */
+#define STM32_SDMMC_MASK_TXDAVLIE (1 << 20) /* Bit 20: Data available in Tx FIFO interrupt enable */
+#define STM32_SDMMC_MASK_RXDAVLIE (1 << 21) /* Bit 21: Data available in Rx FIFO interrupt enable */
+#define STM32_SDMMC_MASK_SDIOITIE (1 << 22) /* Bit 22: SDIO mode interrupt received interrupt enable */
+#define STM32_SDMMC_MASK_CEATAENDIE (1 << 23) /* Bit 23: CE-ATA command completion interrupt enable */
+
+#define STM32_SDMMC_MASK_RESET (0)
+
+#define STM32_SDMMC_FIFOCNT_SHIFT (0)
+#define STM32_SDMMC_FIFOCNT_MASK (0x0ffffff << STM32_SDMMC_FIFOCNT_SHIFT)
+
+#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX77XX_SDMMC_H */
+
diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_dbgmcu.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_dbgmcu.h
new file mode 100644
index 0000000000000000000000000000000000000000..6804dc2574891d0e8233f868dc6a61d2bb51c7f1
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_dbgmcu.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/chip/stm32f76xx77xx_dbgmcu.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32F76XX77XXDBGMCU_H
+#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F76XX77XXDBGMCU_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register Addresses *******************************************************/
+
+#define STM32_DBGMCU_IDCODE 0xe0042000 /* MCU identifier */
+#define STM32_DBGMCU_CR 0xe0042004 /* MCU debug */
+#define STM32_DBGMCU_APB1_FZ 0xe0042008 /* Debug MCU APB1 freeze register */
+#define STM32_DBGMCU_APB2_FZ 0xe004200c /* Debug MCU APB2 freeze register */
+
+/* Register Bitfield Definitions ********************************************/
+
+/* MCU identifier */
+
+#define DBGMCU_IDCODE_DEVID_SHIFT (0) /* Bits 11-0: Device Identifier */
+#define DBGMCU_IDCODE_DEVID_MASK (0x0fff << DBGMCU_IDCODE_DEVID_SHIFT)
+#define DBGMCU_IDCODE_REVID_SHIFT (16) /* Bits 31-16: Revision Identifier */
+#define DBGMCU_IDCODE_REVID_MASK (0xffff << DBGMCU_IDCODE_REVID_SHIFT)
+
+/* MCU debug */
+
+#define DBGMCU_CR_SLEEP (1 << 0) /* Bit 0: Debug Sleep Mode */
+#define DBGMCU_CR_STOP (1 << 1) /* Bit 1: Debug Stop Mode */
+#define DBGMCU_CR_STANDBY (1 << 2) /* Bit 2: Debug Standby mode */
+#define DBGMCU_CR_TRACEIOEN (1 << 5) /* Bit 5: Trace enabled */
+
+#define DBGMCU_CR_TRACEMODE_SHIFT (6) /* Bits 7-6: Trace mode pin assignement */
+#define DBGMCU_CR_TRACEMODE_MASK (3 << DBGMCU_CR_TRACEMODE_SHIFT)
+#define DBGMCU_CR_ASYNCH (0 << DBGMCU_CR_TRACEMODE_SHIFT) /* Asynchronous Mode */
+#define DBGMCU_CR_SYNCH1 (1 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=1 */
+#define DBGMCU_CR_SYNCH2 (2 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=2 */
+#define DBGMCU_CR_SYNCH4 (3 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=4 */
+
+/* Debug MCU APB1 freeze register */
+
+#define DBGMCU_APB1_TIM2STOP (1 << 0) /* Bit 0: TIM2 stopped when core is halted */
+#define DBGMCU_APB1_TIM3STOP (1 << 1) /* Bit 1: TIM3 stopped when core is halted */
+#define DBGMCU_APB1_TIM4STOP (1 << 2) /* Bit 2: TIM4 stopped when core is halted */
+#define DBGMCU_APB1_TIM5STOP (1 << 3) /* Bit 3: TIM5 stopped when core is halted */
+#define DBGMCU_APB1_TIM6STOP (1 << 4) /* Bit 4: TIM6 stopped when core is halted */
+#define DBGMCU_APB1_TIM7STOP (1 << 5) /* Bit 5: TIM7 stopped when core is halted */
+#define DBGMCU_APB1_TIM12STOP (1 << 6) /* Bit 6: TIM12 stopped when core is halted */
+#define DBGMCU_APB1_TIM13STOP (1 << 7) /* Bit 7: TIM13 stopped when core is halted */
+#define DBGMCU_APB1_TIM14STOP (1 << 8) /* Bit 8: TIM14 stopped when core is halted */
+#define DBGMCU_APB1_LPTIM1STOP (1 << 9) /* Bit 9: LPTIM1 stopped when core is halted */
+#define DBGMCU_APB1_RTCSTOP (1 << 10) /* Bit 10: RTC stopped when Core is halted */
+#define DBGMCU_APB1_WWDGSTOP (1 << 11) /* Bit 11: Window Watchdog stopped when core is halted */
+#define DBGMCU_APB1_IWDGSTOP (1 << 12) /* Bit 12: Independent Watchdog stopped when core is halted */
+#define DBGMCU_APB1_CAN3STOP (1 << 13) /* Bit 13: CAN3 stopped when Core is halted */
+#define DBGMCU_APB1_I2C1STOP (1 << 21) /* Bit 21: I2C1 SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_APB1_I2C2STOP (1 << 22) /* Bit 22: I2C2 SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_APB1_I2C3STOP (1 << 23) /* Bit 23: I2C3 SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_APB1_I2C4STOP (1 << 24) /* Bit 24: I2C4 SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_APB1_CAN1STOP (1 << 25) /* Bit 25: CAN1 stopped when core is halted */
+#define DBGMCU_APB1_CAN2STOP (1 << 26) /* Bit 26: CAN2 stopped when core is halted */
+
+/* Debug MCU APB2 freeze register */
+
+#define DBGMCU_APB2_TIM1STOP (1 << 0) /* Bit 0: TIM1 stopped when core is halted */
+#define DBGMCU_APB2_TIM8STOP (1 << 1) /* Bit 1: TIM8 stopped when core is halted */
+#define DBGMCU_APB2_TIM9STOP (1 << 16) /* Bit 16: TIM9 stopped when core is halted */
+#define DBGMCU_APB2_TIM10STOP (1 << 17) /* Bit 17: TIM10 stopped when core is halted */
+#define DBGMCU_APB2_TIM11STOP (1 << 18) /* Bit 18: TIM11 stopped when core is halted */
+
+#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F76XX77XXDBGMCU_H */
diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_memorymap.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_memorymap.h
index fd1a41f36de6567bf23bb05bf27ee5a2cedf01db..81f3512fe6aa1af501df775da1ea7346b046b4b5 100644
--- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_memorymap.h
+++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_memorymap.h
@@ -49,7 +49,7 @@
* Pre-processor Definitions
************************************************************************************/
-/* STM32F40XXX Address Blocks *******************************************************/
+/* STM32F76XXX STM32F77XXX Address Blocks *******************************************/
#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */
#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */
diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h
index 4c60603c95a1d9b55317a36f2a9fbc685f3455b8..b2ded840dfbe9b42d98ae3fb2a09252a87893c8a 100644
--- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h
+++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h
@@ -943,7 +943,7 @@
#define GPIO_SDMMC2_CMD (GPIO_ALT|GPIO_AF11|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN7)
#define GPIO_SDMMC2_D0_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14)
#define GPIO_SDMMC2_D1_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15)
-#define GPIO_SDMMC2_D2_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN)
+#define GPIO_SDMMC2_D2_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3)
#define GPIO_SDMMC2_D3_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4)
#define GPIO_SDMMC2_D0_2 (GPIO_ALT|GPIO_AF11|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN9)
#define GPIO_SDMMC2_D1_2 (GPIO_ALT|GPIO_AF11|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10)
diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h
index a63cc1911a46610233b14a9e06d7689c55caaef1..a1b9ed4e321aa78a42b106e18af5d988a39a1d64 100644
--- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h
+++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h
@@ -595,7 +595,7 @@
# define RCC_PLLI2SCFGR_PLLI2SN(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SN_SHIFT)
#define RCC_PLLI2SCFGR_PLLI2SP_SHIFT (16) /* Bits 16-17: PLLI2S division factor for SPDIFRX clock */
#define RCC_PLLI2SCFGR_PLLI2SP_MASK (3 << RCC_PLLI2SCFGR_PLLI2SP_SHIFT)
-# define RCC_PLLI2SCFGR_PLLI2SP(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT)
+# define RCC_PLLI2SCFGR_PLLI2SP(n) ((((n)>>1)-1) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT)
#define RCC_PLLI2SCFGR_PLLI2SQ_SHIFT (24) /* Bits 24-27: PLLI2S division factor for SAIs clock */
#define RCC_PLLI2SCFGR_PLLI2SQ_MASK (15 << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT)
# define RCC_PLLI2SCFGR_PLLI2SQ(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT)
@@ -610,7 +610,7 @@
# define RCC_PLLSAICFGR_PLLSAIN(n) ((n) << RCC_PLLSAICFGR_PLLSAIN_SHIFT)
#define RCC_PLLSAICFGR_PLLSAIP_SHIFT (16) /* Bits 16-17: PLLSAI division factor for 48MHz clock */
#define RCC_PLLSAICFGR_PLLSAIP_MASK (3 << RCC_PLLSAICFGR_PLLSAIP_SHIFT)
-# define RCC_PLLSAICFGR_PLLSAIP(n) ((n) << RCC_PLLSAICFGR_PLLSAIP_SHIFT)
+# define RCC_PLLSAICFGR_PLLSAIP(n) ((((n)>>1)-1) << RCC_PLLSAICFGR_PLLSAIP_SHIFT)
#define RCC_PLLSAICFGR_PLLSAIQ_SHIFT (24) /* Bits 24-27: PLLSAI division factor for SAI clock */
#define RCC_PLLSAICFGR_PLLSAIQ_MASK (0x0F << RCC_PLLSAICFGR_PLLSAIQ_SHIFT)
# define RCC_PLLSAICFGR_PLLSAIQ(n) ((n) << RCC_PLLSAICFGR_PLLSAIQ_SHIFT)
diff --git a/arch/arm/src/stm32f7/stm32_alarm.h b/arch/arm/src/stm32f7/stm32_alarm.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee0b8b89164b480fcf44e80be348a901522baa85
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_alarm.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * arch/arm/src/include/stm32f7/stm32_alarm.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Authors: Neil hancock - delegated to Gregory Nutt Mar 30, 2016
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_STM32_ALARM_H
+#define __ARCH_ARM_SRC_STM32F7_STM32_ALARM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+
+#ifdef CONFIG_RTC_ALARM
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+typedef CODE void (*alm_callback_t)(FAR void *arg, unsigned int alarmid);
+
+/* These features map to STM32 RTC from stm32F7xx
+ */
+
+enum alm_id_e
+{
+ RTC_ALARMA = 0, /* RTC ALARM A */
+ RTC_ALARMB, /* RTC ALARM B */
+ RTC_ALARM_LAST
+};
+
+/* Structure used to pass parameters to set an alarm */
+
+struct alm_setalarm_s
+{
+ int as_id; /* enum alm_id_e */
+ struct tm as_time; /* Alarm expiration time */
+ alm_callback_t as_cb; /* Callback (if non-NULL) */
+ FAR void *as_arg; /* Argument for callback */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_rtc_setalarm
+ *
+ * Description:
+ * Set an alarm to an absolute time using associated hardware.
+ *
+ * Input Parameters:
+ * alminfo - Information about the alarm configuration.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo);
+
+/****************************************************************************
+ * Name: stm32_rtc_cancelalarm
+ *
+ * Description:
+ * Cancel an alarm.
+ *
+ * Input Parameters:
+ * alarmid - Identifies the alarm to be cancelled
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+int stm32_rtc_cancelalarm(enum alm_id_e alarmid);
+
+#endif /* CONFIG_RTC_ALARM */
+#endif /* __ARCH_ARM_SRC_STM32F7_STM32_ALARM_H */
diff --git a/arch/arm/src/stm32f7/stm32_allocateheap.c b/arch/arm/src/stm32f7/stm32_allocateheap.c
index 541e0654b1fd42c68d1f67139b3334157ab78e88..8b21ad68b762db71e7969c8f92e8429bdb3d6525 100644
--- a/arch/arm/src/stm32f7/stm32_allocateheap.c
+++ b/arch/arm/src/stm32f7/stm32_allocateheap.c
@@ -41,6 +41,7 @@
#include
#include
+#include
#include
#include
diff --git a/arch/arm/src/stm32f7/stm32_bbsram.c b/arch/arm/src/stm32f7/stm32_bbsram.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd653cfe56855ad3d97a57ee7f31dea8a0f513d0
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_bbsram.c
@@ -0,0 +1,886 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_bbsram.c
+ *
+ * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ * David Sidrane
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This will driver create a set of files in the STM32's Battery backed up
+ * SRAM. That can be used to store data retained across power cycles.
+ *
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "stm32_bbsram.h"
+#include "chip.h"
+#include "stm32_pwr.h"
+#include "stm32_rtc.h"
+
+#ifdef CONFIG_STM32F7_BBSRAM
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if !defined(CONFIG_STM32F7_BKPSRAM)
+#error Driver Requires CONFIG_STM32F7_BKPSRAM to be enabled
+#endif
+
+#define MAX_OPENCNT (255) /* Limit of uint8_t */
+
+#ifndef CONFIG_DEBUG_INFO
+# undef CONFIG_BBSRAM_DEBUG
+#endif
+
+#if defined(CONFIG_BBSRAM_DEBUG)
+# define BBSRAM_DEBUG_READ() stm32_bbsram_rd()
+# define BBSRAM_DUMP(p,s) stm32_bbsram_dump(p,s)
+#else
+# define BBSRAM_DEBUG_READ()
+# define BBSRAM_DUMP(p,s)
+#endif
+
+#define BBSRAM_HEADER_SIZE (sizeof(struct bbsramfh_s))
+#define BBSRAM_CRCED_OFFSET (sizeof(((struct bbsramfh_s *)0)->crc))
+#define BBSRAM_CRCED_SIZE(l) (BBSRAM_HEADER_SIZE-(BBSRAM_CRCED_OFFSET)+(l))
+#define BBSRAM_ALIGNMENT (sizeof(((struct bbsramfh_s *)0)->crc))
+#define BBSRAM_ALIGNMENT_MASK (BBSRAM_ALIGNMENT-1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* File Header */
+
+struct bbsramfh_s
+{
+ uint32_t crc; /* CRC calculated over data and this struct
+ * starting at fileno */
+ uint8_t fileno; /* The minor number */
+ uint8_t dirty; /* Data has been written to the file */
+ uint16_t len; /* Total Bytes in this file */
+ struct timespec lastwrite; /* Last write time */
+ uint8_t data[]; /* Data in the file */
+};
+
+struct stm32_bbsram_s
+{
+ sem_t exclsem; /* For atomic accesses to this structure */
+ uint8_t refs; /* Number of references */
+ FAR struct bbsramfh_s *bbf; /* File in bbram */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_bbsram_open(FAR struct file *filep);
+static int stm32_bbsram_close(FAR struct file *filep);
+static off_t stm32_bbsram_seek(FAR struct file *filep, off_t offset,
+ int whence);
+static ssize_t stm32_bbsram_read(FAR struct file *filep, FAR char *buffer,
+ size_t len);
+static ssize_t stm32_bbsram_write(FAR struct file *filep,
+ FAR const char *buffer, size_t len);
+static int stm32_bbsram_ioctl(FAR struct file *filep, int cmd,
+ unsigned long arg);
+#ifndef CONFIG_DISABLE_POLL
+static int stm32_bbsram_poll(FAR struct file *filep, FAR struct pollfd *fds,
+ bool setup);
+#endif
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+static int stm32_bbsram_unlink(FAR struct inode *inode);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if defined(CONFIG_BBSRAM_DEBUG)
+static uint8_t debug[STM32F7_BBSRAM_SIZE];
+#endif
+
+static const struct file_operations stm32_bbsram_fops =
+{
+ .open = stm32_bbsram_open,
+ .close = stm32_bbsram_close,
+ .read = stm32_bbsram_read,
+ .write = stm32_bbsram_write,
+ .seek = stm32_bbsram_seek,
+ .ioctl = stm32_bbsram_ioctl,
+#ifndef CONFIG_DISABLE_POLL
+ .poll = stm32_bbsram_poll,
+#endif
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+ .unlink = stm32_bbsram_unlink,
+#endif
+};
+
+static struct stm32_bbsram_s g_bbsram[CONFIG_STM32F7_BBSRAM_FILES];
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_bbsram_rd
+ ****************************************************************************/
+
+#if defined(CONFIG_BBSRAM_DEBUG)
+static void stm32_bbsram_rd(void)
+{
+ memcpy(&debug, (uint8_t *)STM32_BKPSRAM_BASE, sizeof debug);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_bbsram_rd
+ ****************************************************************************/
+
+#if defined(CONFIG_BBSRAM_DEBUG)
+static void stm32_bbsram_dump(FAR struct bbsramfh_s *bbf, char *op)
+{
+ BBSRAM_DEBUG_READ();
+ _info("%s:\n", op);
+ _info(" File Address:0x%8x\n", bbf);
+ _info(" crc:0x%8x\n", bbf->crc);
+ _info(" fileno:%d\n", (int) bbf->fileno);
+ _info(" dirty:%d\n", (int) bbf->dirty);
+ _info(" length:%d\n", (int) bbf->len);
+ _info(" time:%ld:%ld\n", bbf->lastwrite.tv_sec, bbf->lastwrite.tv_nsec);
+ _info(" data: 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",
+ bbf->data[0], bbf->data[1], bbf->data[2], bbf->data[3], bbf->data[4]);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_bbsram_semgive
+ ****************************************************************************/
+
+static void stm32_bbsram_semgive(FAR struct stm32_bbsram_s *priv)
+{
+ sem_post(&priv->exclsem);
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_semtake
+ *
+ * Description:
+ * Take a semaphore handling any exceptional conditions
+ *
+ * Input Parameters:
+ * priv - A reference to the CAN peripheral state
+ *
+ * Returned Value:
+ * None
+ *
+****************************************************************************/
+
+static void stm32_bbsram_semtake(FAR struct stm32_bbsram_s *priv)
+{
+ int ret;
+
+ /* Wait until we successfully get the semaphore. EINTR is the only
+ * expected 'failure' (meaning that the wait for the semaphore was
+ * interrupted by a signal.
+ */
+
+ do
+ {
+ ret = sem_wait(&priv->exclsem);
+ DEBUGASSERT(ret == 0 || errno == EINTR);
+ }
+ while (ret < 0);
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_ulock
+ *
+ * Description:
+ * Unprotects RTC registers, RTC backup data registers and backup SRAM
+ * against parasitic write access
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void stm32_bbsram_unlock(void)
+{
+ (void)stm32_pwr_enablebkp(true);
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_lock
+ *
+ * Description:
+ * Protects RTC registers, RTC backup data registers and backup SRAM
+ * against parasitic write access
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void stm32_bbsram_lock(void)
+{
+ (void)stm32_pwr_enablebkp(false);
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_crc
+ *
+ * Description:
+ * Calculates the CRC of the block
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static uint32_t stm32_bbsram_crc(FAR struct bbsramfh_s *pf)
+{
+ return crc32((uint8_t *)pf + BBSRAM_CRCED_OFFSET, BBSRAM_CRCED_SIZE(pf->len));
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_open
+ *
+ * Description: Open the device
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_open(FAR struct file *filep)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ /* Increment the reference count */
+
+ stm32_bbsram_semtake(bbr);
+ if (bbr->refs == MAX_OPENCNT)
+ {
+ return -EMFILE;
+ }
+ else
+ {
+ bbr->refs++;
+ }
+
+ stm32_bbsram_semgive(bbr);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_internal_close
+ *
+ * Description:
+ * Close BBSRAM entry; Recalculate the time and crc
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_internal_close(FAR struct bbsramfh_s *bbf)
+{
+ bbf->dirty = 0;
+ (void)clock_gettime(CLOCK_REALTIME, &bbf->lastwrite);
+ bbf->crc = stm32_bbsram_crc(bbf);
+
+ BBSRAM_DUMP(bbf, "close done");
+ return bbf->len;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_close
+ *
+ * Description: close the device
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_close(FAR struct file *filep)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+ int ret = OK;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ stm32_bbsram_semtake(bbr);
+
+ BBSRAM_DUMP(bbr->bbf, "close");
+
+ if (bbr->refs == 0)
+ {
+ ret = -EIO;
+ }
+ else
+ {
+ bbr->refs--;
+
+ if (bbr->refs == 0)
+ {
+ if (bbr->bbf->dirty)
+ {
+ /* Recalculate the time and crc */
+
+ stm32_bbsram_unlock();
+ stm32_bbsram_internal_close(bbr->bbf);
+ stm32_bbsram_lock();
+ }
+ }
+ }
+
+ stm32_bbsram_semgive(bbr);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_seek
+ ****************************************************************************/
+
+static off_t stm32_bbsram_seek(FAR struct file *filep, off_t offset,
+ int whence)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+ off_t newpos;
+ int ret;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ stm32_bbsram_semtake(bbr);
+
+ /* Determine the new, requested file position */
+
+ switch (whence)
+ {
+ case SEEK_CUR:
+ newpos = filep->f_pos + offset;
+ break;
+
+ case SEEK_SET:
+ newpos = offset;
+ break;
+
+ case SEEK_END:
+ newpos = bbr->bbf->len + offset;
+ break;
+
+ default:
+ /* Return EINVAL if the whence argument is invalid */
+
+ stm32_bbsram_semgive(bbr);
+ return -EINVAL;
+ }
+
+ /* Opengroup.org:
+ *
+ * "The lseek() function shall allow the file offset to be set beyond the end
+ * of the existing data in the file. If data is later written at this point,
+ * subsequent reads of data in the gap shall return bytes with the value 0
+ * until data is actually written into the gap."
+ *
+ * We can conform to the first part, but not the second. But return EINVAL if
+ *
+ * "...the resulting file offset would be negative for a regular file, block
+ * special file, or directory."
+ */
+
+ if (newpos >= 0)
+ {
+ filep->f_pos = newpos;
+ ret = newpos;
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
+
+ stm32_bbsram_semgive(bbr);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_read
+ ****************************************************************************/
+
+static ssize_t stm32_bbsram_read(FAR struct file *filep, FAR char *buffer,
+ size_t len)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ stm32_bbsram_semtake(bbr);
+
+ /* Trim len if read would go beyond end of device */
+
+ if ((filep->f_pos + len) > bbr->bbf->len)
+ {
+ len = bbr->bbf->len - filep->f_pos;
+ }
+
+ memcpy(buffer, &bbr->bbf->data[filep->f_pos], len);
+ filep->f_pos += len;
+ stm32_bbsram_semgive(bbr);
+ return len;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_internal_write
+ ****************************************************************************/
+
+static ssize_t stm32_bbsram_internal_write(FAR struct bbsramfh_s *bbf,
+ FAR const char *buffer,
+ off_t offset, size_t len)
+{
+ bbf->dirty = 1;
+ memcpy(&bbf->data[offset], buffer, len);
+ return len;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_write
+ ****************************************************************************/
+
+static ssize_t stm32_bbsram_write(FAR struct file *filep,
+ FAR const char *buffer, size_t len)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+ int ret = -EFBIG;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ /* Forbid writes past the end of the device */
+
+ if (filep->f_pos < bbr->bbf->len)
+ {
+ /* Clamp len to avoid crossing the end of the memory */
+
+ if ((filep->f_pos + len) > bbr->bbf->len)
+ {
+ len = bbr->bbf->len - filep->f_pos;
+ }
+
+ ret = len; /* save number of bytes written */
+
+ stm32_bbsram_semtake(bbr);
+ BBSRAM_DUMP(bbr->bbf, "write");
+ stm32_bbsram_unlock();
+ stm32_bbsram_internal_write(bbr->bbf, buffer, filep->f_pos, len);
+ stm32_bbsram_lock();
+ filep->f_pos += len;
+ BBSRAM_DUMP(bbr->bbf, "write done");
+ stm32_bbsram_semgive(bbr);
+ }
+
+ BBSRAM_DEBUG_READ();
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_poll
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_POLL
+static int stm32_bbsram_poll(FAR struct file *filep, FAR struct pollfd *fds,
+ bool setup)
+{
+ if (setup)
+ {
+ fds->revents |= (fds->events & (POLLIN | POLLOUT));
+ if (fds->revents != 0)
+ {
+ sem_post(fds->sem);
+ }
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_bbsram_ioctl
+ *
+ * Description: Return device geometry
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_ioctl(FAR struct file *filep, int cmd,
+ unsigned long arg)
+{
+ FAR struct inode *inode = filep->f_inode;
+ FAR struct stm32_bbsram_s *bbr;
+ int ret = -ENOTTY;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ if (cmd == STM32F7_BBSRAM_GETDESC_IOCTL)
+ {
+ FAR struct bbsramd_s *bbrr = (FAR struct bbsramd_s *)((uintptr_t)arg);
+
+ stm32_bbsram_semtake(bbr);
+ if (!bbrr)
+ {
+ ret = -EINVAL;
+ }
+ else
+ {
+ bbrr->fileno = bbr->bbf->fileno;
+ bbrr->lastwrite = bbr->bbf->lastwrite;
+ bbrr->len = bbr->bbf->len;
+ bbrr->flags = ((bbr->bbf->crc == stm32_bbsram_crc(bbr->bbf))
+ ? BBSRAM_CRC_VALID : 0);
+ bbrr->flags |= ((bbr->bbf->dirty) ? BBSRAM_DIRTY : 0);
+ ret = OK;
+ }
+
+ stm32_bbsram_semgive(bbr);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_bbsram_unlink
+ *
+ * Description:
+ * This function will remove the remove the file from the file system
+ * it will zero the contents and time stamp. It will leave the fileno
+ * and pointer to the BBSRAM intact.
+ * It should be called called on the the file used for the crash dump
+ * to remove it from visibility in the file system after it is created or
+ * read thus arming it.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+static int stm32_bbsram_unlink(FAR struct inode *inode)
+{
+ FAR struct stm32_bbsram_s *bbr;
+
+ DEBUGASSERT(inode && inode->i_private);
+ bbr = (FAR struct stm32_bbsram_s *)inode->i_private;
+
+ stm32_bbsram_semtake(bbr);
+ stm32_bbsram_unlock();
+ memset(bbr->bbf->data, 0, bbr->bbf->len);
+ bbr->bbf->lastwrite.tv_nsec = 0;
+ bbr->bbf->lastwrite.tv_sec = 0;
+ bbr->bbf->crc = stm32_bbsram_crc(bbr->bbf);
+ stm32_bbsram_lock();
+ bbr->refs = 0;
+ stm32_bbsram_semgive(bbr);
+ sem_destroy(&bbr->exclsem);
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_bbsram_probe
+ *
+ * Description: Based on the number of files defined and their sizes
+ * Initializes the base pointers to the file entries.
+ *
+ ****************************************************************************/
+
+static int stm32_bbsram_probe(int *ent, struct stm32_bbsram_s pdev[])
+{
+ int i;
+ int avail = STM32F7_BBSRAM_SIZE;
+ int alloc;
+ int size;
+ int ret = -EFBIG;
+ struct bbsramfh_s *pf = (struct bbsramfh_s *) STM32_BKPSRAM_BASE;
+
+ for (i = 0; (i < CONFIG_STM32F7_BBSRAM_FILES) && ent[i] && (avail > 0); i++)
+ {
+ /* Validate the actual allocations against what is in the BBSRAM */
+
+ size = ent[i];
+
+ /* Use all that is left */
+
+ if (size == -1)
+ {
+ size = avail - (BBSRAM_HEADER_SIZE + BBSRAM_ALIGNMENT_MASK);
+ }
+
+ /* Add in header size and keep aligned */
+
+ alloc = size + BBSRAM_HEADER_SIZE + BBSRAM_ALIGNMENT_MASK;
+ alloc &= ~(BBSRAM_ALIGNMENT_MASK);
+
+ /* Does it fit? */
+
+ if (alloc <= avail)
+ {
+ ret = i + 1;
+ BBSRAM_DUMP(pf, "probe");
+
+ if (pf->len != size ||
+ pf->fileno != i ||
+ pf->crc != stm32_bbsram_crc(pf))
+ {
+
+ /* Not Valid so wipe the file in BBSRAM */
+
+ memset((uint8_t *)pf, 0, alloc);
+ pf->fileno = i;
+ pf->len = size;
+ pf->crc = stm32_bbsram_crc(pf);
+ BBSRAM_DUMP(pf, "probe reset");
+ }
+
+ pdev[i].bbf = pf;
+ pf = (struct bbsramfh_s *)((uint8_t *)pf + alloc);
+ sem_init(&g_bbsram[i].exclsem, 0, 1);
+ }
+
+ avail -= alloc;
+ }
+
+ BBSRAM_DEBUG_READ();
+ return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: stm32_bbsraminitialize
+ *
+ * Description:
+ * Initialize the Battery Backed up SRAM driver.
+ *
+ * Parameters:
+ * devpath - the path to instantiate the files.
+ * sizes - Pointer to a any array of file sizes to create
+ * the last entry should be 0
+ * A size of -1 will use all the remaining spaces
+ *
+ * If the length of sizes is greater then CONFIG_STM32_BBSRAM_FILES
+ * CONFIG_STM32_BBSRAM_FILES will be returned.
+ *
+ * Returned Value:
+ * Number of files created on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int stm32_bbsraminitialize(char *devpath, int *sizes)
+{
+ int i;
+ int fcnt;
+ char path[32];
+ char devname[32];
+
+ int ret = OK;
+
+ if (devpath == NULL)
+ {
+ return -EINVAL;
+ }
+
+ i = strlen(devpath);
+ if (i == 0 || i > sizeof(path) + 3)
+ {
+ return -EINVAL;
+ }
+
+ memset(g_bbsram, 0, sizeof(g_bbsram));
+
+ /* Clocking for the PWR block must be provided. However, this is done
+ * unconditionally in stm32f7xxxx_rcc.c on power up. This done
+ * unconditionally because the PWR block is also needed to set the
+ * internal voltage regulator for maximum performance.
+ */
+
+ /* Enable backup SRAM clock is done in rcc_enableahb1() when
+ * CONFIG_STM32_BKPSRAM is defined.
+ */
+
+ /* Allow Access */
+
+ stm32_bbsram_unlock();
+
+ /* Enable backup regulator so that the data is retained in Standby and
+ * VBAT modes
+ */
+
+ stm32_pwr_enablebreg(true);
+
+ fcnt = stm32_bbsram_probe(sizes, g_bbsram);
+
+ strncpy(path, devpath, sizeof(path));
+ strcat(path, "%d");
+
+ for (i = 0; i < fcnt && ret >= OK; i++)
+ {
+ snprintf(devname, sizeof(devname), path, i);
+ ret = register_driver(devname, &stm32_bbsram_fops, 0666, &g_bbsram[i]);
+ }
+
+ /* Disallow Access */
+
+ stm32_bbsram_lock();
+ return ret < OK ? ret : fcnt;
+}
+
+/****************************************************************************
+ * Function: stm32_bbsram_savepanic
+ *
+ * Description:
+ * Saves the panic context in a previously allocated BBSRAM file
+ *
+ * Parameters:
+ * fileno - the value returned by the ioctl STM32_BBSRAM_GETDESC_IOCTL
+ * context - Pointer to a any array of bytes to save
+ * length - The length of the data pointed to byt context
+ *
+ * Returned Value:
+ * Length saved or negated errno.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_STM32F7_SAVE_CRASHDUMP)
+int stm32_bbsram_savepanic(int fileno, uint8_t *context, int length)
+{
+ FAR struct bbsramfh_s *bbf;
+ int fill;
+ int ret = -ENOSPC;
+
+ /* On a bad day we could panic while panicking, (and we debug assert)
+ * this is a potential feeble attempt at only writing the first
+ * panic's context to the file
+ */
+
+ static bool once = false;
+
+ if (!once)
+ {
+ once = true;
+
+ DEBUGASSERT(fileno > 0 && fileno < CONFIG_STM32F7_BBSRAM_FILES);
+
+ bbf = g_bbsram[fileno].bbf;
+
+ DEBUGASSERT(bbf);
+
+ /* If the g_bbsram has been nulled out we return ENXIO.
+ *
+ * As once ensures we will keep the first dump. Checking the time for
+ * 0 protects from over writing a previous crash dump that has not
+ * been saved to long term storage and erased. The dreaded reboot
+ * loop.
+ */
+
+ if (!bbf)
+ {
+ ret = -ENXIO;
+ }
+ else if ((bbf->lastwrite.tv_sec == 0 && bbf->lastwrite.tv_nsec == 0))
+ {
+ /* Clamp length if too big */
+
+ if (length > bbf->len)
+ {
+ length = bbf->len;
+ }
+
+ stm32_bbsram_unlock();
+
+ stm32_bbsram_internal_write(bbf, (char *) context, 0, length);
+
+ /* Fill with 0 if data is less then file size */
+
+ fill = (int) bbf->len - length;
+
+ if (fill > 0)
+ {
+ memset(&bbf->data[length], 0, fill);
+ }
+
+ /* Seal the file */
+
+ stm32_bbsram_internal_close(bbf);
+
+ stm32_bbsram_lock();
+ ret = length;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+#endif /* CONFIG_BBSRAM_DRIVER */
diff --git a/arch/arm/src/stm32f7/stm32_bbsram.h b/arch/arm/src/stm32f7/stm32_bbsram.h
new file mode 100644
index 0000000000000000000000000000000000000000..554a0c60df84bb78ec0d2ff569117b9033d9a62f
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_bbsram.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_bbsram.h
+ *
+ * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_STM32_BBSRAM_H
+#define __ARCH_ARM_SRC_STM32F7_STM32_BBSRAM_H
+
+/****************************************************************************
+ * The purpose of this driver is to add battery backup file to the file
+ * system. There can be CONFIG_STM32F7_BBRSRAM_COUNT files defined.
+ * These files are of fixed size up to the maximum of the backing 4K SRAM.
+ *
+ * If CONFIG_SAVE_CRASHDUMP is defined The driver also supports a feature
+ * to save the context of a PANIC in one of these files.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) || \
+ defined(CONFIG_STM32F7_STM32F76XX) || defined(CONFIG_STM32F7_STM32F77XX)
+# define STM32F7_BBSRAM_SIZE 4096
+#else
+# error "No backup SRAM on this STM32 Device"
+#endif
+
+#if !defined(CONFIG_STM32F7_BBSRAM_FILES)
+# define CONFIG_STM32F7_BBSRAM_FILES 4
+#endif
+
+/* REVISIT: What guarantees that STM32F7_BBSRAM_GETDESC_IOCTL has a unique
+ * value among all over _DIOC() values?
+ */
+
+#define STM32F7_BBSRAM_GETDESC_IOCTL _DIOC(0x0010) /* Returns a bbsramd_s */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+enum bbsramdf_e
+{
+ BBSRAM_CRC_VALID = 1, /* The crc is valid */
+ BBSRAM_DIRTY = 2, /* The file was closed */
+};
+
+struct bbsramd_s
+{
+ uint8_t flags; /* The crc is valid and the file was closed */
+ uint8_t fileno; /* The minor number */
+ uint16_t len; /* Total Bytes in this file*/
+ struct timespec lastwrite; /* Last write time */
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+# define EXTERN extern "C"
+extern "C"
+{
+#else
+# define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+/****************************************************************************
+ * Function: stm32_bbsraminitialize
+ *
+ * Description:
+ * Initialize the Battery Backed up SRAM driver.
+ *
+ * Parameters:
+ * devpath - the path to instantiate the files.
+ * sizes - Pointer to a any array of file sizes to create
+ * the last entry should be 0
+ * A size of -1 will use all the remaining spaces
+ *
+ * If the length of sizes is greater then CONFIG_STM32F7_BBSRAM_FILES
+ * CONFIG_STM32F7_BBSRAM_FILES will be returned.
+ *
+ * Returned Value:
+ * Number of files created on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int stm32_bbsraminitialize(char *devpath, int *sizes);
+
+/****************************************************************************
+* Function: stm32_bbsram_savepanic
+*
+* Description:
+* Saves the panic context in a previously allocated BBSRAM file
+*
+* Parameters:
+* fileno - the value returned by the ioctl STM32F7_BBSRAM_GETDESC_IOCTL
+* context - Pointer to a any array of bytes to save
+* length - The length of the data pointed to byt context
+*
+* Returned Value:
+* Length saved or negated errno.
+*
+* Assumptions:
+*
+****************************************************************************/
+
+#if defined(CONFIG_STM32F7_SAVE_CRASHDUMP)
+int stm32_bbsram_savepanic(int fileno, uint8_t *context, int length);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32F7_STM32_BBSRAM_H */
diff --git a/arch/arm/src/stm32f7/stm32_dbgmcu.h b/arch/arm/src/stm32f7/stm32_dbgmcu.h
new file mode 100644
index 0000000000000000000000000000000000000000..0aef4d5f0a0284c023b58a8e6877f5e5db64921c
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_dbgmcu.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_dbgmcu.h
+ *
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_STM32_DBGMCU_H
+#define __ARCH_ARM_SRC_STM32F7_STM32_DBGMCU_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include "chip/stm32_dbgmcu.h"
+
+#endif /* __ARCH_ARM_SRC_STM32F7_STM32_DBGMCU_H */
diff --git a/arch/arm/src/stm32f7/stm32_dma.c b/arch/arm/src/stm32f7/stm32_dma.c
index 7b03377bcccdfc02d705472da1848db21d385088..a695a07adf5b5447a14f237186e25dcf1268aa5a 100644
--- a/arch/arm/src/stm32f7/stm32_dma.c
+++ b/arch/arm/src/stm32f7/stm32_dma.c
@@ -521,9 +521,9 @@ void weak_function up_dmainitialize(void)
* version. Feel free to do that if that is what you need.
*
* Input parameter:
- * dmamap - Identifies the stream/channel resource. For the STM32 F4, this
+ * dmamap - Identifies the stream/channel resource. For the STM32 F7, this
* is a bit-encoded value as provided by the DMAMAP_* definitions
- * in chip/stm32f40xxx_dma.h
+ * in chip/stm32f7xxxxxxx_dma.h
*
* Returned Value:
* Provided that 'dmamap' is valid, this function ALWAYS returns a non-NULL,
@@ -609,7 +609,7 @@ void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
dmainfo("paddr: %08x maddr: %08x ntransfers: %d scr: %08x\n",
paddr, maddr, ntransfers, scr);
-#ifdef CONFIG_STM32_DMACAPABLE
+#ifdef CONFIG_STM32F7_DMACAPABLE
DEBUGASSERT(stm32_dmacapable(maddr, ntransfers, scr));
#endif
@@ -865,7 +865,7 @@ size_t stm32_dmaresidual(DMA_HANDLE handle)
*
****************************************************************************/
-#ifdef CONFIG_STM32_DMACAPABLE
+#ifdef CONFIG_STM32F7_DMACAPABLE
bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr)
{
uint32_t transfer_size, burst_length;
@@ -965,29 +965,35 @@ bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr)
case STM32_FSMC_BANK3:
case STM32_FSMC_BANK4:
case STM32_SRAM_BASE:
+
/* All RAM is supported */
break;
case STM32_CODE_BASE:
- /* Everything except the CCM ram is supported */
- if (maddr >= STM32_CCMRAM_BASE &&
- (maddr - STM32_CCMRAM_BASE) < 65536)
+ /* Everything except the ITCM ram is supported per the manual
+ * The ITCM bus is not accessible on AHBS. So the DMA data transfer
+ * to/from ITCM RAM is not supported.
+ */
+
+ if (maddr >= STM32_INSTRAM_BASE &&
+ (maddr - STM32_INSTRAM_BASE) < 0x3fff)
{
- dmainfo("stm32_dmacapable: transfer targets CCMRAM\n");
+ dmainfo("stm32_dmacapable: transfer targets ITCM RAM\n");
return false;
}
break;
default:
+
/* Everything else is unsupported by DMA */
dmainfo("stm32_dmacapable: transfer targets unknown/unsupported region\n");
return false;
}
- dmainfo("stm32_dmacapable: transfer OK\n");
+ dmainfo("stm32_dmacapable: transfer OK\n");
return true;
}
#endif
diff --git a/arch/arm/src/stm32f7/stm32_dma.h b/arch/arm/src/stm32f7/stm32_dma.h
index f78221c94993234f6e1cc18a4f383db37263b488..b25cb84e7dd34aa481065f2790207e06dddca692 100644
--- a/arch/arm/src/stm32f7/stm32_dma.h
+++ b/arch/arm/src/stm32f7/stm32_dma.h
@@ -62,8 +62,8 @@
* Public Types
************************************************************************************/
-/* DMA_HANDLE provides an opaque are reference that can be used to represent a DMA
- * channel (F1) or a DMA stream (F4).
+/* DMA_HANDLE Provides an opaque are reference that can be used to represent a DMA
+ * a DMA stream.
*/
typedef FAR void *DMA_HANDLE;
@@ -137,10 +137,8 @@ extern "C"
*
* Input parameter:
* chan - Identifies the stream/channel resource
- * For the STM32 F1, this is simply the channel number as provided by
- * the DMACHAN_* definitions in chip/stm32f10xxx_dma.h.
- * For the STM32 F4, this is a bit encoded value as provided by the
- * the DMAMAP_* definitions in chip/stm32f40xxx_dma.h
+ * For the STM32 F7, this is a bit encoded value as provided by the
+ * the DMAMAP_* definitions in chip/stm32f7xxxxxxx_dma.h
*
* Returned Value:
* Provided that 'chan' is valid, this function ALWAYS returns a non-NULL,
@@ -248,7 +246,7 @@ size_t stm32_dmaresidual(DMA_HANDLE handle);
*
****************************************************************************/
-#ifdef CONFIG_STM32_DMACAPABLE
+#ifdef CONFIG_STM32F7_DMACAPABLE
bool stm32_dmacapable(uintptr_t maddr, uint32_t count, uint32_t ccr);
#else
# define stm32_dmacapable(maddr, count, ccr) (true)
diff --git a/arch/arm/src/stm32f7/stm32_dtcm.h b/arch/arm/src/stm32f7/stm32_dtcm.h
index a3e76330e917e10d0c68bf8aacdefc7ee1c0293d..0b52bcf96c2fd64fee52861915b5ac3e2e29f09c 100644
--- a/arch/arm/src/stm32f7/stm32_dtcm.h
+++ b/arch/arm/src/stm32f7/stm32_dtcm.h
@@ -1,8 +1,9 @@
/****************************************************************************
* arch/arm/src/stm32f7/stm32_dtcm.h
*
- * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
+ * David Sidrane
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -52,14 +53,14 @@
#define HAVE_DTCM_HEAP 1
-/* Only the STM32 F2, F3, and F4 have DTCM memory */
+/* The STM32 F7 have DTCM memory */
-#if defined(CONFIG_STM32_STM32F30XX)
-# define DTCM_START 0x10000000
-# define DTCM_END 0x10002000
-#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
-# define DTCM_START 0x10000000
-# define DTCM_END 0x10010000
+#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX)
+# define DTCM_START 0x20000000
+# define DTCM_END 0x20010000
+#elif defined(CONFIG_STM32F7_STM32F76XX) || defined(CONFIG_STM32F7_STM32F77XX)
+# define DTCM_START 0x20000000
+# define DTCM_END 0x20020000
#else
# undef HAVE_DTCM_HEAP
#endif
@@ -68,7 +69,7 @@
* heap.
*/
-#ifndef CONFIG_STM32_DTCMEXCLUDE
+#ifndef CONFIG_STM32F7_DTCMEXCLUDE
# undef HAVE_DTCM_HEAP
#endif
diff --git a/arch/arm/src/stm32f7/stm32_exti_pwr.h b/arch/arm/src/stm32f7/stm32_exti_pwr.h
new file mode 100644
index 0000000000000000000000000000000000000000..b72acd5cc9fcaeeec51b942753151befd7ebeedc
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_exti_pwr.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_exti_pwr.h
+ *
+ * Copyright (C) 2015 Haltian Ltd. All rights reserved.
+ * Authors: Dmitry Nikolaev
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_STM32_EXTI_PWR_H
+#define __ARCH_ARM_SRC_STM32F7_STM32_EXTI_PWR_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_exti_pvd
+ *
+ * Description:
+ * Sets/clears EXTI PVD interrupt.
+ *
+ * Parameters:
+ * - rising/falling edge: enables interrupt on rising/falling edge
+ * - event: generate event when set
+ * - func: when non-NULL, generate interrupt
+ *
+ * Returns:
+ * The previous value of the interrupt handler function pointer. This
+ * value may, for example, be used to restore the previous handler when
+ * multiple handlers are used.
+ *
+ ****************************************************************************/
+
+xcpt_t stm32_exti_pvd(bool risingedge, bool fallingedge, bool event,
+ xcpt_t func);
+
+#endif /* __ARCH_ARM_SRC_STM32F7_STM32_EXTI_PWR_H */
diff --git a/arch/arm/src/stm32f7/stm32_irq.c b/arch/arm/src/stm32f7/stm32_irq.c
index eb7a8e1b868399ee96bd2a03216db11fbc34be50..758f32b14778b41a3317ea5c7b6c11815db4e1ad 100644
--- a/arch/arm/src/stm32f7/stm32_irq.c
+++ b/arch/arm/src/stm32f7/stm32_irq.c
@@ -656,7 +656,7 @@ int up_prioritize_irq(int irq, int priority)
uint32_t regval;
int shift;
- DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < STM32_IRQ_NIRQS &&
+ DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS &&
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
if (irq < STM32_IRQ_FIRST)
diff --git a/arch/arm/src/stm32f7/stm32_lsi.c b/arch/arm/src/stm32f7/stm32_lsi.c
new file mode 100644
index 0000000000000000000000000000000000000000..46e961637277fb452dfdb0c553bf298eca6b0047
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_lsi.c
@@ -0,0 +1,89 @@
+/****************************************************************************
+ * arch/arm/src/stm32f/stm32_lsi.c
+ *
+ * Copyright (C) 2012, 2015-2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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
+
+#include "up_arch.h"
+
+#include "stm32_rcc.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_rcc_enablelsi
+ *
+ * Description:
+ * Enable the Internal Low-Speed (LSI) RC Oscillator.
+ *
+ ****************************************************************************/
+
+void stm32_rcc_enablelsi(void)
+{
+ /* Enable the Internal Low-Speed (LSI) RC Oscillator by setting the LSION
+ * bit the RCC CSR register.
+ */
+
+ modifyreg32(STM32_RCC_CSR, 0, RCC_CSR_LSION);
+
+ /* Wait for the internal RC 40 kHz oscillator to be stable. */
+
+ while ((getreg32(STM32_RCC_CSR) & RCC_CSR_LSIRDY) == 0);
+}
+
+/****************************************************************************
+ * Name: stm32_rcc_disablelsi
+ *
+ * Description:
+ * Disable the Internal Low-Speed (LSI) RC Oscillator.
+ *
+ ****************************************************************************/
+
+void stm32_rcc_disablelsi(void)
+{
+ /* Enable the Internal Low-Speed (LSI) RC Oscillator by setting the LSION
+ * bit the RCC CSR register.
+ */
+
+ modifyreg32(STM32_RCC_CSR, RCC_CSR_LSION, 0);
+
+ /* LSIRDY should go low after 3 LSI clock cycles */
+}
diff --git a/arch/arm/src/stm32f7/stm32_otg.h b/arch/arm/src/stm32f7/stm32_otg.h
new file mode 100644
index 0000000000000000000000000000000000000000..7eba65a61ba4b4b6c0a72cee6d8b50b8d3be108b
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_otg.h
@@ -0,0 +1,148 @@
+/************************************************************************************
+ * arch/arm/src/stm32f7/stm32_otg.h
+ *
+ * Copyright (C) 2012-2013, 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_STM32_OTG_H
+#define __ARCH_ARM_SRC_STM32F7_STM32_OTG_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include
+
+#include "chip.h"
+#include "chip/stm32_otg.h"
+
+#if defined(CONFIG_STM32F7_OTGFS) || defined(CONFIG_STM32F7_OTGHS)
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+/* Configuration ********************************************************************/
+
+#ifndef CONFIG_OTG_PRI
+# define CONFIG_OTG_PRI NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+
+#if defined(CONFIG_STM32F7_OTGFS)
+# define STM32_IRQ_OTG STM32_IRQ_OTGFS
+# define STM32_OTG_BASE STM32_USBOTGFS_BASE
+# define STM32_NENDPOINTS (6) /* ep0-5 x 2 for IN and OUT */
+# define GPIO_OTG_DM GPIO_OTGFS_DM
+# define GPIO_OTG_DP GPIO_OTGFS_DP
+# define GPIO_OTG_ID GPIO_OTGFS_ID
+# define GPIO_OTG_SOF GPIO_OTGFS_SOF
+# define STM32_OTG_FIFO_SIZE 1280
+#endif
+
+#if defined(CONFIG_STM32F7_OTGHS)
+# define STM32_IRQ_OTG STM32_IRQ_OTGHS
+# define STM32_OTG_BASE STM32_USBOTGHS_BASE
+# define STM32_NENDPOINTS (7) /* ep0-8 x 2 for IN and OUT but driver internals use byte to map + one bit for direction */
+# define GPIO_OTG_DM GPIO_OTGHS_DM
+# define GPIO_OTG_DP GPIO_OTGHS_DP
+# define GPIO_OTG_ID GPIO_OTGHS_ID
+# define GPIO_OTG_SOF GPIO_OTGHS_SOF
+# define STM32_OTG_FIFO_SIZE 4096
+#endif
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: stm32_otghost_initialize
+ *
+ * Description:
+ * Initialize USB host device controller hardware.
+ *
+ * Input Parameters:
+ * controller -- If the device supports more than USB host controller, then
+ * this identifies which controller is being initializeed. Normally, this
+ * is just zero.
+ *
+ * Returned Value:
+ * And instance of the USB host interface. The controlling task should
+ * use this interface to (1) call the wait() method to wait for a device
+ * to be connected, and (2) call the enumerate() method to bind the device
+ * to a class driver.
+ *
+ * Assumptions:
+ * - This function should called in the initialization sequence in order
+ * to initialize the USB device functionality.
+ * - Class drivers should be initialized prior to calling this function.
+ * Otherwise, there is a race condition if the device is already connected.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST
+struct usbhost_connection_s;
+FAR struct usbhost_connection_s *stm32_otghost_initialize(int controller);
+#endif
+
+/************************************************************************************
+ * Name: stm32_usbsuspend
+ *
+ * Description:
+ * Board logic must provide the stm32_usbsuspend logic if the OTG FS device driver
+ * is used. This function is called whenever the USB enters or leaves suspend
+ * mode. This is an opportunity for the board logic to shutdown clocks, power,
+ * etc. while the USB is suspended.
+ *
+ ************************************************************************************/
+
+void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_STM32F7_OTGFS */
+#endif /* __ARCH_ARM_SRC_STM32F7_STM32_OTG_H */
diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c
new file mode 100644
index 0000000000000000000000000000000000000000..6a776976e2d4b489654ef58215d5e1aacec8deec
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_otgdev.c
@@ -0,0 +1,5765 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_otgdev.c
+ *
+ * Copyright (C) 2012-2014, 2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "chip.h"
+#include "stm32_gpio.h"
+#include "stm32_otg.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+
+#if defined(CONFIG_USBDEV) && (defined(CONFIG_STM32F7_OTGFS) || \
+ defined(CONFIG_STM32F7_OTGHS))
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_USBDEV_EP0_MAXSIZE
+# define CONFIG_USBDEV_EP0_MAXSIZE 64
+#endif
+
+#ifndef CONFIG_USBDEV_SETUP_MAXDATASIZE
+# define CONFIG_USBDEV_SETUP_MAXDATASIZE CONFIG_USBDEV_EP0_MAXSIZE
+#endif
+
+#ifndef CONFIG_USBDEV_MAXPOWER
+# define CONFIG_USBDEV_MAXPOWER 100 /* mA */
+#endif
+
+/* There is 1.25Kb of FIFO memory. The default partitions this memory
+ * so that there is a TxFIFO allocated for each endpoint and with more
+ * memory provided for the common RxFIFO. A more knowledge-able
+ * configuration would not allocate any TxFIFO space to OUT endpoints.
+ */
+
+#ifndef CONFIG_USBDEV_RXFIFO_SIZE
+# define CONFIG_USBDEV_RXFIFO_SIZE (STM32_OTG_FIFO_SIZE - STM32_OTG_FIFO_SIZE/4/2/STM32_NENDPOINTS*4*STM32_NENDPOINTS)
+#endif
+
+#if STM32_NENDPOINTS > 0
+# ifndef CONFIG_USBDEV_EP0_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP0_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 0
+#endif
+
+#if STM32_NENDPOINTS > 1
+# ifndef CONFIG_USBDEV_EP1_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP1_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP1_TXFIFO_SIZE 0
+#endif
+
+#if STM32_NENDPOINTS > 2
+# ifndef CONFIG_USBDEV_EP2_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP2_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP2_TXFIFO_SIZE 0
+#endif
+
+#if STM32_NENDPOINTS > 3
+# ifndef CONFIG_USBDEV_EP3_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP3_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP3_TXFIFO_SIZE 0
+#endif
+
+#if STM32_NENDPOINTS > 4
+# ifndef CONFIG_USBDEV_EP4_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP4_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP4_TXFIFO_SIZE 0
+#endif
+
+#if STM32_NENDPOINTS > 5
+# ifndef CONFIG_USBDEV_EP5_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP5_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP5_TXFIFO_SIZE 0
+#endif
+
+#if STM32_NENDPOINTS > 6
+# ifndef CONFIG_USBDEV_EP6_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP6_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP6_TXFIFO_SIZE 0
+#endif
+
+#if STM32_NENDPOINTS > 7
+# ifndef CONFIG_USBDEV_EP7_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP7_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP7_TXFIFO_SIZE 0
+#endif
+
+#if STM32_NENDPOINTS > 8
+# ifndef CONFIG_USBDEV_EP8_TXFIFO_SIZE
+# define CONFIG_USBDEV_EP8_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS)
+# endif
+#else
+# define CONFIG_USBDEV_EP8_TXFIFO_SIZE 0
+#endif
+
+/* The actual FIFO addresses that we use must be aligned to 4-byte boundaries;
+ * FIFO sizes must be provided in units of 32-bit words.
+ */
+
+#define STM32_RXFIFO_BYTES ((CONFIG_USBDEV_RXFIFO_SIZE + 3) & ~3)
+#define STM32_RXFIFO_WORDS ((CONFIG_USBDEV_RXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP0_TXFIFO_BYTES ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP0_TXFIFO_WORDS ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP1_TXFIFO_BYTES ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP1_TXFIFO_WORDS ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP2_TXFIFO_BYTES ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP2_TXFIFO_WORDS ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP3_TXFIFO_BYTES ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP3_TXFIFO_WORDS ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP4_TXFIFO_BYTES ((CONFIG_USBDEV_EP4_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP4_TXFIFO_WORDS ((CONFIG_USBDEV_EP4_TXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP5_TXFIFO_BYTES ((CONFIG_USBDEV_EP5_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP5_TXFIFO_WORDS ((CONFIG_USBDEV_EP5_TXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP6_TXFIFO_BYTES ((CONFIG_USBDEV_EP6_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP6_TXFIFO_WORDS ((CONFIG_USBDEV_EP6_TXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP7_TXFIFO_BYTES ((CONFIG_USBDEV_EP7_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP7_TXFIFO_WORDS ((CONFIG_USBDEV_EP7_TXFIFO_SIZE + 3) >> 2)
+
+#define STM32_EP8_TXFIFO_BYTES ((CONFIG_USBDEV_EP8_TXFIFO_SIZE + 3) & ~3)
+#define STM32_EP8_TXFIFO_WORDS ((CONFIG_USBDEV_EP8_TXFIFO_SIZE + 3) >> 2)
+
+
+#if (STM32_RXFIFO_BYTES + \
+ STM32_EP0_TXFIFO_BYTES + STM32_EP1_TXFIFO_BYTES + STM32_EP2_TXFIFO_BYTES + STM32_EP3_TXFIFO_BYTES + \
+ STM32_EP4_TXFIFO_BYTES + STM32_EP5_TXFIFO_BYTES + STM32_EP6_TXFIFO_BYTES + STM32_EP7_TXFIFO_BYTES + CONFIG_USBDEV_EP8_TXFIFO_SIZE \
+ ) > STM32_OTG_FIFO_SIZE
+# error "FIFO allocations exceed FIFO memory size"
+#endif
+
+/* Debug ***********************************************************************/
+/* Trace error codes */
+
+#define STM32_TRACEERR_ALLOCFAIL 0x01
+#define STM32_TRACEERR_BADCLEARFEATURE 0x02
+#define STM32_TRACEERR_BADDEVGETSTATUS 0x03
+#define STM32_TRACEERR_BADEPNO 0x04
+#define STM32_TRACEERR_BADEPGETSTATUS 0x05
+#define STM32_TRACEERR_BADGETCONFIG 0x06
+#define STM32_TRACEERR_BADGETSETDESC 0x07
+#define STM32_TRACEERR_BADGETSTATUS 0x08
+#define STM32_TRACEERR_BADSETADDRESS 0x09
+#define STM32_TRACEERR_BADSETCONFIG 0x0a
+#define STM32_TRACEERR_BADSETFEATURE 0x0b
+#define STM32_TRACEERR_BADTESTMODE 0x0c
+#define STM32_TRACEERR_BINDFAILED 0x0d
+#define STM32_TRACEERR_DISPATCHSTALL 0x0e
+#define STM32_TRACEERR_DRIVER 0x0f
+#define STM32_TRACEERR_DRIVERREGISTERED 0x10
+#define STM32_TRACEERR_EP0NOSETUP 0x11
+#define STM32_TRACEERR_EP0SETUPSTALLED 0x12
+#define STM32_TRACEERR_EPINNULLPACKET 0x13
+#define STM32_TRACEERR_EPINUNEXPECTED 0x14
+#define STM32_TRACEERR_EPOUTNULLPACKET 0x15
+#define STM32_TRACEERR_EPOUTUNEXPECTED 0x16
+#define STM32_TRACEERR_INVALIDCTRLREQ 0x17
+#define STM32_TRACEERR_INVALIDPARMS 0x18
+#define STM32_TRACEERR_IRQREGISTRATION 0x19
+#define STM32_TRACEERR_NOEP 0x1a
+#define STM32_TRACEERR_NOTCONFIGURED 0x1b
+#define STM32_TRACEERR_EPOUTQEMPTY 0x1c
+#define STM32_TRACEERR_EPINREQEMPTY 0x1d
+#define STM32_TRACEERR_NOOUTSETUP 0x1e
+#define STM32_TRACEERR_POLLTIMEOUT 0x1f
+
+/* Trace interrupt codes */
+
+#define STM32_TRACEINTID_USB 1 /* USB Interrupt entry/exit */
+#define STM32_TRACEINTID_INTPENDING 2 /* On each pass through the loop */
+
+#define STM32_TRACEINTID_EPOUT (10 + 0) /* First level interrupt decode */
+#define STM32_TRACEINTID_EPIN (10 + 1)
+#define STM32_TRACEINTID_MISMATCH (10 + 2)
+#define STM32_TRACEINTID_WAKEUP (10 + 3)
+#define STM32_TRACEINTID_SUSPEND (10 + 4)
+#define STM32_TRACEINTID_SOF (10 + 5)
+#define STM32_TRACEINTID_RXFIFO (10 + 6)
+#define STM32_TRACEINTID_DEVRESET (10 + 7)
+#define STM32_TRACEINTID_ENUMDNE (10 + 8)
+#define STM32_TRACEINTID_IISOIXFR (10 + 9)
+#define STM32_TRACEINTID_IISOOXFR (10 + 10)
+#define STM32_TRACEINTID_SRQ (10 + 11)
+#define STM32_TRACEINTID_OTG (10 + 12)
+
+#define STM32_TRACEINTID_EPOUT_XFRC (40 + 0) /* EPOUT second level decode */
+#define STM32_TRACEINTID_EPOUT_EPDISD (40 + 1)
+#define STM32_TRACEINTID_EPOUT_SETUP (40 + 2)
+#define STM32_TRACEINTID_DISPATCH (40 + 3)
+
+#define STM32_TRACEINTID_GETSTATUS (50 + 0) /* EPOUT third level decode */
+#define STM32_TRACEINTID_EPGETSTATUS (50 + 1)
+#define STM32_TRACEINTID_DEVGETSTATUS (50 + 2)
+#define STM32_TRACEINTID_IFGETSTATUS (50 + 3)
+#define STM32_TRACEINTID_CLEARFEATURE (50 + 4)
+#define STM32_TRACEINTID_SETFEATURE (50 + 5)
+#define STM32_TRACEINTID_SETADDRESS (50 + 6)
+#define STM32_TRACEINTID_GETSETDESC (50 + 7)
+#define STM32_TRACEINTID_GETCONFIG (50 + 8)
+#define STM32_TRACEINTID_SETCONFIG (50 + 9)
+#define STM32_TRACEINTID_GETSETIF (50 + 10)
+#define STM32_TRACEINTID_SYNCHFRAME (50 + 11)
+
+#define STM32_TRACEINTID_EPIN_XFRC (70 + 0) /* EPIN second level decode */
+#define STM32_TRACEINTID_EPIN_TOC (70 + 1)
+#define STM32_TRACEINTID_EPIN_ITTXFE (70 + 2)
+#define STM32_TRACEINTID_EPIN_EPDISD (70 + 3)
+#define STM32_TRACEINTID_EPIN_TXFE (70 + 4)
+
+#define STM32_TRACEINTID_EPIN_EMPWAIT (80 + 0) /* EPIN second level decode */
+
+#define STM32_TRACEINTID_OUTNAK (90 + 0) /* RXFLVL second level decode */
+#define STM32_TRACEINTID_OUTRECVD (90 + 1)
+#define STM32_TRACEINTID_OUTDONE (90 + 2)
+#define STM32_TRACEINTID_SETUPDONE (90 + 3)
+#define STM32_TRACEINTID_SETUPRECVD (90 + 4)
+
+/* Endpoints ******************************************************************/
+
+/* Odd physical endpoint numbers are IN; even are OUT */
+
+#define STM32_EPPHYIN2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_IN)
+#define STM32_EPPHYOUT2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_OUT)
+
+/* Endpoint 0 */
+
+#define EP0 (0)
+
+/* The set of all enpoints available to the class implementation (1-3) */
+
+#define STM32_EP_AVAILABLE (0x0e) /* All available endpoints */
+
+/* Maximum packet sizes for full speed endpoints */
+
+#define STM32_MAXPACKET (64) /* Max packet size (1-64) */
+
+/* Delays **********************************************************************/
+
+#define STM32_READY_DELAY 200000
+#define STM32_FLUSH_DELAY 200000
+
+/* Request queue operations ****************************************************/
+
+#define stm32_rqempty(ep) ((ep)->head == NULL)
+#define stm32_rqpeek(ep) ((ep)->head)
+
+/* Standard stuff **************************************************************/
+
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Overall device state */
+
+enum stm32_devstate_e
+{
+ DEVSTATE_DEFAULT = 0, /* Power-up, unconfigured state. This state simply
+ * means that the device is not yet been given an
+ * address.
+ * SET: At initialization, uninitialization,
+ * reset, and whenever the device address
+ * is set to zero
+ * TESTED: Never
+ */
+ DEVSTATE_ADDRESSED, /* Device address has been assigned, not no
+ * configuration has yet been selected.
+ * SET: When either a non-zero device address
+ * is first assigned or when the device
+ * is unconfigured (with configuration == 0)
+ * TESTED: never
+ */
+ DEVSTATE_CONFIGURED, /* Address assigned and configured:
+ * SET: When the device has been addressed and
+ * an non-zero configuration has been selected.
+ * TESTED: In many places to assure that the USB device
+ * has been properly configured by the host.
+ */
+};
+
+/* Endpoint 0 states */
+
+enum stm32_ep0state_e
+{
+ EP0STATE_IDLE = 0, /* Idle State, leave on receiving a SETUP packet or
+ * epsubmit:
+ * SET: In stm32_epin() and stm32_epout() when
+ * we revert from request processing to
+ * SETUP processing.
+ * TESTED: Never
+ */
+ EP0STATE_SETUP_OUT, /* OUT SETUP packet received. Waiting for the DATA
+ * OUT phase of SETUP Packet to complete before
+ * processing a SETUP command (without a USB request):
+ * SET: Set in stm32_rxinterrupt() when SETUP OUT
+ * packet is received.
+ * TESTED: In stm32_ep0out_receive()
+ */
+ EP0STATE_SETUP_READY, /* IN SETUP packet received -OR- OUT SETUP packet and
+ * accompanying data have been received. Processing
+ * of SETUP command will happen soon.
+ * SET: (1) stm32_ep0out_receive() when the OUT
+ * SETUP data phase completes, or (2)
+ * stm32_rxinterrupt() when an IN SETUP is
+ * packet received.
+ * TESTED: Tested in stm32_epout_interrupt() when
+ * SETUP phase is done to see if the SETUP
+ * command is ready to be processed. Also
+ * tested in stm32_ep0out_setup() just to
+ * double-check that we have a SETUP request
+ * and any accompanying data.
+ */
+ EP0STATE_SETUP_PROCESS, /* SETUP Packet is being processed by stm32_ep0out_setup():
+ * SET: When SETUP packet received in EP0 OUT
+ * TESTED: Never
+ */
+ EP0STATE_SETUPRESPONSE, /* Short SETUP response write (without a USB request):
+ * SET: When SETUP response is sent by
+ * stm32_ep0in_setupresponse()
+ * TESTED: Never
+ */
+ EP0STATE_DATA_IN, /* Waiting for data out stage (with a USB request):
+ * SET: In stm32_epin_request() when a write
+ * request is processed on EP0.
+ * TESTED: In stm32_epin() to see if we should
+ * revert to SETUP processing.
+ */
+ EP0STATE_DATA_OUT /* Waiting for data in phase to complete ( with a
+ * USB request)
+ * SET: In stm32_epout_request() when a read
+ * request is processed on EP0.
+ * TESTED: In stm32_epout() to see if we should
+ * revert to SETUP processing
+ */
+};
+
+/* Parsed control request */
+
+struct stm32_ctrlreq_s
+{
+ uint8_t type;
+ uint8_t req;
+ uint16_t value;
+ uint16_t index;
+ uint16_t len;
+};
+
+/* A container for a request so that the request may be retained in a list */
+
+struct stm32_req_s
+{
+ struct usbdev_req_s req; /* Standard USB request */
+ struct stm32_req_s *flink; /* Supports a singly linked list */
+};
+
+/* This is the internal representation of an endpoint */
+
+struct stm32_ep_s
+{
+ /* Common endpoint fields. This must be the first thing defined in the
+ * structure so that it is possible to simply cast from struct usbdev_ep_s
+ * to struct stm32_ep_s.
+ */
+
+ struct usbdev_ep_s ep; /* Standard endpoint structure */
+
+ /* STM32-specific fields */
+
+ struct stm32_usbdev_s *dev; /* Reference to private driver data */
+ struct stm32_req_s *head; /* Request list for this endpoint */
+ struct stm32_req_s *tail;
+ uint8_t epphy; /* Physical EP address */
+ uint8_t eptype:2; /* Endpoint type */
+ uint8_t active:1; /* 1: A request is being processed */
+ uint8_t stalled:1; /* 1: Endpoint is stalled */
+ uint8_t isin:1; /* 1: IN Endpoint */
+ uint8_t odd:1; /* 1: Odd frame */
+ uint8_t zlp:1; /* 1: Transmit a zero-length-packet (IN EPs only) */
+};
+
+/* This structure retains the state of the USB device controller */
+
+struct stm32_usbdev_s
+{
+ /* Common device fields. This must be the first thing defined in the
+ * structure so that it is possible to simply cast from struct usbdev_s
+ * to struct stm32_usbdev_s.
+ */
+
+ struct usbdev_s usbdev;
+
+ /* The bound device class driver */
+
+ struct usbdevclass_driver_s *driver;
+
+ /* STM32-specific fields */
+
+ uint8_t stalled:1; /* 1: Protocol stalled */
+ uint8_t selfpowered:1; /* 1: Device is self powered */
+ uint8_t addressed:1; /* 1: Peripheral address has been set */
+ uint8_t configured:1; /* 1: Class driver has been configured */
+ uint8_t wakeup:1; /* 1: Device remote wake-up */
+ uint8_t dotest:1; /* 1: Test mode selected */
+
+ uint8_t devstate:4; /* See enum stm32_devstate_e */
+ uint8_t ep0state:4; /* See enum stm32_ep0state_e */
+ uint8_t testmode:4; /* Selected test mode */
+ uint8_t epavail[2]; /* Bitset of available OUT/IN endpoints */
+
+ /* E0 SETUP data buffering.
+ *
+ * ctrlreq:
+ * The 8-byte SETUP request is received on the EP0 OUT endpoint and is
+ * saved.
+ *
+ * ep0data
+ * For OUT SETUP requests, the SETUP data phase must also complete before
+ * the SETUP command can be processed. The pack receipt logic will save
+ * the accompanying EP0 IN data in ep0data[] before the SETUP command is
+ * processed.
+ *
+ * For IN SETUP requests, the DATA phase will occur AFTER the SETUP
+ * control request is processed. In that case, ep0data[] may be used as
+ * the response buffer.
+ *
+ * ep0datlen
+ * Length of OUT DATA received in ep0data[] (Not used with OUT data)
+ */
+
+ struct usb_ctrlreq_s ctrlreq;
+ uint8_t ep0data[CONFIG_USBDEV_SETUP_MAXDATASIZE];
+ uint16_t ep0datlen;
+
+ /* The endpoint lists */
+
+ struct stm32_ep_s epin[STM32_NENDPOINTS];
+ struct stm32_ep_s epout[STM32_NENDPOINTS];
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Register operations ******************************************************/
+
+#if defined(CONFIG_STM32F7_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES)
+static uint32_t stm32_getreg(uint32_t addr);
+static void stm32_putreg(uint32_t val, uint32_t addr);
+#else
+# define stm32_getreg(addr) getreg32(addr)
+# define stm32_putreg(val,addr) putreg32(val,addr)
+#endif
+
+/* Request queue operations **************************************************/
+
+static FAR struct stm32_req_s *stm32_req_remfirst(FAR struct stm32_ep_s *privep);
+static bool stm32_req_addlast(FAR struct stm32_ep_s *privep,
+ FAR struct stm32_req_s *req);
+
+/* Low level data transfers and request operations ***************************/
+/* Special endpoint 0 data transfer logic */
+
+static void stm32_ep0in_setupresponse(FAR struct stm32_usbdev_s *priv,
+ FAR uint8_t *data, uint32_t nbytes);
+static inline void stm32_ep0in_transmitzlp(FAR struct stm32_usbdev_s *priv);
+static void stm32_ep0in_activate(void);
+
+static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv);
+
+/* IN request and TxFIFO handling */
+
+static void stm32_txfifo_write(FAR struct stm32_ep_s *privep,
+ FAR uint8_t *buf, int nbytes);
+static void stm32_epin_transfer(FAR struct stm32_ep_s *privep,
+ FAR uint8_t *buf, int nbytes);
+static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep);
+
+/* OUT request and RxFIFO handling */
+
+static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep,
+ FAR uint8_t *dest, uint16_t len);
+static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len);
+static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep);
+static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt);
+static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt);
+static void stm32_epout_request(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep);
+
+/* General request handling */
+
+static void stm32_ep_flush(FAR struct stm32_ep_s *privep);
+static void stm32_req_complete(FAR struct stm32_ep_s *privep,
+ int16_t result);
+static void stm32_req_cancel(FAR struct stm32_ep_s *privep,
+ int16_t status);
+
+/* Interrupt handling ********************************************************/
+
+static struct stm32_ep_s *stm32_ep_findbyaddr(struct stm32_usbdev_s *priv,
+ uint16_t eplog);
+static int stm32_req_dispatch(FAR struct stm32_usbdev_s *priv,
+ FAR const struct usb_ctrlreq_s *ctrl);
+static void stm32_usbreset(FAR struct stm32_usbdev_s *priv);
+
+/* Second level OUT endpoint interrupt processing */
+
+static inline void stm32_ep0out_testmode(FAR struct stm32_usbdev_s *priv,
+ uint16_t index);
+static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv,
+ FAR struct stm32_ctrlreq_s *ctrlreq);
+static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv);
+static inline void stm32_epout(FAR struct stm32_usbdev_s *priv,
+ uint8_t epno);
+static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv);
+
+/* Second level IN endpoint interrupt processing */
+
+static inline void stm32_epin_runtestmode(FAR struct stm32_usbdev_s *priv);
+static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno);
+static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv,
+ int epno);
+static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv);
+
+/* Other second level interrupt processing */
+
+static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv);
+static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv);
+static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv);
+static inline void stm32_enuminterrupt(FAR struct stm32_usbdev_s *priv);
+#ifdef CONFIG_USBDEV_ISOCHRONOUS
+static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv);
+static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv);
+#endif
+#ifdef CONFIG_USBDEV_VBUSSENSING
+static inline void stm32_sessioninterrupt(FAR struct stm32_usbdev_s *priv);
+static inline void stm32_otginterrupt(FAR struct stm32_usbdev_s *priv);
+#endif
+
+/* First level interrupt processing */
+
+static int stm32_usbinterrupt(int irq, FAR void *context);
+
+/* Endpoint operations *********************************************************/
+/* Global OUT NAK controls */
+
+static void stm32_enablegonak(FAR struct stm32_ep_s *privep);
+static void stm32_disablegonak(FAR struct stm32_ep_s *privep);
+
+/* Endpoint configuration */
+
+static int stm32_epout_configure(FAR struct stm32_ep_s *privep,
+ uint8_t eptype, uint16_t maxpacket);
+static int stm32_epin_configure(FAR struct stm32_ep_s *privep,
+ uint8_t eptype, uint16_t maxpacket);
+static int stm32_ep_configure(FAR struct usbdev_ep_s *ep,
+ FAR const struct usb_epdesc_s *desc, bool last);
+static void stm32_ep0_configure(FAR struct stm32_usbdev_s *priv);
+
+/* Endpoint disable */
+
+static void stm32_epout_disable(FAR struct stm32_ep_s *privep);
+static void stm32_epin_disable(FAR struct stm32_ep_s *privep);
+static int stm32_ep_disable(FAR struct usbdev_ep_s *ep);
+
+/* Endpoint request management */
+
+static FAR struct usbdev_req_s *stm32_ep_allocreq(FAR struct usbdev_ep_s *ep);
+static void stm32_ep_freereq(FAR struct usbdev_ep_s *ep,
+ FAR struct usbdev_req_s *);
+
+/* Endpoint buffer management */
+
+#ifdef CONFIG_USBDEV_DMA
+static void *stm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep,
+ unsigned bytes);
+static void stm32_ep_freebuffer(FAR struct usbdev_ep_s *ep,
+ FAR void *buf);
+#endif
+
+/* Endpoint request submission */
+
+static int stm32_ep_submit(FAR struct usbdev_ep_s *ep,
+ struct usbdev_req_s *req);
+
+/* Endpoint request cancellation */
+
+static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep,
+ struct usbdev_req_s *req);
+
+/* Stall handling */
+
+static int stm32_epout_setstall(FAR struct stm32_ep_s *privep);
+static int stm32_epin_setstall(FAR struct stm32_ep_s *privep);
+static int stm32_ep_setstall(FAR struct stm32_ep_s *privep);
+static int stm32_ep_clrstall(FAR struct stm32_ep_s *privep);
+static int stm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume);
+static void stm32_ep0_stall(FAR struct stm32_usbdev_s *priv);
+
+/* Endpoint allocation */
+
+static FAR struct usbdev_ep_s *stm32_ep_alloc(FAR struct usbdev_s *dev,
+ uint8_t epno, bool in, uint8_t eptype);
+static void stm32_ep_free(FAR struct usbdev_s *dev,
+ FAR struct usbdev_ep_s *ep);
+
+/* USB device controller operations ********************************************/
+
+static int stm32_getframe(struct usbdev_s *dev);
+static int stm32_wakeup(struct usbdev_s *dev);
+static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered);
+static int stm32_pullup(struct usbdev_s *dev, bool enable);
+static void stm32_setaddress(struct stm32_usbdev_s *priv,
+ uint16_t address);
+static int stm32_txfifo_flush(uint32_t txfnum);
+static int stm32_rxfifo_flush(void);
+
+/* Initialization **************************************************************/
+
+static void stm32_swinitialize(FAR struct stm32_usbdev_s *priv);
+static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Since there is only a single USB interface, all status information can be
+ * be simply retained in a single global instance.
+ */
+
+static struct stm32_usbdev_s g_otghsdev;
+
+static const struct usbdev_epops_s g_epops =
+{
+ .configure = stm32_ep_configure,
+ .disable = stm32_ep_disable,
+ .allocreq = stm32_ep_allocreq,
+ .freereq = stm32_ep_freereq,
+#ifdef CONFIG_USBDEV_DMA
+ .allocbuffer = stm32_ep_allocbuffer,
+ .freebuffer = stm32_ep_freebuffer,
+#endif
+ .submit = stm32_ep_submit,
+ .cancel = stm32_ep_cancel,
+ .stall = stm32_ep_stall,
+};
+
+static const struct usbdev_ops_s g_devops =
+{
+ .allocep = stm32_ep_alloc,
+ .freeep = stm32_ep_free,
+ .getframe = stm32_getframe,
+ .wakeup = stm32_wakeup,
+ .selfpowered = stm32_selfpowered,
+ .pullup = stm32_pullup,
+};
+
+/* Device error strings that may be enabled for more descriptive USB trace
+ * output.
+ */
+
+#ifdef CONFIG_USBDEV_TRACE_STRINGS
+const struct trace_msg_t g_usb_trace_strings_deverror[] =
+{
+ TRACE_STR(STM32_TRACEERR_ALLOCFAIL ),
+ TRACE_STR(STM32_TRACEERR_BADCLEARFEATURE ),
+ TRACE_STR(STM32_TRACEERR_BADDEVGETSTATUS ),
+ TRACE_STR(STM32_TRACEERR_BADEPNO ),
+ TRACE_STR(STM32_TRACEERR_BADEPGETSTATUS ),
+ TRACE_STR(STM32_TRACEERR_BADGETCONFIG ),
+ TRACE_STR(STM32_TRACEERR_BADGETSETDESC ),
+ TRACE_STR(STM32_TRACEERR_BADGETSTATUS ),
+ TRACE_STR(STM32_TRACEERR_BADSETADDRESS ),
+ TRACE_STR(STM32_TRACEERR_BADSETCONFIG ),
+ TRACE_STR(STM32_TRACEERR_BADSETFEATURE ),
+ TRACE_STR(STM32_TRACEERR_BADTESTMODE ),
+ TRACE_STR(STM32_TRACEERR_BINDFAILED ),
+ TRACE_STR(STM32_TRACEERR_DISPATCHSTALL ),
+ TRACE_STR(STM32_TRACEERR_DRIVER ),
+ TRACE_STR(STM32_TRACEERR_DRIVERREGISTERED),
+ TRACE_STR(STM32_TRACEERR_EP0NOSETUP ),
+ TRACE_STR(STM32_TRACEERR_EP0SETUPSTALLED ),
+ TRACE_STR(STM32_TRACEERR_EPINNULLPACKET ),
+ TRACE_STR(STM32_TRACEERR_EPINUNEXPECTED ),
+ TRACE_STR(STM32_TRACEERR_EPOUTNULLPACKET ),
+ TRACE_STR(STM32_TRACEERR_EPOUTUNEXPECTED ),
+ TRACE_STR(STM32_TRACEERR_INVALIDCTRLREQ ),
+ TRACE_STR(STM32_TRACEERR_INVALIDPARMS ),
+ TRACE_STR(STM32_TRACEERR_IRQREGISTRATION ),
+ TRACE_STR(STM32_TRACEERR_NOEP ),
+ TRACE_STR(STM32_TRACEERR_NOTCONFIGURED ),
+ TRACE_STR(STM32_TRACEERR_EPOUTQEMPTY ),
+ TRACE_STR(STM32_TRACEERR_EPINREQEMPTY ),
+ TRACE_STR(STM32_TRACEERR_NOOUTSETUP ),
+ TRACE_STR(STM32_TRACEERR_POLLTIMEOUT ),
+ TRACE_STR_END
+};
+#endif
+
+/* Interrupt event strings that may be enabled for more descriptive USB trace
+ * output.
+ */
+
+#ifdef CONFIG_USBDEV_TRACE_STRINGS
+const struct trace_msg_t g_usb_trace_strings_intdecode[] =
+{
+ TRACE_STR(STM32_TRACEINTID_USB ),
+ TRACE_STR(STM32_TRACEINTID_INTPENDING ),
+ TRACE_STR(STM32_TRACEINTID_EPOUT ),
+ TRACE_STR(STM32_TRACEINTID_EPIN ),
+ TRACE_STR(STM32_TRACEINTID_MISMATCH ),
+ TRACE_STR(STM32_TRACEINTID_WAKEUP ),
+ TRACE_STR(STM32_TRACEINTID_SUSPEND ),
+ TRACE_STR(STM32_TRACEINTID_SOF ),
+ TRACE_STR(STM32_TRACEINTID_RXFIFO ),
+ TRACE_STR(STM32_TRACEINTID_DEVRESET ),
+ TRACE_STR(STM32_TRACEINTID_ENUMDNE ),
+ TRACE_STR(STM32_TRACEINTID_IISOIXFR ),
+ TRACE_STR(STM32_TRACEINTID_IISOOXFR ),
+ TRACE_STR(STM32_TRACEINTID_SRQ ),
+ TRACE_STR(STM32_TRACEINTID_OTG ),
+ TRACE_STR(STM32_TRACEINTID_EPOUT_XFRC ),
+ TRACE_STR(STM32_TRACEINTID_EPOUT_EPDISD),
+ TRACE_STR(STM32_TRACEINTID_EPOUT_SETUP ),
+ TRACE_STR(STM32_TRACEINTID_DISPATCH ),
+ TRACE_STR(STM32_TRACEINTID_GETSTATUS ),
+ TRACE_STR(STM32_TRACEINTID_EPGETSTATUS ),
+ TRACE_STR(STM32_TRACEINTID_DEVGETSTATUS),
+ TRACE_STR(STM32_TRACEINTID_IFGETSTATUS ),
+ TRACE_STR(STM32_TRACEINTID_CLEARFEATURE),
+ TRACE_STR(STM32_TRACEINTID_SETFEATURE ),
+ TRACE_STR(STM32_TRACEINTID_SETADDRESS ),
+ TRACE_STR(STM32_TRACEINTID_GETSETDESC ),
+ TRACE_STR(STM32_TRACEINTID_GETCONFIG ),
+ TRACE_STR(STM32_TRACEINTID_SETCONFIG ),
+ TRACE_STR(STM32_TRACEINTID_GETSETIF ),
+ TRACE_STR(STM32_TRACEINTID_SYNCHFRAME ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_XFRC ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_TOC ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_ITTXFE ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_EPDISD ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_TXFE ),
+ TRACE_STR(STM32_TRACEINTID_EPIN_EMPWAIT),
+ TRACE_STR(STM32_TRACEINTID_OUTNAK ),
+ TRACE_STR(STM32_TRACEINTID_OUTRECVD ),
+ TRACE_STR(STM32_TRACEINTID_OUTDONE ),
+ TRACE_STR(STM32_TRACEINTID_SETUPDONE ),
+ TRACE_STR(STM32_TRACEINTID_SETUPRECVD ),
+ TRACE_STR_END
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_getreg
+ *
+ * Description:
+ * Get the contents of an STM32 register
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_STM32F7_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES)
+static uint32_t stm32_getreg(uint32_t addr)
+{
+ static uint32_t prevaddr = 0;
+ static uint32_t preval = 0;
+ static uint32_t count = 0;
+
+ /* Read the value from the register */
+
+ uint32_t val = getreg32(addr);
+
+ /* Is this the same value that we read from the same register last time? Are
+ * we polling the register? If so, suppress some of the output.
+ */
+
+ if (addr == prevaddr && val == preval)
+ {
+ if (count == 0xffffffff || ++count > 3)
+ {
+ if (count == 4)
+ {
+ llerr("...\n");
+ }
+
+ return val;
+ }
+ }
+
+ /* No this is a new address or value */
+
+ else
+ {
+ /* Did we print "..." for the previous value? */
+
+ if (count > 3)
+ {
+ /* Yes.. then show how many times the value repeated */
+
+ llerr("[repeats %d more times]\n", count-3);
+ }
+
+ /* Save the new address, value, and count */
+
+ prevaddr = addr;
+ preval = val;
+ count = 1;
+ }
+
+ /* Show the register value read */
+
+ llerr("%08x->%08x\n", addr, val);
+ return val;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_putreg
+ *
+ * Description:
+ * Set the contents of an STM32 register to a value
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_STM32F7_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES)
+static void stm32_putreg(uint32_t val, uint32_t addr)
+{
+ /* Show the register value being written */
+
+ llerr("%08x<-%08x\n", addr, val);
+
+ /* Write the value */
+
+ putreg32(val, addr);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_req_remfirst
+ *
+ * Description:
+ * Remove a request from the head of an endpoint request queue
+ *
+ ****************************************************************************/
+
+static FAR struct stm32_req_s *stm32_req_remfirst(FAR struct stm32_ep_s *privep)
+{
+ FAR struct stm32_req_s *ret = privep->head;
+
+ if (ret)
+ {
+ privep->head = ret->flink;
+ if (!privep->head)
+ {
+ privep->tail = NULL;
+ }
+
+ ret->flink = NULL;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_req_addlast
+ *
+ * Description:
+ * Add a request to the end of an endpoint request queue
+ *
+ ****************************************************************************/
+
+static bool stm32_req_addlast(FAR struct stm32_ep_s *privep,
+ FAR struct stm32_req_s *req)
+{
+ bool is_empty = !privep->head;
+
+ req->flink = NULL;
+ if (is_empty)
+ {
+ privep->head = req;
+ privep->tail = req;
+ }
+ else
+ {
+ privep->tail->flink = req;
+ privep->tail = req;
+ }
+
+ return is_empty;
+}
+
+/****************************************************************************
+ * Name: stm32_ep0in_setupresponse
+ *
+ * Description:
+ * Schedule a short transfer on Endpoint 0 (IN or OUT)
+ *
+ ****************************************************************************/
+
+static void stm32_ep0in_setupresponse(FAR struct stm32_usbdev_s *priv,
+ FAR uint8_t *buf, uint32_t nbytes)
+{
+ stm32_epin_transfer(&priv->epin[EP0], buf, nbytes);
+ priv->ep0state = EP0STATE_SETUPRESPONSE;
+ stm32_ep0out_ctrlsetup(priv);
+}
+
+/****************************************************************************
+ * Name: stm32_ep0in_transmitzlp
+ *
+ * Description:
+ * Send a zero length packet (ZLP) on endpoint 0 IN
+ *
+ ****************************************************************************/
+
+static inline void stm32_ep0in_transmitzlp(FAR struct stm32_usbdev_s *priv)
+{
+ stm32_ep0in_setupresponse(priv, NULL, 0);
+}
+
+/****************************************************************************
+ * Name: stm32_ep0in_activate
+ *
+ * Description:
+ * Activate the endpoint 0 IN endpoint.
+ *
+ ****************************************************************************/
+
+static void stm32_ep0in_activate(void)
+{
+ uint32_t regval;
+
+ /* Set the max packet size of the IN EP. */
+
+ regval = stm32_getreg(STM32_OTG_DIEPCTL(0));
+ regval &= ~OTG_DIEPCTL0_MPSIZ_MASK;
+
+#if CONFIG_USBDEV_EP0_MAXSIZE == 8
+ regval |= OTG_DIEPCTL0_MPSIZ_8;
+#elif CONFIG_USBDEV_EP0_MAXSIZE == 16
+ regval |= OTG_DIEPCTL0_MPSIZ_16;
+#elif CONFIG_USBDEV_EP0_MAXSIZE == 32
+ regval |= OTG_DIEPCTL0_MPSIZ_32;
+#elif CONFIG_USBDEV_EP0_MAXSIZE == 64
+ regval |= OTG_DIEPCTL0_MPSIZ_64;
+#else
+# error "Unsupported value of CONFIG_USBDEV_EP0_MAXSIZE"
+#endif
+
+ stm32_putreg(regval, STM32_OTG_DIEPCTL(0));
+
+ /* Clear global IN NAK */
+
+ regval = stm32_getreg(STM32_OTG_DCTL);
+ regval |= OTG_DCTL_CGINAK;
+ stm32_putreg(regval, STM32_OTG_DCTL);
+}
+
+/****************************************************************************
+ * Name: stm32_ep0out_ctrlsetup
+ *
+ * Description:
+ * Setup to receive a SETUP packet.
+ *
+ ****************************************************************************/
+
+static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv)
+{
+ uint32_t regval;
+
+ /* Setup the hardware to perform the SETUP transfer */
+
+ regval = (USB_SIZEOF_CTRLREQ * 3 << OTG_DOEPTSIZ0_XFRSIZ_SHIFT) |
+ (OTG_DOEPTSIZ0_PKTCNT) |
+ (3 << OTG_DOEPTSIZ0_STUPCNT_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DOEPTSIZ(0));
+
+ /* Then clear NAKing and enable the transfer */
+
+ regval = stm32_getreg(STM32_OTG_DOEPCTL(0));
+ regval |= (OTG_DOEPCTL0_CNAK | OTG_DOEPCTL0_EPENA);
+ stm32_putreg(regval, STM32_OTG_DOEPCTL(0));
+}
+
+/****************************************************************************
+ * Name: stm32_txfifo_write
+ *
+ * Description:
+ * Send data to the endpoint's TxFIFO.
+ *
+ ****************************************************************************/
+
+static void stm32_txfifo_write(FAR struct stm32_ep_s *privep,
+ FAR uint8_t *buf, int nbytes)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ int nwords;
+ int i;
+
+ /* Convert the number of bytes to words */
+
+ nwords = (nbytes + 3) >> 2;
+
+ /* Get the TxFIFO for this endpoint (same as the endpoint number) */
+
+ regaddr = STM32_OTG_DFIFO_DEP(privep->epphy);
+
+ /* Then transfer each word to the TxFIFO */
+
+ for (i = 0; i < nwords; i++)
+ {
+ /* Read four bytes from the source buffer (to avoid unaligned accesses)
+ * and pack these into one 32-bit word (little endian).
+ */
+
+ regval = (uint32_t)*buf++;
+ regval |= ((uint32_t)*buf++) << 8;
+ regval |= ((uint32_t)*buf++) << 16;
+ regval |= ((uint32_t)*buf++) << 24;
+
+ /* Then write the packet data to the TxFIFO */
+
+ stm32_putreg(regval, regaddr);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_epin_transfer
+ *
+ * Description:
+ * Start the Tx data transfer
+ *
+ ****************************************************************************/
+
+static void stm32_epin_transfer(FAR struct stm32_ep_s *privep,
+ FAR uint8_t *buf, int nbytes)
+{
+ uint32_t pktcnt;
+ uint32_t regval;
+
+ /* Read the DIEPSIZx register */
+
+ regval = stm32_getreg(STM32_OTG_DIEPTSIZ(privep->epphy));
+
+ /* Clear the XFRSIZ, PKTCNT, and MCNT field of the DIEPSIZx register */
+
+ regval &= ~(OTG_DIEPTSIZ_XFRSIZ_MASK | OTG_DIEPTSIZ_PKTCNT_MASK |
+ OTG_DIEPTSIZ_MCNT_MASK);
+
+ /* Are we sending a zero length packet (ZLP) */
+
+ if (nbytes == 0)
+ {
+ /* Yes.. leave the transfer size at zero and set the packet count to 1 */
+
+ pktcnt = 1;
+ }
+ else
+ {
+ /* No.. Program the transfer size and packet count . First calculate:
+ *
+ * xfrsize = The total number of bytes to be sent.
+ * pktcnt = the number of packets (of maxpacket bytes) required to
+ * perform the transfer.
+ */
+
+ pktcnt = ((uint32_t)nbytes + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket;
+ }
+
+ /* Set the XFRSIZ and PKTCNT */
+
+ regval |= (pktcnt << OTG_DIEPTSIZ_PKTCNT_SHIFT);
+ regval |= ((uint32_t)nbytes << OTG_DIEPTSIZ_XFRSIZ_SHIFT);
+
+ /* If this is an isochronous endpoint, then set the multi-count field to
+ * the PKTCNT as well.
+ */
+
+ if (privep->eptype == USB_EP_ATTR_XFER_ISOC)
+ {
+ regval |= (pktcnt << OTG_DIEPTSIZ_MCNT_SHIFT);
+ }
+
+ /* Save DIEPSIZx register value */
+
+ stm32_putreg(regval, STM32_OTG_DIEPTSIZ(privep->epphy));
+
+ /* Read the DIEPCTLx register */
+
+ regval = stm32_getreg(STM32_OTG_DIEPCTL(privep->epphy));
+
+ /* If this is an isochronous endpoint, then set the even/odd frame bit
+ * the DIEPCTLx register.
+ */
+
+ if (privep->eptype == USB_EP_ATTR_XFER_ISOC)
+ {
+ /* Check bit 0 of the frame number of the received SOF and set the
+ * even/odd frame to match.
+ */
+
+ uint32_t status = stm32_getreg(STM32_OTG_DSTS);
+ if ((status & OTG_DSTS_SOFFN0) == OTG_DSTS_SOFFN_EVEN)
+ {
+ regval |= OTG_DIEPCTL_SEVNFRM;
+ }
+ else
+ {
+ regval |= OTG_DIEPCTL_SODDFRM;
+ }
+ }
+
+ /* EP enable, IN data in FIFO */
+
+ regval &= ~OTG_DIEPCTL_EPDIS;
+ regval |= (OTG_DIEPCTL_CNAK | OTG_DIEPCTL_EPENA);
+ stm32_putreg(regval, STM32_OTG_DIEPCTL(privep->epphy));
+
+ /* Transfer the data to the TxFIFO. At this point, the caller has already
+ * assured that there is sufficient space in the TxFIFO to hold the transfer
+ * we can just blindly continue.
+ */
+
+ stm32_txfifo_write(privep, buf, nbytes);
+}
+
+/****************************************************************************
+ * Name: stm32_epin_request
+ *
+ * Description:
+ * Begin or continue write request processing.
+ *
+ ****************************************************************************/
+
+static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep)
+{
+ struct stm32_req_s *privreq;
+ uint32_t regaddr;
+ uint32_t regval;
+ uint8_t *buf;
+ int nbytes;
+ int nwords;
+ int bytesleft;
+
+ /* We get here in one of four possible ways. From three interrupting
+ * events:
+ *
+ * 1. From stm32_epin as part of the transfer complete interrupt processing
+ * This interrupt indicates that the last transfer has completed.
+ * 2. As part of the ITTXFE interrupt processing. That interrupt indicates
+ * that an IN token was received when the associated TxFIFO was empty.
+ * 3. From stm32_epin_txfifoempty as part of the TXFE interrupt processing.
+ * The TXFE interrupt is only enabled when the TxFIFO is full and the
+ * software must wait for space to become available in the TxFIFO.
+ *
+ * And this function may be called immediately when the write request is
+ * queue to start up the next transaction.
+ *
+ * 4. From stm32_ep_submit when a new write request is received WHILE the
+ * endpoint is not active (privep->active == false).
+ */
+
+ /* Check the request from the head of the endpoint request queue */
+
+ privreq = stm32_rqpeek(privep);
+ if (!privreq)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINREQEMPTY), privep->epphy);
+
+ /* There is no TX transfer in progress and no new pending TX
+ * requests to send. To stop transmitting any data on a particular
+ * IN endpoint, the application must set the IN NAK bit. To set this
+ * bit, the following field must be programmed.
+ */
+
+ regaddr = STM32_OTG_DIEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval |= OTG_DIEPCTL_SNAK;
+ stm32_putreg(regval, regaddr);
+
+ /* The endpoint is no longer active */
+
+ privep->active = false;
+ return;
+ }
+
+ uinfo("EP%d req=%p: len=%d xfrd=%d zlp=%d\n",
+ privep->epphy, privreq, privreq->req.len,
+ privreq->req.xfrd, privep->zlp);
+
+ /* Check for a special case: If we are just starting a request (xfrd==0) and
+ * the class driver is trying to send a zero-length packet (len==0). Then set
+ * the ZLP flag so that the packet will be sent.
+ */
+
+ if (privreq->req.len == 0)
+ {
+ /* The ZLP flag is set TRUE whenever we want to force the driver to
+ * send a zero-length-packet on the next pass through the loop (below).
+ * The flag is cleared whenever a packet is sent in the loop below.
+ */
+
+ privep->zlp = true;
+ }
+
+ /* Add one more packet to the TxFIFO. We will wait for the transfer
+ * complete event before we add the next packet (or part of a packet
+ * to the TxFIFO).
+ *
+ * The documentation says that we can can multiple packets to the TxFIFO,
+ * but it seems that we need to get the transfer complete event before
+ * we can add the next (or maybe I have got something wrong?)
+ */
+
+#if 0
+ while (privreq->req.xfrd < privreq->req.len || privep->zlp)
+#else
+ if (privreq->req.xfrd < privreq->req.len || privep->zlp)
+#endif
+ {
+ /* Get the number of bytes left to be sent in the request */
+
+ bytesleft = privreq->req.len - privreq->req.xfrd;
+ nbytes = bytesleft;
+
+ /* Assume no zero-length-packet on the next pass through this loop */
+
+ privep->zlp = false;
+
+ /* Limit the size of the transfer to one full packet and handle
+ * zero-length packets (ZLPs).
+ */
+
+ if (nbytes > 0)
+ {
+ /* Either send the maxpacketsize or all of the remaining data in
+ * the request.
+ */
+
+ if (nbytes >= privep->ep.maxpacket)
+ {
+ nbytes = privep->ep.maxpacket;
+
+ /* Handle the case where this packet is exactly the
+ * maxpacketsize. Do we need to send a zero-length packet
+ * in this case?
+ */
+
+ if (bytesleft == privep->ep.maxpacket &&
+ (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0)
+ {
+ /* The ZLP flag is set TRUE whenever we want to force
+ * the driver to send a zero-length-packet on the next
+ * pass through this loop. The flag is cleared (above)
+ * whenever we are committed to sending any packet and
+ * set here when we want to force one more pass through
+ * the loop.
+ */
+
+ privep->zlp = true;
+ }
+ }
+ }
+
+ /* Get the transfer size in 32-bit words */
+
+ nwords = (nbytes + 3) >> 2;
+
+ /* Get the number of 32-bit words available in the TxFIFO. The
+ * DXTFSTS indicates the amount of free space available in the
+ * endpoint TxFIFO. Values are in terms of 32-bit words:
+ *
+ * 0: Endpoint TxFIFO is full
+ * 1: 1 word available
+ * 2: 2 words available
+ * n: n words available
+ */
+
+ regaddr = STM32_OTG_DTXFSTS(privep->epphy);
+
+ /* Check for space in the TxFIFO. If space in the TxFIFO is not
+ * available, then set up an interrupt to resume the transfer when
+ * the TxFIFO is empty.
+ */
+
+ regval = stm32_getreg(regaddr);
+ if ((int)(regval & OTG_DTXFSTS_MASK) < nwords)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EMPWAIT), (uint16_t)regval);
+
+ /* There is insufficient space in the TxFIFO. Wait for a TxFIFO
+ * empty interrupt and try again.
+ */
+
+ uint32_t empmsk = stm32_getreg(STM32_OTG_DIEPEMPMSK);
+ empmsk |= OTG_DIEPEMPMSK(privep->epphy);
+ stm32_putreg(empmsk, STM32_OTG_DIEPEMPMSK);
+
+ /* Terminate the transfer. We will try again when the TxFIFO empty
+ * interrupt is received.
+ */
+
+ return;
+ }
+
+ /* Transfer data to the TxFIFO */
+
+ buf = privreq->req.buf + privreq->req.xfrd;
+ stm32_epin_transfer(privep, buf, nbytes);
+
+ /* If it was not before, the OUT endpoint is now actively transferring
+ * data.
+ */
+
+ privep->active = true;
+
+ /* EP0 is a special case */
+
+ if (privep->epphy == EP0)
+ {
+ priv->ep0state = EP0STATE_DATA_IN;
+ }
+
+ /* Update for the next time through the loop */
+
+ privreq->req.xfrd += nbytes;
+ }
+
+ /* Note that the ZLP, if any, must be sent as a separate transfer. The need
+ * for a ZLP is indicated by privep->zlp. If all of the bytes were sent
+ * (including any final null packet) then we are finished with the transfer
+ */
+
+ if (privreq->req.xfrd >= privreq->req.len && !privep->zlp)
+ {
+ usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
+
+ /* We are finished with the request (although the transfer has not
+ * yet completed).
+ */
+
+ stm32_req_complete(privep, OK);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_rxfifo_read
+ *
+ * Description:
+ * Read packet from the RxFIFO into a read request.
+ *
+ ****************************************************************************/
+
+static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep,
+ FAR uint8_t *dest, uint16_t len)
+{
+ uint32_t regaddr;
+ int i;
+
+ /* Get the address of the RxFIFO. Note: there is only one RxFIFO so
+ * we might as well use the address associated with EP0.
+ */
+
+ regaddr = STM32_OTG_DFIFO_DEP(EP0);
+
+ /* Read 32-bits and write 4 x 8-bits at time (to avoid unaligned accesses) */
+
+ for (i = 0; i < len; i += 4)
+ {
+ union
+ {
+ uint32_t w;
+ uint8_t b[4];
+ } data;
+
+ /* Read 1 x 32-bits of EP0 packet data */
+
+ data.w = stm32_getreg(regaddr);
+
+ /* Write 4 x 8-bits of EP0 packet data */
+
+ *dest++ = data.b[0];
+ *dest++ = data.b[1];
+ *dest++ = data.b[2];
+ *dest++ = data.b[3];
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_rxfifo_discard
+ *
+ * Description:
+ * Discard packet data from the RxFIFO.
+ *
+ ****************************************************************************/
+
+static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len)
+{
+ if (len > 0)
+ {
+ uint32_t regaddr;
+ int i;
+
+ /* Get the address of the RxFIFO Note: there is only one RxFIFO so
+ * we might as well use the address associated with EP0.
+ */
+
+ regaddr = STM32_OTG_DFIFO_DEP(EP0);
+
+ /* Read 32-bits at time */
+
+ for (i = 0; i < len; i += 4)
+ {
+ volatile uint32_t data = stm32_getreg(regaddr);
+ (void)data;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_epout_complete
+ *
+ * Description:
+ * This function is called when an OUT transfer complete interrupt is
+ * received. It completes the read request at the head of the endpoint's
+ * request queue.
+ *
+ ****************************************************************************/
+
+static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep)
+{
+ struct stm32_req_s *privreq;
+
+ /* Since a transfer just completed, there must be a read request at the head of
+ * the endpoint request queue.
+ */
+
+ privreq = stm32_rqpeek(privep);
+ DEBUGASSERT(privreq);
+
+ if (!privreq)
+ {
+ /* An OUT transfer completed, but no packet to receive the data. This
+ * should not happen.
+ */
+
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy);
+ privep->active = false;
+ return;
+ }
+
+ uinfo("EP%d: len=%d xfrd=%d\n",
+ privep->epphy, privreq->req.len, privreq->req.xfrd);
+
+ /* Return the completed read request to the class driver and mark the state
+ * IDLE.
+ */
+
+ usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
+ stm32_req_complete(privep, OK);
+ privep->active = false;
+
+ /* Now set up the next read request (if any) */
+
+ stm32_epout_request(priv, privep);
+}
+
+/****************************************************************************
+ * Name: stm32_ep0out_receive
+ *
+ * Description:
+ * This function is called from the RXFLVL interrupt handler when new incoming
+ * data is available in the endpoint's RxFIFO. This function will simply
+ * copy the incoming data into pending request's data buffer.
+ *
+ ****************************************************************************/
+
+static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt)
+{
+ FAR struct stm32_usbdev_s *priv;
+
+ /* Sanity Checking */
+
+ DEBUGASSERT(privep && privep->ep.priv);
+ priv = (FAR struct stm32_usbdev_s *)privep->ep.priv;
+
+ uinfo("EP0: bcnt=%d\n", bcnt);
+ usbtrace(TRACE_READ(EP0), bcnt);
+
+ /* Verify that an OUT SETUP request as received before this data was
+ * received in the RxFIFO.
+ */
+
+ if (priv->ep0state == EP0STATE_SETUP_OUT)
+ {
+ /* Read the data into our special buffer for SETUP data */
+
+ int readlen = MIN(CONFIG_USBDEV_SETUP_MAXDATASIZE, bcnt);
+ stm32_rxfifo_read(privep, priv->ep0data, readlen);
+
+ /* Do we have to discard any excess bytes? */
+
+ stm32_rxfifo_discard(privep, bcnt - readlen);
+
+ /* Now we can process the setup command */
+
+ privep->active = false;
+ priv->ep0state = EP0STATE_SETUP_READY;
+ priv->ep0datlen = readlen;
+
+ stm32_ep0out_setup(priv);
+ }
+ else
+ {
+ /* This is an error. We don't have any idea what to do with the EP0
+ * data in this case. Just read and discard it so that the RxFIFO
+ * does not become constipated.
+ */
+
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOOUTSETUP), priv->ep0state);
+ stm32_rxfifo_discard(privep, bcnt);
+ privep->active = false;
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_epout_receive
+ *
+ * Description:
+ * This function is called from the RXFLVL interrupt handler when new incoming
+ * data is available in the endpoint's RxFIFO. This function will simply
+ * copy the incoming data into pending request's data buffer.
+ *
+ ****************************************************************************/
+
+static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt)
+{
+ struct stm32_req_s *privreq;
+ uint8_t *dest;
+ int buflen;
+ int readlen;
+
+ /* Get a reference to the request at the head of the endpoint's request
+ * queue.
+ */
+
+ privreq = stm32_rqpeek(privep);
+ if (!privreq)
+ {
+ /* Incoming data is available in the RxFIFO, but there is no read setup
+ * to receive the receive the data. This should not happen for data
+ * endpoints; those endpoints should have been NAKing any OUT data tokens.
+ *
+ * We should get here normally on OUT data phase following an OUT
+ * SETUP command. EP0 data will still receive data in this case and it
+ * should not be NAKing.
+ */
+
+ if (privep->epphy == 0)
+ {
+ stm32_ep0out_receive(privep, bcnt);
+ }
+ else
+ {
+ /* Otherwise, the data is lost. This really should not happen if
+ * NAKing is working as expected.
+ */
+
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy);
+
+ /* Discard the data in the RxFIFO */
+
+ stm32_rxfifo_discard(privep, bcnt);
+ }
+
+ privep->active = false;
+ return;
+ }
+
+ uinfo("EP%d: len=%d xfrd=%d\n", privep->epphy, privreq->req.len, privreq->req.xfrd);
+ usbtrace(TRACE_READ(privep->epphy), bcnt);
+
+ /* Get the number of bytes to transfer from the RxFIFO */
+
+ buflen = privreq->req.len - privreq->req.xfrd;
+ DEBUGASSERT(buflen > 0 && buflen >= bcnt);
+ readlen = MIN(buflen, bcnt);
+
+ /* Get the destination of the data transfer */
+
+ dest = privreq->req.buf + privreq->req.xfrd;
+
+ /* Transfer the data from the RxFIFO to the request's data buffer */
+
+ stm32_rxfifo_read(privep, dest, readlen);
+
+ /* If there were more bytes in the RxFIFO than could be held in the read
+ * request, then we will have to discard those.
+ */
+
+ stm32_rxfifo_discard(privep, bcnt - readlen);
+
+ /* Update the number of bytes transferred */
+
+ privreq->req.xfrd += readlen;
+}
+
+/****************************************************************************
+ * Name: stm32_epout_request
+ *
+ * Description:
+ * This function is called when either (1) new read request is received, or
+ * (2) a pending receive request completes. If there is no read in pending,
+ * then this function will initiate the next OUT (read) operation.
+ *
+ ****************************************************************************/
+
+static void stm32_epout_request(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep)
+{
+ struct stm32_req_s *privreq;
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t xfrsize;
+ uint32_t pktcnt;
+
+ /* Make sure that there is not already a pending request request. If there is,
+ * just return, leaving the newly received request in the request queue.
+ */
+
+ if (!privep->active)
+ {
+ /* Loop until a valid request is found (or the request queue is empty).
+ * The loop is only need to look at the request queue again is an invalid
+ * read request is encountered.
+ */
+
+ for (; ; )
+ {
+ /* Get a reference to the request at the head of the endpoint's request queue */
+
+ privreq = stm32_rqpeek(privep);
+ if (!privreq)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy);
+
+ /* There are no read requests to be setup. Configure the hardware to
+ * NAK any incoming packets. (This should already be the case. I
+ * think that the hardware will automatically NAK after a transfer is
+ * completed until SNAK is cleared).
+ */
+
+ regaddr = STM32_OTG_DOEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval |= OTG_DOEPCTL_SNAK;
+ stm32_putreg(regval, regaddr);
+
+ /* This endpoint is no longer actively transferring */
+
+ privep->active = false;
+ return;
+ }
+
+ uinfo("EP%d: len=%d\n", privep->epphy, privreq->req.len);
+
+ /* Ignore any attempt to receive a zero length packet (this really
+ * should not happen.
+ */
+
+ if (privreq->req.len <= 0)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTNULLPACKET), 0);
+ stm32_req_complete(privep, OK);
+ }
+
+ /* Otherwise, we have a usable read request... break out of the loop */
+
+ else
+ {
+ break;
+ }
+ }
+
+ /* Setup the pending read into the request buffer. First calculate:
+ *
+ * pktcnt = the number of packets (of maxpacket bytes) required to
+ * perform the transfer.
+ * xfrsize = The total number of bytes required (in units of
+ * maxpacket bytes).
+ */
+
+ pktcnt = (privreq->req.len + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket;
+ xfrsize = pktcnt * privep->ep.maxpacket;
+
+ /* Then setup the hardware to perform this transfer */
+
+ regaddr = STM32_OTG_DOEPTSIZ(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval &= ~(OTG_DOEPTSIZ_XFRSIZ_MASK | OTG_DOEPTSIZ_PKTCNT_MASK);
+ regval |= (xfrsize << OTG_DOEPTSIZ_XFRSIZ_SHIFT);
+ regval |= (pktcnt << OTG_DOEPTSIZ_PKTCNT_SHIFT);
+ stm32_putreg(regval, regaddr);
+
+ /* Then enable the transfer */
+
+ regaddr = STM32_OTG_DOEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+
+ /* When an isochronous transfer is enabled the Even/Odd frame bit must
+ * also be set appropriately.
+ */
+
+#ifdef CONFIG_USBDEV_ISOCHRONOUS
+ if (privep->eptype == USB_EP_ATTR_XFER_ISOC)
+ {
+ if (privep->odd)
+ {
+ regval |= OTG_DOEPCTL_SODDFRM;
+ }
+ else
+ {
+ regval |= OTG_DOEPCTL_SEVNFRM;
+ }
+ }
+#endif
+
+ /* Clearing NAKing and enable the transfer. */
+
+ regval |= (OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA);
+ stm32_putreg(regval, regaddr);
+
+ /* A transfer is now active on this endpoint */
+
+ privep->active = true;
+
+ /* EP0 is a special case. We need to know when to switch back to
+ * normal SETUP processing.
+ */
+
+ if (privep->epphy == EP0)
+ {
+ priv->ep0state = EP0STATE_DATA_OUT;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_ep_flush
+ *
+ * Description:
+ * Flush any primed descriptors from this ep
+ *
+ ****************************************************************************/
+
+static void stm32_ep_flush(struct stm32_ep_s *privep)
+{
+ if (privep->isin)
+ {
+ stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_D(privep->epphy));
+ }
+ else
+ {
+ stm32_rxfifo_flush();
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_req_complete
+ *
+ * Description:
+ * Handle termination of the request at the head of the endpoint request queue.
+ *
+ ****************************************************************************/
+
+static void stm32_req_complete(struct stm32_ep_s *privep, int16_t result)
+{
+ FAR struct stm32_req_s *privreq;
+
+ /* Remove the request at the head of the request list */
+
+ privreq = stm32_req_remfirst(privep);
+ DEBUGASSERT(privreq != NULL);
+
+ /* If endpoint 0, temporarily reflect the state of protocol stalled
+ * in the callback.
+ */
+
+ bool stalled = privep->stalled;
+ if (privep->epphy == EP0)
+ {
+ privep->stalled = privep->dev->stalled;
+ }
+
+ /* Save the result in the request structure */
+
+ privreq->req.result = result;
+
+ /* Callback to the request completion handler */
+
+ privreq->req.callback(&privep->ep, &privreq->req);
+
+ /* Restore the stalled indication */
+
+ privep->stalled = stalled;
+}
+
+/****************************************************************************
+ * Name: stm32_req_cancel
+ *
+ * Description:
+ * Cancel all pending requests for an endpoint
+ *
+ ****************************************************************************/
+
+static void stm32_req_cancel(struct stm32_ep_s *privep, int16_t status)
+{
+ if (!stm32_rqempty(privep))
+ {
+ stm32_ep_flush(privep);
+ }
+
+ while (!stm32_rqempty(privep))
+ {
+ usbtrace(TRACE_COMPLETE(privep->epphy),
+ (stm32_rqpeek(privep))->req.xfrd);
+ stm32_req_complete(privep, status);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_ep_findbyaddr
+ *
+ * Description:
+ * Find the physical endpoint structure corresponding to a logic endpoint
+ * address
+ *
+ ****************************************************************************/
+
+static struct stm32_ep_s *stm32_ep_findbyaddr(struct stm32_usbdev_s *priv,
+ uint16_t eplog)
+{
+ struct stm32_ep_s *privep;
+ uint8_t epphy = USB_EPNO(eplog);
+
+ if (epphy >= STM32_NENDPOINTS)
+ {
+ return NULL;
+ }
+
+ /* Is this an IN or an OUT endpoint? */
+
+ if (USB_ISEPIN(eplog))
+ {
+ privep = &priv->epin[epphy];
+ }
+ else
+ {
+ privep = &priv->epout[epphy];
+ }
+
+ /* Return endpoint reference */
+
+ DEBUGASSERT(privep->epphy == epphy);
+ return privep;
+}
+
+/****************************************************************************
+ * Name: stm32_req_dispatch
+ *
+ * Description:
+ * Provide unhandled setup actions to the class driver. This is logically part
+ * of the USB interrupt handler.
+ *
+ ****************************************************************************/
+
+static int stm32_req_dispatch(struct stm32_usbdev_s *priv,
+ const struct usb_ctrlreq_s *ctrl)
+{
+ int ret = -EIO;
+
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DISPATCH), 0);
+ if (priv->driver)
+ {
+ /* Forward to the control request to the class driver implementation */
+
+ ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl,
+ priv->ep0data, priv->ep0datlen);
+ }
+
+ if (ret < 0)
+ {
+ /* Stall on failure */
+
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DISPATCHSTALL), 0);
+ priv->stalled = true;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_usbreset
+ *
+ * Description:
+ * Reset Usb engine
+ *
+ ****************************************************************************/
+
+static void stm32_usbreset(struct stm32_usbdev_s *priv)
+{
+ FAR struct stm32_ep_s *privep;
+ uint32_t regval;
+ int i;
+
+ /* Clear the Remote Wake-up Signaling */
+
+ regval = stm32_getreg(STM32_OTG_DCTL);
+ regval &= ~OTG_DCTL_RWUSIG;
+ stm32_putreg(regval, STM32_OTG_DCTL);
+
+ /* Flush the EP0 Tx FIFO */
+
+ stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_D(EP0));
+
+ /* Tell the class driver that we are disconnected. The class
+ * driver should then accept any new configurations.
+ */
+
+ if (priv->driver)
+ {
+ CLASS_DISCONNECT(priv->driver, &priv->usbdev);
+ }
+
+ /* Mark all endpoints as available */
+
+ priv->epavail[0] = STM32_EP_AVAILABLE;
+ priv->epavail[1] = STM32_EP_AVAILABLE;
+
+ /* Disable all end point interrupts */
+
+ for (i = 0; i < STM32_NENDPOINTS ; i++)
+ {
+ /* Disable endpoint interrupts */
+
+ stm32_putreg(0xff, STM32_OTG_DIEPINT(i));
+ stm32_putreg(0xff, STM32_OTG_DOEPINT(i));
+
+ /* Return write requests to the class implementation */
+
+ privep = &priv->epin[i];
+ stm32_req_cancel(privep, -ESHUTDOWN);
+
+ /* Reset IN endpoint status */
+
+ privep->stalled = false;
+
+ /* Return read requests to the class implementation */
+
+ privep = &priv->epout[i];
+ stm32_req_cancel(privep, -ESHUTDOWN);
+
+ /* Reset endpoint status */
+
+ privep->stalled = false;
+ }
+
+ stm32_putreg(0xffffffff, STM32_OTG_DAINT);
+
+ /* Mask all device endpoint interrupts except EP0 */
+
+ regval = (OTG_DAINT_IEP(EP0) | OTG_DAINT_OEP(EP0));
+ stm32_putreg(regval, STM32_OTG_DAINTMSK);
+
+ /* Unmask OUT interrupts */
+
+ regval = (OTG_DOEPMSK_XFRCM | OTG_DOEPMSK_STUPM | OTG_DOEPMSK_EPDM);
+ stm32_putreg(regval, STM32_OTG_DOEPMSK);
+
+ /* Unmask IN interrupts */
+
+ regval = (OTG_DIEPMSK_XFRCM | OTG_DIEPMSK_EPDM | OTG_DIEPMSK_TOM);
+ stm32_putreg(regval, STM32_OTG_DIEPMSK);
+
+ /* Reset device address to 0 */
+
+ stm32_setaddress(priv, 0);
+ priv->devstate = DEVSTATE_DEFAULT;
+ priv->usbdev.speed = USB_SPEED_FULL;
+
+ /* Re-configure EP0 */
+
+ stm32_ep0_configure(priv);
+
+ /* Setup EP0 to receive SETUP packets */
+
+ stm32_ep0out_ctrlsetup(priv);
+}
+
+/****************************************************************************
+ * Name: stm32_ep0out_testmode
+ *
+ * Description:
+ * Select test mode
+ *
+ ****************************************************************************/
+
+static inline void stm32_ep0out_testmode(FAR struct stm32_usbdev_s *priv,
+ uint16_t index)
+{
+ uint8_t testmode;
+
+ testmode = index >> 8;
+ switch (testmode)
+ {
+ case 1:
+ priv->testmode = OTG_TESTMODE_J;
+ break;
+
+ case 2:
+ priv->testmode = OTG_TESTMODE_K;
+ break;
+
+ case 3:
+ priv->testmode = OTG_TESTMODE_SE0_NAK;
+ break;
+
+ case 4:
+ priv->testmode = OTG_TESTMODE_PACKET;
+ break;
+
+ case 5:
+ priv->testmode = OTG_TESTMODE_FORCE;
+ break;
+
+ default:
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode);
+ priv->dotest = false;
+ priv->testmode = OTG_TESTMODE_DISABLED;
+ priv->stalled = true;
+ }
+
+ priv->dotest = true;
+ stm32_ep0in_transmitzlp(priv);
+}
+
+/****************************************************************************
+ * Name: stm32_ep0out_stdrequest
+ *
+ * Description:
+ * Handle a stanard request on EP0. Pick off the things of interest to the
+ * USB device controller driver; pass what is left to the class driver.
+ *
+ ****************************************************************************/
+
+static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv,
+ FAR struct stm32_ctrlreq_s *ctrlreq)
+{
+ FAR struct stm32_ep_s *privep;
+
+ /* Handle standard request */
+
+ switch (ctrlreq->req)
+ {
+ case USB_REQ_GETSTATUS:
+ {
+ /* type: device-to-host; recipient = device, interface, endpoint
+ * value: 0
+ * index: zero interface endpoint
+ * len: 2; data = status
+ */
+
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0);
+ if (!priv->addressed ||
+ ctrlreq->len != 2 ||
+ USB_REQ_ISOUT(ctrlreq->type) ||
+ ctrlreq->value != 0)
+ {
+ priv->stalled = true;
+ }
+ else
+ {
+ switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK)
+ {
+ case USB_REQ_RECIPIENT_ENDPOINT:
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0);
+ privep = stm32_ep_findbyaddr(priv, ctrlreq->index);
+ if (!privep)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), 0);
+ priv->stalled = true;
+ }
+ else
+ {
+ if (privep->stalled)
+ {
+ priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT);
+ }
+ else
+ {
+ priv->ep0data[0] = 0; /* Not stalled */
+ }
+
+ priv->ep0data[1] = 0;
+ stm32_ep0in_setupresponse(priv, priv->ep0data, 2);
+ }
+ }
+ break;
+
+ case USB_REQ_RECIPIENT_DEVICE:
+ {
+ if (ctrlreq->index == 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), 0);
+
+ /* Features: Remote Wakeup and self-powered */
+
+ priv->ep0data[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED);
+ priv->ep0data[0] |= (priv->wakeup << USB_FEATURE_REMOTEWAKEUP);
+ priv->ep0data[1] = 0;
+
+ stm32_ep0in_setupresponse(priv, priv->ep0data, 2);
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), 0);
+ priv->stalled = true;
+ }
+ }
+ break;
+
+ case USB_REQ_RECIPIENT_INTERFACE:
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0);
+ priv->ep0data[0] = 0;
+ priv->ep0data[1] = 0;
+
+ stm32_ep0in_setupresponse(priv, priv->ep0data, 2);
+ }
+ break;
+
+ default:
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0);
+ priv->stalled = true;
+ }
+ break;
+ }
+ }
+ }
+ break;
+
+ case USB_REQ_CLEARFEATURE:
+ {
+ /* type: host-to-device; recipient = device, interface or endpoint
+ * value: feature selector
+ * index: zero interface endpoint;
+ * len: zero, data = none
+ */
+
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0);
+ if (priv->addressed != 0 && ctrlreq->len == 0)
+ {
+ uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK;
+ if (recipient == USB_REQ_RECIPIENT_ENDPOINT &&
+ ctrlreq->value == USB_FEATURE_ENDPOINTHALT &&
+ (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL)
+ {
+ stm32_ep_clrstall(privep);
+ stm32_ep0in_transmitzlp(priv);
+ }
+ else if (recipient == USB_REQ_RECIPIENT_DEVICE &&
+ ctrlreq->value == USB_FEATURE_REMOTEWAKEUP)
+ {
+ priv->wakeup = 0;
+ stm32_ep0in_transmitzlp(priv);
+ }
+ else
+ {
+ /* Actually, I think we could just stall here. */
+
+ (void)stm32_req_dispatch(priv, &priv->ctrlreq);
+ }
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0);
+ priv->stalled = true;
+ }
+ }
+ break;
+
+ case USB_REQ_SETFEATURE:
+ {
+ /* type: host-to-device; recipient = device, interface, endpoint
+ * value: feature selector
+ * index: zero interface endpoint;
+ * len: 0; data = none
+ */
+
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0);
+ if (priv->addressed != 0 && ctrlreq->len == 0)
+ {
+ uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK;
+ if (recipient == USB_REQ_RECIPIENT_ENDPOINT &&
+ ctrlreq->value == USB_FEATURE_ENDPOINTHALT &&
+ (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL)
+ {
+ stm32_ep_setstall(privep);
+ stm32_ep0in_transmitzlp(priv);
+ }
+ else if (recipient == USB_REQ_RECIPIENT_DEVICE &&
+ ctrlreq->value == USB_FEATURE_REMOTEWAKEUP)
+ {
+ priv->wakeup = 1;
+ stm32_ep0in_transmitzlp(priv);
+ }
+ else if (recipient == USB_REQ_RECIPIENT_DEVICE &&
+ ctrlreq->value == USB_FEATURE_TESTMODE &&
+ ((ctrlreq->index & 0xff) == 0))
+ {
+ stm32_ep0out_testmode(priv, ctrlreq->index);
+ }
+ else if (priv->configured)
+ {
+ /* Actually, I think we could just stall here. */
+
+ (void)stm32_req_dispatch(priv, &priv->ctrlreq);
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0);
+ priv->stalled = true;
+ }
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0);
+ priv->stalled = true;
+ }
+ }
+ break;
+
+ case USB_REQ_SETADDRESS:
+ {
+ /* type: host-to-device; recipient = device
+ * value: device address
+ * index: 0
+ * len: 0; data = none
+ */
+
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), ctrlreq->value);
+ if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
+ ctrlreq->index == 0 &&
+ ctrlreq->len == 0 &&
+ ctrlreq->value < 128 &&
+ priv->devstate != DEVSTATE_CONFIGURED)
+ {
+ /* Save the address. We cannot actually change to the next address until
+ * the completion of the status phase.
+ */
+
+ stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]);
+ stm32_ep0in_transmitzlp(priv);
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0);
+ priv->stalled = true;
+ }
+ }
+ break;
+
+ case USB_REQ_GETDESCRIPTOR:
+ /* type: device-to-host; recipient = device
+ * value: descriptor type and index
+ * index: 0 or language ID;
+ * len: descriptor len; data = descriptor
+ */
+
+ case USB_REQ_SETDESCRIPTOR:
+ /* type: host-to-device; recipient = device
+ * value: descriptor type and index
+ * index: 0 or language ID;
+ * len: descriptor len; data = descriptor
+ */
+
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0);
+ if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE)
+ {
+ (void)stm32_req_dispatch(priv, &priv->ctrlreq);
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0);
+ priv->stalled = true;
+ }
+ }
+ break;
+
+ case USB_REQ_GETCONFIGURATION:
+ /* type: device-to-host; recipient = device
+ * value: 0;
+ * index: 0;
+ * len: 1; data = configuration value
+ */
+
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0);
+ if (priv->addressed &&
+ (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
+ ctrlreq->value == 0 &&
+ ctrlreq->index == 0 &&
+ ctrlreq->len == 1)
+ {
+ (void)stm32_req_dispatch(priv, &priv->ctrlreq);
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0);
+ priv->stalled = true;
+ }
+ }
+ break;
+
+ case USB_REQ_SETCONFIGURATION:
+ /* type: host-to-device; recipient = device
+ * value: configuration value
+ * index: 0;
+ * len: 0; data = none
+ */
+
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0);
+ if (priv->addressed &&
+ (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
+ ctrlreq->index == 0 &&
+ ctrlreq->len == 0)
+ {
+ /* Give the configuration to the class driver */
+
+ int ret = stm32_req_dispatch(priv, &priv->ctrlreq);
+
+ /* If the class driver accepted the configuration, then mark the
+ * device state as configured (or not, depending on the
+ * configuration).
+ */
+
+ if (ret == OK)
+ {
+ uint8_t cfg = (uint8_t)ctrlreq->value;
+ if (cfg != 0)
+ {
+ priv->devstate = DEVSTATE_CONFIGURED;
+ priv->configured = true;
+ }
+ else
+ {
+ priv->devstate = DEVSTATE_ADDRESSED;
+ priv->configured = false;
+ }
+ }
+ }
+ else
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0);
+ priv->stalled = true;
+ }
+ }
+ break;
+
+ case USB_REQ_GETINTERFACE:
+ /* type: device-to-host; recipient = interface
+ * value: 0
+ * index: interface;
+ * len: 1; data = alt interface
+ */
+
+ case USB_REQ_SETINTERFACE:
+ /* type: host-to-device; recipient = interface
+ * value: alternate setting
+ * index: interface;
+ * len: 0; data = none
+ */
+
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0);
+ (void)stm32_req_dispatch(priv, &priv->ctrlreq);
+ }
+ break;
+
+ case USB_REQ_SYNCHFRAME:
+ /* type: device-to-host; recipient = endpoint
+ * value: 0
+ * index: endpoint;
+ * len: 2; data = frame number
+ */
+
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0);
+ }
+ break;
+
+ default:
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0);
+ priv->stalled = true;
+ }
+ break;
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_ep0out_setup
+ *
+ * Description:
+ * USB Ctrl EP Setup Event. This is logically part of the USB interrupt
+ * handler. This event occurs when a setup packet is receive on EP0 OUT.
+ *
+ ****************************************************************************/
+
+static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv)
+{
+ struct stm32_ctrlreq_s ctrlreq;
+
+ /* Verify that a SETUP was received */
+
+ if (priv->ep0state != EP0STATE_SETUP_READY)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0NOSETUP), priv->ep0state);
+ return;
+ }
+
+ /* Terminate any pending requests */
+
+ stm32_req_cancel(&priv->epout[EP0], -EPROTO);
+ stm32_req_cancel(&priv->epin[EP0], -EPROTO);
+
+ /* Assume NOT stalled */
+
+ priv->epout[EP0].stalled = false;
+ priv->epin[EP0].stalled = false;
+ priv->stalled = false;
+
+ /* Starting to process a control request - update state */
+
+ priv->ep0state = EP0STATE_SETUP_PROCESS;
+
+ /* And extract the little-endian 16-bit values to host order */
+
+ ctrlreq.type = priv->ctrlreq.type;
+ ctrlreq.req = priv->ctrlreq.req;
+ ctrlreq.value = GETUINT16(priv->ctrlreq.value);
+ ctrlreq.index = GETUINT16(priv->ctrlreq.index);
+ ctrlreq.len = GETUINT16(priv->ctrlreq.len);
+
+ uinfo("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
+ ctrlreq.type, ctrlreq.req, ctrlreq.value, ctrlreq.index, ctrlreq.len);
+
+ /* Check for a standard request */
+
+ if ((ctrlreq.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD)
+ {
+ /* Dispatch any non-standard requests */
+
+ (void)stm32_req_dispatch(priv, &priv->ctrlreq);
+ }
+ else
+ {
+ /* Handle standard requests. */
+
+ stm32_ep0out_stdrequest(priv, &ctrlreq);
+ }
+
+ /* Check if the setup processing resulted in a STALL */
+
+ if (priv->stalled)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state);
+ stm32_ep0_stall(priv);
+ }
+
+ /* Reset state/data associated with thie SETUP request */
+
+ priv->ep0datlen = 0;
+}
+
+/****************************************************************************
+ * Name: stm32_epout
+ *
+ * Description:
+ * This is part of the OUT endpoint interrupt processing. This function
+ * handles the OUT event for a single endpoint.
+ *
+ ****************************************************************************/
+
+static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, uint8_t epno)
+{
+ FAR struct stm32_ep_s *privep;
+
+ /* Endpoint 0 is a special case. */
+
+ if (epno == 0)
+ {
+ privep = &priv->epout[EP0];
+
+ /* In the EP0STATE_DATA_OUT state, we are receiving data into the
+ * request buffer. In that case, we must continue the request
+ * processing.
+ */
+
+ if (priv->ep0state == EP0STATE_DATA_OUT)
+ {
+ /* Continue processing data from the EP0 OUT request queue */
+
+ stm32_epout_complete(priv, privep);
+
+ /* If we are not actively processing an OUT request, then we
+ * need to setup to receive the next control request.
+ */
+
+ if (!privep->active)
+ {
+ stm32_ep0out_ctrlsetup(priv);
+ priv->ep0state = EP0STATE_IDLE;
+ }
+ }
+ }
+
+ /* For other endpoints, the only possibility is that we are continuing
+ * or finishing an OUT request.
+ */
+
+ else if (priv->devstate == DEVSTATE_CONFIGURED)
+ {
+ stm32_epout_complete(priv, &priv->epout[epno]);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_epout_interrupt
+ *
+ * Description:
+ * USB OUT endpoint interrupt handler. The core generates this interrupt when
+ * there is an interrupt is pending on one of the OUT endpoints of the core.
+ * The driver must read the OTG DAINT register to determine the exact number
+ * of the OUT endpoint on which the interrupt occurred, and then read the
+ * corresponding OTG DOEPINTx register to determine the exact cause of the
+ * interrupt.
+ *
+ ****************************************************************************/
+
+static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv)
+{
+ uint32_t daint;
+ uint32_t regval;
+ uint32_t doepint;
+ int epno;
+
+ /* Get the pending, enabled interrupts for the OUT endpoint from the endpoint
+ * interrupt status register.
+ */
+
+ regval = stm32_getreg(STM32_OTG_DAINT);
+ regval &= stm32_getreg(STM32_OTG_DAINTMSK);
+ daint = (regval & OTG_DAINT_OEP_MASK) >> OTG_DAINT_OEP_SHIFT;
+
+ if (daint == 0)
+ {
+ /* We got an interrupt, but there is no unmasked endpoint that caused
+ * it ?! When this happens, the interrupt flag never gets cleared and
+ * we are stuck in infinite interrupt loop.
+ *
+ * This shouldn't happen if we are diligent about handling timing
+ * issues when masking endpoint interrupts. However, this workaround
+ * avoids infinite loop and allows operation to continue normally. It
+ * works by clearing each endpoint flags, masked or not.
+ */
+
+ regval = stm32_getreg(STM32_OTG_DAINT);
+ daint = (regval & OTG_DAINT_OEP_MASK) >> OTG_DAINT_OEP_SHIFT;
+
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTUNEXPECTED),
+ (uint16_t)regval);
+
+ epno = 0;
+ while (daint)
+ {
+ if ((daint & 1) != 0)
+ {
+ regval = stm32_getreg(STM32_OTG_DOEPINT(epno));
+ uerr("DOEPINT(%d) = %08x\n", epno, regval);
+ stm32_putreg(0xFF, STM32_OTG_DOEPINT(epno));
+ }
+
+ epno++;
+ daint >>= 1;
+ }
+
+ return;
+ }
+
+ /* Process each pending IN endpoint interrupt */
+
+ epno = 0;
+ while (daint)
+ {
+ /* Is an OUT interrupt pending for this endpoint? */
+
+ if ((daint & 1) != 0)
+ {
+ /* Yes.. get the OUT endpoint interrupt status */
+
+ doepint = stm32_getreg(STM32_OTG_DOEPINT(epno));
+ doepint &= stm32_getreg(STM32_OTG_DOEPMSK);
+
+ /* Transfer completed interrupt. This interrupt is trigged when
+ * stm32_rxinterrupt() removes the last packet data from the RxFIFO.
+ * In this case, core internally sets the NAK bit for this endpoint to
+ * prevent it from receiving any more packets.
+ */
+
+ if ((doepint & OTG_DOEPINT_XFRC) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_XFRC), (uint16_t)doepint);
+
+ /* Clear the bit in DOEPINTn for this interrupt */
+
+ stm32_putreg(OTG_DOEPINT_XFRC, STM32_OTG_DOEPINT(epno));
+
+ /* Handle the RX transfer data ready event */
+
+ stm32_epout(priv, epno);
+ }
+
+ /* Endpoint disabled interrupt (ignored because this interrupt is
+ * used in polled mode by the endpoint disable logic).
+ */
+#if 1
+ /* REVISIT: */
+ if ((doepint & OTG_DOEPINT_EPDISD) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_EPDISD), (uint16_t)doepint);
+
+ /* Clear the bit in DOEPINTn for this interrupt */
+
+ stm32_putreg(OTG_DOEPINT_EPDISD, STM32_OTG_DOEPINT(epno));
+ }
+#endif
+ /* Setup Phase Done (control EPs) */
+
+ if ((doepint & OTG_DOEPINT_SETUP) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_SETUP), priv->ep0state);
+
+ /* Handle the receipt of the IN SETUP packets now (OUT setup
+ * packet processing may be delayed until the accompanying
+ * OUT DATA is received)
+ */
+
+ if (priv->ep0state == EP0STATE_SETUP_READY)
+ {
+ stm32_ep0out_setup(priv);
+ }
+ stm32_putreg(OTG_DOEPINT_SETUP, STM32_OTG_DOEPINT(epno));
+ }
+ }
+
+ epno++;
+ daint >>= 1;
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_epin_runtestmode
+ *
+ * Description:
+ * Execute the test mode setup by the SET FEATURE request
+ *
+ ****************************************************************************/
+
+static inline void stm32_epin_runtestmode(FAR struct stm32_usbdev_s *priv)
+{
+ uint32_t regval = stm32_getreg(STM32_OTG_DCTL);
+ regval &= OTG_DCTL_TCTL_MASK;
+ regval |= (uint32_t)priv->testmode << OTG_DCTL_TCTL_SHIFT;
+ stm32_putreg(regval , STM32_OTG_DCTL);
+
+ priv->dotest = 0;
+ priv->testmode = OTG_TESTMODE_DISABLED;
+}
+
+/****************************************************************************
+ * Name: stm32_epin
+ *
+ * Description:
+ * This is part of the IN endpoint interrupt processing. This function
+ * handles the IN event for a single endpoint.
+ *
+ ****************************************************************************/
+
+static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno)
+{
+ FAR struct stm32_ep_s *privep = &priv->epin[epno];
+
+ /* Endpoint 0 is a special case. */
+
+ if (epno == 0)
+ {
+ /* In the EP0STATE_DATA_IN state, we are sending data from request
+ * buffer. In that case, we must continue the request processing.
+ */
+
+ if (priv->ep0state == EP0STATE_DATA_IN)
+ {
+ /* Continue processing data from the EP0 OUT request queue */
+
+ stm32_epin_request(priv, privep);
+
+ /* If we are not actively processing an OUT request, then we
+ * need to setup to receive the next control request.
+ */
+
+ if (!privep->active)
+ {
+ stm32_ep0out_ctrlsetup(priv);
+ priv->ep0state = EP0STATE_IDLE;
+ }
+ }
+
+ /* Test mode is another special case */
+
+ if (priv->dotest)
+ {
+ stm32_epin_runtestmode(priv);
+ }
+ }
+
+ /* For other endpoints, the only possibility is that we are continuing
+ * or finishing an IN request.
+ */
+
+ else if (priv->devstate == DEVSTATE_CONFIGURED)
+ {
+ /* Continue processing data from the endpoint write request queue */
+
+ stm32_epin_request(priv, privep);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_epin_txfifoempty
+ *
+ * Description:
+ * TxFIFO empty interrupt handling
+ *
+ ****************************************************************************/
+
+static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv, int epno)
+{
+ FAR struct stm32_ep_s *privep = &priv->epin[epno];
+
+ /* Continue processing the write request queue. This may mean sending
+ * more data from the existing request or terminating the current requests
+ * and (perhaps) starting the IN transfer from the next write request.
+ */
+
+ stm32_epin_request(priv, privep);
+}
+
+/****************************************************************************
+ * Name: stm32_epin_interrupt
+ *
+ * Description:
+ * USB IN endpoint interrupt handler. The core generates this interrupt when
+ * an interrupt is pending on one of the IN endpoints of the core. The driver
+ * must read the OTG DAINT register to determine the exact number of the IN
+ * endpoint on which the interrupt occurred, and then read the corresponding
+ * OTG DIEPINTx register to determine the exact cause of the interrupt.
+ *
+ ****************************************************************************/
+
+static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv)
+{
+ uint32_t diepint;
+ uint32_t daint;
+ uint32_t mask;
+ uint32_t empty;
+ int epno;
+
+ /* Get the pending, enabled interrupts for the IN endpoint from the endpoint
+ * interrupt status register.
+ */
+
+ daint = stm32_getreg(STM32_OTG_DAINT);
+ daint &= stm32_getreg(STM32_OTG_DAINTMSK);
+ daint &= OTG_DAINT_IEP_MASK;
+
+ if (daint == 0)
+ {
+ /* We got an interrupt, but there is no unmasked endpoint that caused
+ * it ?! When this happens, the interrupt flag never gets cleared and
+ * we are stuck in infinite interrupt loop.
+ *
+ * This shouldn't happen if we are diligent about handling timing
+ * issues when masking endpoint interrupts. However, this workaround
+ * avoids infinite loop and allows operation to continue normally. It
+ * works by clearing each endpoint flags, masked or not.
+ */
+
+ daint = stm32_getreg(STM32_OTG_DAINT);
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINUNEXPECTED),
+ (uint16_t)daint);
+
+ daint &= OTG_DAINT_IEP_MASK;
+ epno = 0;
+
+ while (daint)
+ {
+ if ((daint & 1) != 0)
+ {
+ uerr("DIEPINT(%d) = %08x\n",
+ epno, stm32_getreg(STM32_OTG_DIEPINT(epno)));
+ stm32_putreg(0xFF, STM32_OTG_DIEPINT(epno));
+ }
+
+ epno++;
+ daint >>= 1;
+ }
+
+ return;
+ }
+
+ /* Process each pending IN endpoint interrupt */
+
+ epno = 0;
+ while (daint)
+ {
+ /* Is an IN interrupt pending for this endpoint? */
+
+ if ((daint & 1) != 0)
+ {
+ /* Get IN interrupt mask register. Bits 0-6 correspond to enabled
+ * interrupts as will be found in the DIEPINT interrupt status
+ * register.
+ */
+
+ mask = stm32_getreg(STM32_OTG_DIEPMSK);
+
+ /* Check if the TxFIFO not empty interrupt is enabled for this
+ * endpoint in the DIEPMSK register. Bits n corresponds to
+ * endpoint n in the register. That condition corresponds to
+ * bit 7 of the DIEPINT interrupt status register. There is
+ * no TXFE bit in the mask register, so we fake one here.
+ */
+
+ empty = stm32_getreg(STM32_OTG_DIEPEMPMSK);
+ if ((empty & OTG_DIEPEMPMSK(epno)) != 0)
+ {
+ mask |= OTG_DIEPINT_TXFE;
+ }
+
+ /* Now, read the interrupt status and mask out all disabled
+ * interrupts.
+ */
+
+ diepint = stm32_getreg(STM32_OTG_DIEPINT(epno)) & mask;
+
+ /* Decode and process the enabled, pending interrupts */
+ /* Transfer completed interrupt */
+
+ if ((diepint & OTG_DIEPINT_XFRC) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_XFRC),
+ (uint16_t)diepint);
+
+ /* It is possible that logic may be waiting for a the
+ * TxFIFO to become empty. We disable the TxFIFO empty
+ * interrupt here; it will be re-enabled if there is still
+ * insufficient space in the TxFIFO.
+ */
+
+ empty &= ~OTG_DIEPEMPMSK(epno);
+ stm32_putreg(empty, STM32_OTG_DIEPEMPMSK);
+ stm32_putreg(OTG_DIEPINT_XFRC, STM32_OTG_DIEPINT(epno));
+
+ /* IN transfer complete */
+
+ stm32_epin(priv, epno);
+ }
+
+ /* Timeout condition */
+
+ if ((diepint & OTG_DIEPINT_TOC) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TOC), (uint16_t)diepint);
+ stm32_putreg(OTG_DIEPINT_TOC, STM32_OTG_DIEPINT(epno));
+ }
+
+ /* IN token received when TxFIFO is empty. Applies to non-periodic IN
+ * endpoints only. This interrupt indicates that an IN token was received
+ * when the associated TxFIFO (periodic/non-periodic) was empty. This
+ * interrupt is asserted on the endpoint for which the IN token was
+ * received.
+ */
+
+ if ((diepint & OTG_DIEPINT_ITTXFE) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_ITTXFE), (uint16_t)diepint);
+ stm32_epin_request(priv, &priv->epin[epno]);
+ stm32_putreg(OTG_DIEPINT_ITTXFE, STM32_OTG_DIEPINT(epno));
+ }
+
+ /* IN endpoint NAK effective (ignored as this used only in polled
+ * mode)
+ */
+#if 0
+ if ((diepint & OTG_DIEPINT_INEPNE) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_INEPNE), (uint16_t)diepint);
+ stm32_putreg(OTG_DIEPINT_INEPNE, STM32_OTG_DIEPINT(epno));
+ }
+#endif
+ /* Endpoint disabled interrupt (ignored as this used only in polled
+ * mode)
+ */
+#if 0
+ if ((diepint & OTG_DIEPINT_EPDISD) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EPDISD), (uint16_t)diepint);
+ stm32_putreg(OTG_DIEPINT_EPDISD, STM32_OTG_DIEPINT(epno));
+ }
+#endif
+ /* Transmit FIFO empty */
+
+ if ((diepint & OTG_DIEPINT_TXFE) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TXFE), (uint16_t)diepint);
+
+ /* If we were waiting for TxFIFO to become empty, the we might have both
+ * XFRC and TXFE interrupts pending. Since we do the same thing for both
+ * cases, ignore the TXFE if we have already processed the XFRC.
+ */
+
+ if ((diepint & OTG_DIEPINT_XFRC) == 0)
+ {
+ /* Mask further FIFO empty interrupts. This will be re-enabled
+ * whenever we need to wait for a FIFO event.
+ */
+
+ empty &= ~OTG_DIEPEMPMSK(epno);
+ stm32_putreg(empty, STM32_OTG_DIEPEMPMSK);
+
+ /* Handle TxFIFO empty */
+
+ stm32_epin_txfifoempty(priv, epno);
+ }
+
+ /* Clear the pending TxFIFO empty interrupt */
+
+ stm32_putreg(OTG_DIEPINT_TXFE, STM32_OTG_DIEPINT(epno));
+ }
+ }
+
+ epno++;
+ daint >>= 1;
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_resumeinterrupt
+ *
+ * Description:
+ * Resume/remote wakeup detected interrupt
+ *
+ ****************************************************************************/
+
+static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv)
+{
+ uint32_t regval;
+
+ /* Restart the PHY clock and un-gate USB core clock (HCLK) */
+
+#ifdef CONFIG_USBDEV_LOWPOWER
+ regval = stm32_getreg(STM32_OTG_PCGCCTL);
+ regval &= ~(OTG_PCGCCTL_STPPCLK | OTG_PCGCCTL_GATEHCLK);
+ stm32_putreg(regval, STM32_OTG_PCGCCTL);
+#endif
+
+ /* Clear remote wake-up signaling */
+
+ regval = stm32_getreg(STM32_OTG_DCTL);
+ regval &= ~OTG_DCTL_RWUSIG;
+ stm32_putreg(regval, STM32_OTG_DCTL);
+
+ /* Restore full power -- whatever that means for this particular board */
+
+ stm32_usbsuspend((struct usbdev_s *)priv, true);
+
+ /* Notify the class driver of the resume event */
+
+ if (priv->driver)
+ {
+ CLASS_RESUME(priv->driver, &priv->usbdev);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_suspendinterrupt
+ *
+ * Description:
+ * USB suspend interrupt
+ *
+ ****************************************************************************/
+
+static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv)
+{
+#ifdef CONFIG_USBDEV_LOWPOWER
+ uint32_t regval;
+#endif
+
+ /* Notify the class driver of the suspend event */
+
+ if (priv->driver)
+ {
+ CLASS_SUSPEND(priv->driver, &priv->usbdev);
+ }
+
+#ifdef CONFIG_USBDEV_LOWPOWER
+ /* OTG_DSTS_SUSPSTS is set as long as the suspend condition is detected
+ * on USB. Check if we are still have the suspend condition, that we are
+ * connected to the host, and that we have been configured.
+ */
+
+ regval = stm32_getreg(STM32_OTG_DSTS);
+
+ if ((regval & OTG_DSTS_SUSPSTS) != 0 && devstate == DEVSTATE_CONFIGURED)
+ {
+ /* Switch off OTG clocking. Setting OTG_PCGCCTL_STPPCLK stops the
+ * PHY clock.
+ */
+
+ regval = stm32_getreg(STM32_OTG_PCGCCTL);
+ regval |= OTG_PCGCCTL_STPPCLK;
+ stm32_putreg(regval, STM32_OTG_PCGCCTL);
+
+ /* Setting OTG_PCGCCTL_GATEHCLK gate HCLK to modules other than
+ * the AHB Slave and Master and wakeup logic.
+ */
+
+ regval |= OTG_PCGCCTL_GATEHCLK;
+ stm32_putreg(regval, STM32_OTG_PCGCCTL);
+ }
+#endif
+
+ /* Let the board-specific logic know that we have entered the suspend
+ * state
+ */
+
+ stm32_usbsuspend((FAR struct usbdev_s *)priv, false);
+}
+
+/****************************************************************************
+ * Name: stm32_rxinterrupt
+ *
+ * Description:
+ * RxFIFO non-empty interrupt. This interrupt indicates that there is at
+ * least one packet pending to be read from the RxFIFO.
+ *
+ ****************************************************************************/
+
+static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv)
+{
+ FAR struct stm32_ep_s *privep;
+ uint32_t regval;
+ int bcnt;
+ int epphy;
+
+ /* Disable the Rx status queue level interrupt */
+
+ regval = stm32_getreg(STM32_OTG_GINTMSK);
+ regval &= ~OTG_GINT_RXFLVL;
+ stm32_putreg(regval, STM32_OTG_GINTMSK);
+
+ /* Get the status from the top of the FIFO */
+
+ regval = stm32_getreg(STM32_OTG_GRXSTSP);
+
+ /* Decode status fields */
+
+ epphy = (regval & OTG_GRXSTSD_EPNUM_MASK) >> OTG_GRXSTSD_EPNUM_SHIFT;
+
+ if (epphy < STM32_NENDPOINTS)
+ {
+ privep = &priv->epout[epphy];
+
+ /* Handle the RX event according to the packet status field */
+
+ switch (regval & OTG_GRXSTSD_PKTSTS_MASK)
+ {
+ /* Global OUT NAK. This indicate that the global OUT NAK bit has taken
+ * effect.
+ *
+ * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't
+ * Care.
+ */
+
+ case OTG_GRXSTSD_PKTSTS_OUTNAK:
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0);
+ }
+ break;
+
+ /* OUT data packet received.
+ *
+ * PKTSTS = DataOUT, BCNT = size of the received data OUT packet,
+ * EPNUM = EPNUM on which the packet was received, DPID = Actual Data PID.
+ */
+
+ case OTG_GRXSTSD_PKTSTS_OUTRECVD:
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy);
+ bcnt = (regval & OTG_GRXSTSD_BCNT_MASK) >> OTG_GRXSTSD_BCNT_SHIFT;
+ if (bcnt > 0)
+ {
+ stm32_epout_receive(privep, bcnt);
+ }
+ }
+ break;
+
+ /* OUT transfer completed. This indicates that an OUT data transfer for
+ * the specified OUT endpoint has completed. After this entry is popped
+ * from the receive FIFO, the core asserts a Transfer Completed interrupt
+ * on the specified OUT endpoint.
+ *
+ * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on
+ * which the data transfer is complete, DPID = Don't Care.
+ */
+
+ case OTG_GRXSTSD_PKTSTS_OUTDONE:
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy);
+ }
+ break;
+
+ /* SETUP transaction completed. This indicates that the Setup stage for
+ * the specified endpoint has completed and the Data stage has started.
+ * After this entry is popped from the receive FIFO, the core asserts a
+ * Setup interrupt on the specified control OUT endpoint (triggers an
+ * interrupt).
+ *
+ * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num,
+ * DPID = Don't Care.
+ */
+
+ case OTG_GRXSTSD_PKTSTS_SETUPDONE:
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy);
+ }
+ break;
+
+ /* SETUP data packet received. This indicates that a SETUP packet for the
+ * specified endpoint is now available for reading from the receive FIFO.
+ *
+ * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0.
+ */
+
+ case OTG_GRXSTSD_PKTSTS_SETUPRECVD:
+ {
+ uint16_t datlen;
+
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy);
+
+ /* Read EP0 setup data. NOTE: If multiple SETUP packets are received,
+ * the last one overwrites the previous setup packets and only that
+ * last SETUP packet will be processed.
+ */
+
+ stm32_rxfifo_read(&priv->epout[EP0], (FAR uint8_t *)&priv->ctrlreq,
+ USB_SIZEOF_CTRLREQ);
+
+ /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP,
+ * then we need to wait for the completion of the data phase to
+ * process the setup command. If it is an IN SETUP packet, then
+ * we must processing the command BEFORE we enter the DATA phase.
+ *
+ * If the data associated with the OUT SETUP packet is zero length,
+ * then, of course, we don't need to wait.
+ */
+
+ datlen = GETUINT16(priv->ctrlreq.len);
+ if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0)
+ {
+ /* Clear NAKSTS so that we can receive the data */
+
+ regval = stm32_getreg(STM32_OTG_DOEPCTL(0));
+ regval |= OTG_DOEPCTL0_CNAK;
+ stm32_putreg(regval, STM32_OTG_DOEPCTL(0));
+
+ /* Wait for the data phase. */
+
+ priv->ep0state = EP0STATE_SETUP_OUT;
+ }
+ else
+ {
+ /* We can process the setup data as soon as SETUP done word is
+ * popped of the RxFIFO.
+ */
+
+ priv->ep0state = EP0STATE_SETUP_READY;
+ }
+ }
+ break;
+
+ default:
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS),
+ (regval & OTG_GRXSTSD_PKTSTS_MASK) >> OTG_GRXSTSD_PKTSTS_SHIFT);
+ }
+ break;
+ }
+ }
+
+ /* Enable the Rx Status Queue Level interrupt */
+
+ regval = stm32_getreg(STM32_OTG_GINTMSK);
+ regval |= OTG_GINT_RXFLVL;
+ stm32_putreg(regval, STM32_OTG_GINTMSK);
+}
+
+/****************************************************************************
+ * Name: stm32_enuminterrupt
+ *
+ * Description:
+ * Enumeration done interrupt
+ *
+ ****************************************************************************/
+
+static inline void stm32_enuminterrupt(FAR struct stm32_usbdev_s *priv)
+{
+ uint32_t regval;
+
+ /* Activate EP0 */
+
+ stm32_ep0in_activate();
+
+ /* Set USB turn-around time for the full speed device with internal PHY interface. */
+
+ regval = stm32_getreg(STM32_OTG_GUSBCFG);
+ regval &= ~OTG_GUSBCFG_TRDT_MASK;
+ regval |= OTG_GUSBCFG_TRDT(5);
+ stm32_putreg(regval, STM32_OTG_GUSBCFG);
+}
+
+/****************************************************************************
+ * Name: stm32_isocininterrupt
+ *
+ * Description:
+ * Incomplete isochronous IN transfer interrupt. Assertion of the incomplete
+ * isochronous IN transfer interrupt indicates an incomplete isochronous IN
+ * transfer on at least one of the isochronous IN endpoints.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_ISOCHRONOUS
+static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv)
+{
+ int i;
+
+ /* The application must read the endpoint control register for all isochronous
+ * IN endpoints to detect endpoints with incomplete IN data transfers.
+ */
+
+ for (i = 0; i < STM32_NENDPOINTS; i++)
+ {
+ /* Is this an isochronous IN endpoint? */
+
+ privep = &priv->epin[i];
+ if (privep->eptype != USB_EP_ATTR_XFER_ISOC)
+ {
+ /* No... keep looking */
+
+ continue;
+ }
+
+ /* Is there an active read request on the isochronous OUT endpoint? */
+
+ if (!privep->active)
+ {
+ /* No.. the endpoint is not actively transmitting data */
+
+ continue;
+ }
+
+ /* Check if this is the endpoint that had the incomplete transfer */
+
+ regaddr = STM32_OTG_DIEPCTL(privep->epphy);
+ doepctl = stm32_getreg(regaddr);
+ dsts = stm32_getreg(STM32_OTG_DSTS);
+
+ /* EONUM = 0:even frame, 1:odd frame
+ * SOFFN = Frame number of the received SOF
+ */
+
+ eonum = ((doepctl & OTG_DIEPCTL_EONUM) != 0);
+ soffn = ((dsts & OTG_DSTS_SOFFN0) != 0);
+
+ if (eonum != soffn)
+ {
+ /* Not this endpoint */
+
+ continue;
+ }
+
+ /* For isochronous IN endpoints with incomplete transfers,
+ * the application must discard the data in the memory and
+ * disable the endpoint.
+ */
+
+ stm32_req_complete(privep, -EIO);
+#warning "Will clear OTG_DIEPCTL_USBAEP too"
+ stm32_epin_disable(privep);
+ break;
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_isocoutinterrupt
+ *
+ * Description:
+ * Incomplete periodic transfer interrupt
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_ISOCHRONOUS
+static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv)
+{
+ FAR struct stm32_ep_s *privep;
+ FAR struct stm32_req_s *privreq;
+ uint32_t regaddr;
+ uint32_t doepctl;
+ uint32_t dsts;
+ bool eonum;
+ bool soffn;
+
+ /* When it receives an IISOOXFR interrupt, the application must read the
+ * control registers of all isochronous OUT endpoints to determine which
+ * endpoints had an incomplete transfer in the current microframe. An
+ * endpoint transfer is incomplete if both the following conditions are true:
+ *
+ * DOEPCTLx:EONUM = DSTS:SOFFN[0], and
+ * DOEPCTLx:EPENA = 1
+ */
+
+ for (i = 0; i < STM32_NENDPOINTS; i++)
+ {
+ /* Is this an isochronous OUT endpoint? */
+
+ privep = &priv->epout[i];
+ if (privep->eptype != USB_EP_ATTR_XFER_ISOC)
+ {
+ /* No... keep looking */
+
+ continue;
+ }
+
+ /* Is there an active read request on the isochronous OUT endpoint? */
+
+ if (!privep->active)
+ {
+ /* No.. the endpoint is not actively transmitting data */
+
+ continue;
+ }
+
+ /* Check if this is the endpoint that had the incomplete transfer */
+
+ regaddr = STM32_OTG_DOEPCTL(privep->epphy);
+ doepctl = stm32_getreg(regaddr);
+ dsts = stm32_getreg(STM32_OTG_DSTS);
+
+ /* EONUM = 0:even frame, 1:odd frame
+ * SOFFN = Frame number of the received SOF
+ */
+
+ eonum = ((doepctl & OTG_DOEPCTL_EONUM) != 0);
+ soffn = ((dsts & OTG_DSTS_SOFFN0) != 0);
+
+ if (eonum != soffn)
+ {
+ /* Not this endpoint */
+
+ continue;
+ }
+
+ /* For isochronous OUT endpoints with incomplete transfers,
+ * the application must discard the data in the memory and
+ * disable the endpoint.
+ */
+
+ stm32_req_complete(privep, -EIO);
+#warning "Will clear OTG_DOEPCTL_USBAEP too"
+ stm32_epout_disable(privep);
+ break;
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_sessioninterrupt
+ *
+ * Description:
+ * Session request/new session detected interrupt
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_VBUSSENSING
+static inline void stm32_sessioninterrupt(FAR struct stm32_usbdev_s *priv)
+{
+#warning "Missing logic"
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_otginterrupt
+ *
+ * Description:
+ * OTG interrupt
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_VBUSSENSING
+static inline void stm32_otginterrupt(FAR struct stm32_usbdev_s *priv)
+{
+ uint32_t regval;
+
+ /* Check for session end detected */
+
+ regval = stm32_getreg(STM32_OTG_GOTGINT);
+ if ((regval & OTG_GOTGINT_SEDET) != 0)
+ {
+#warning "Missing logic"
+ }
+
+ /* Clear OTG interrupt */
+
+ stm32_putreg(retval, STM32_OTG_GOTGINT);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_usbinterrupt
+ *
+ * Description:
+ * USB interrupt handler
+ *
+ ****************************************************************************/
+
+static int stm32_usbinterrupt(int irq, FAR void *context)
+{
+ /* At present, there is only a single OTG device support. Hence it is
+ * pre-allocated as g_otghsdev. However, in most code, the private data
+ * structure will be referenced using the 'priv' pointer (rather than the
+ * global data) in order to simplify any future support for multiple devices.
+ */
+
+ FAR struct stm32_usbdev_s *priv = &g_otghsdev;
+ uint32_t regval;
+
+ usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_USB), 0);
+
+ /* Assure that we are in device mode */
+
+ DEBUGASSERT((stm32_getreg(STM32_OTG_GINTSTS) & OTG_GINTSTS_CMOD) == OTG_GINTSTS_DEVMODE);
+
+ /* Get the state of all enabled interrupts. We will do this repeatedly
+ * some interrupts (like RXFLVL) will generate additional interrupting
+ * events.
+ */
+
+ for (; ; )
+ {
+ /* Get the set of pending, un-masked interrupts */
+
+ regval = stm32_getreg(STM32_OTG_GINTSTS);
+ regval &= stm32_getreg(STM32_OTG_GINTMSK);
+
+ /* Break out of the loop when there are no further pending (and
+ * unmasked) interrupts to be processes.
+ */
+
+ if (regval == 0)
+ {
+ break;
+ }
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_INTPENDING), (uint16_t)regval);
+
+ /* OUT endpoint interrupt. The core sets this bit to indicate that an
+ * interrupt is pending on one of the OUT endpoints of the core.
+ */
+
+ if ((regval & OTG_GINT_OEP) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT), (uint16_t)regval);
+ stm32_epout_interrupt(priv);
+ stm32_putreg(OTG_GINT_OEP, STM32_OTG_GINTSTS);
+ }
+
+ /* IN endpoint interrupt. The core sets this bit to indicate that
+ * an interrupt is pending on one of the IN endpoints of the core.
+ */
+
+ if ((regval & OTG_GINT_IEP) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN), (uint16_t)regval);
+ stm32_epin_interrupt(priv);
+ stm32_putreg(OTG_GINT_IEP, STM32_OTG_GINTSTS);
+ }
+
+ /* Host/device mode mismatch error interrupt */
+
+#ifdef CONFIG_DEBUG_USB
+ if ((regval & OTG_GINT_MMIS) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_MISMATCH), (uint16_t)regval);
+ stm32_putreg(OTG_GINT_MMIS, STM32_OTG_GINTSTS);
+ }
+#endif
+
+ /* Resume/remote wakeup detected interrupt */
+
+ if ((regval & OTG_GINT_WKUP) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_WAKEUP), (uint16_t)regval);
+ stm32_resumeinterrupt(priv);
+ stm32_putreg(OTG_GINT_WKUP, STM32_OTG_GINTSTS);
+ }
+
+ /* USB suspend interrupt */
+
+ if ((regval & OTG_GINT_USBSUSP) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSPEND), (uint16_t)regval);
+ stm32_suspendinterrupt(priv);
+ stm32_putreg(OTG_GINT_USBSUSP, STM32_OTG_GINTSTS);
+ }
+
+ /* Start of frame interrupt */
+
+#ifdef CONFIG_USBDEV_SOFINTERRUPT
+ if ((regval & OTG_GINT_SOF) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SOF), (uint16_t)regval);
+ stm32_putreg(OTG_GINT_SOF, STM32_OTG_GINTSTS);
+ }
+#endif
+
+ /* RxFIFO non-empty interrupt. Indicates that there is at least one
+ * packet pending to be read from the RxFIFO.
+ */
+
+ if ((regval & OTG_GINT_RXFLVL) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_RXFIFO), (uint16_t)regval);
+ stm32_rxinterrupt(priv);
+ stm32_putreg(OTG_GINT_RXFLVL, STM32_OTG_GINTSTS);
+ }
+
+ /* USB reset interrupt */
+
+ if ((regval & OTG_GINT_USBRST) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVRESET), (uint16_t)regval);
+
+ /* Perform the device reset */
+
+ stm32_usbreset(priv);
+ usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_USB), 0);
+ stm32_putreg(OTG_GINT_USBRST, STM32_OTG_GINTSTS);
+ return OK;
+ }
+
+ /* Enumeration done interrupt */
+
+ if ((regval & OTG_GINT_ENUMDNE) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_ENUMDNE), (uint16_t)regval);
+ stm32_enuminterrupt(priv);
+ stm32_putreg(OTG_GINT_ENUMDNE, STM32_OTG_GINTSTS);
+ }
+
+ /* Incomplete isochronous IN transfer interrupt. When the core finds
+ * non-empty any of the isochronous IN endpoint FIFOs scheduled for
+ * the current frame non-empty, the core generates an IISOIXFR
+ * interrupt.
+ */
+
+#ifdef CONFIG_USBDEV_ISOCHRONOUS
+ if ((regval & OTG_GINT_IISOIXFR) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IISOIXFR), (uint16_t)regval);
+ stm32_isocininterrupt(priv);
+ stm32_putreg(OTG_GINT_IISOIXFR, STM32_OTG_GINTSTS);
+ }
+
+ /* Incomplete isochronous OUT transfer. For isochronous OUT
+ * endpoints, the XFRC interrupt may not always be asserted. If the
+ * core drops isochronous OUT data packets, the application could fail
+ * to detect the XFRC interrupt. The incomplete Isochronous OUT data
+ * interrupt indicates that an XFRC interrupt was not asserted on at
+ * least one of the isochronous OUT endpoints. At this point, the
+ * endpoint with the incomplete transfer remains enabled, but no active
+ * transfers remain in progress on this endpoint on the USB.
+ */
+
+ if ((regval & OTG_GINT_IISOOXFR) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IISOOXFR), (uint16_t)regval);
+ stm32_isocoutinterrupt(priv);
+ stm32_putreg(OTG_GINT_IISOOXFR, STM32_OTG_GINTSTS);
+ }
+#endif
+
+ /* Session request/new session detected interrupt */
+
+#ifdef CONFIG_USBDEV_VBUSSENSING
+ if ((regval & OTG_GINT_SRQ) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SRQ), (uint16_t)regval);
+ stm32_sessioninterrupt(priv);
+ stm32_putreg(OTG_GINT_SRQ, STM32_OTG_GINTSTS);
+ }
+
+ /* OTG interrupt */
+
+ if ((regval & OTG_GINT_OTG) != 0)
+ {
+ usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OTG), (uint16_t)regval);
+ stm32_otginterrupt(priv);
+ stm32_putreg(OTG_GINT_OTG, STM32_OTG_GINTSTS);
+ }
+#endif
+ }
+
+ usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_USB), 0);
+ return OK;
+}
+
+/****************************************************************************
+ * Endpoint operations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_enablegonak
+ *
+ * Description:
+ * Enable global OUT NAK mode
+ *
+ ****************************************************************************/
+
+static void stm32_enablegonak(FAR struct stm32_ep_s *privep)
+{
+ uint32_t regval;
+
+ /* First, make sure that there is no GNOAKEFF interrupt pending. */
+
+#if 0
+ stm32_putreg(OTG_GINT_GONAKEFF, STM32_OTG_GINTSTS);
+#endif
+
+ /* Enable Global OUT NAK mode in the core. */
+
+ regval = stm32_getreg(STM32_OTG_DCTL);
+ regval |= OTG_DCTL_SGONAK;
+ stm32_putreg(regval, STM32_OTG_DCTL);
+
+#if 0
+ /* Wait for the GONAKEFF interrupt that indicates that the OUT NAK
+ * mode is in effect. When the interrupt handler pops the OUTNAK word
+ * from the RxFIFO, the core sets the GONAKEFF interrupt.
+ */
+
+ while ((stm32_getreg(STM32_OTG_GINTSTS) & OTG_GINT_GONAKEFF) == 0);
+ stm32_putreg(OTG_GINT_GONAKEFF, STM32_OTG_GINTSTS);
+
+#else
+ /* Since we are in the interrupt handler, we cannot wait inline for the
+ * GONAKEFF because it cannot occur until service the RXFLVL global interrupt
+ * and pop the OUTNAK word from the RxFIFO.
+ *
+ * Perhaps it is sufficient to wait for Global OUT NAK status to be reported
+ * in OTG DCTL register?
+ */
+
+ while ((stm32_getreg(STM32_OTG_DCTL) & OTG_DCTL_GONSTS) == 0);
+#endif
+}
+
+/****************************************************************************
+ * Name: stm32_disablegonak
+ *
+ * Description:
+ * Disable global OUT NAK mode
+ *
+ ****************************************************************************/
+
+static void stm32_disablegonak(FAR struct stm32_ep_s *privep)
+{
+ uint32_t regval;
+
+ /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */
+
+ regval = stm32_getreg(STM32_OTG_DCTL);
+ regval |= OTG_DCTL_CGONAK;
+ stm32_putreg(regval, STM32_OTG_DCTL);
+}
+
+/****************************************************************************
+ * Name: stm32_epout_configure
+ *
+ * Description:
+ * Configure an OUT endpoint, making it usable
+ *
+ * Input Parameters:
+ * privep - a pointer to an internal endpoint structure
+ * eptype - The type of the endpoint
+ * maxpacket - The max packet size of the endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_epout_configure(FAR struct stm32_ep_s *privep,
+ uint8_t eptype, uint16_t maxpacket)
+{
+ uint32_t mpsiz;
+ uint32_t regaddr;
+ uint32_t regval;
+
+ usbtrace(TRACE_EPCONFIGURE, privep->epphy);
+
+ /* For EP0, the packet size is encoded */
+
+ if (privep->epphy == EP0)
+ {
+ DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL);
+
+ /* Map the size in bytes to the encoded value in the register */
+
+ switch (maxpacket)
+ {
+ case 8:
+ mpsiz = OTG_DOEPCTL0_MPSIZ_8;
+ break;
+
+ case 16:
+ mpsiz = OTG_DOEPCTL0_MPSIZ_16;
+ break;
+
+ case 32:
+ mpsiz = OTG_DOEPCTL0_MPSIZ_32;
+ break;
+
+ case 64:
+ mpsiz = OTG_DOEPCTL0_MPSIZ_64;
+ break;
+
+ default:
+ uerr("Unsupported maxpacket: %d\n", maxpacket);
+ return -EINVAL;
+ }
+ }
+
+ /* For other endpoints, the packet size is in bytes */
+
+ else
+ {
+ mpsiz = (maxpacket << OTG_DOEPCTL_MPSIZ_SHIFT);
+ }
+
+ /* If the endpoint is already active don't change the endpoint control
+ * register.
+ */
+
+ regaddr = STM32_OTG_DOEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ if ((regval & OTG_DOEPCTL_USBAEP) == 0)
+ {
+ if (regval & OTG_DOEPCTL_NAKSTS)
+ {
+ regval |= OTG_DOEPCTL_CNAK;
+ }
+
+ regval &= ~(OTG_DOEPCTL_MPSIZ_MASK | OTG_DOEPCTL_EPTYP_MASK);
+ regval |= mpsiz;
+ regval |= (eptype << OTG_DOEPCTL_EPTYP_SHIFT);
+ regval |= (OTG_DOEPCTL_SD0PID | OTG_DOEPCTL_USBAEP);
+ stm32_putreg(regval, regaddr);
+
+ /* Save the endpoint configuration */
+
+ privep->ep.maxpacket = maxpacket;
+ privep->eptype = eptype;
+ privep->stalled = false;
+ }
+
+ /* Enable the interrupt for this endpoint */
+
+ regval = stm32_getreg(STM32_OTG_DAINTMSK);
+ regval |= OTG_DAINT_OEP(privep->epphy);
+ stm32_putreg(regval, STM32_OTG_DAINTMSK);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_epin_configure
+ *
+ * Description:
+ * Configure an IN endpoint, making it usable
+ *
+ * Input Parameters:
+ * privep - a pointer to an internal endpoint structure
+ * eptype - The type of the endpoint
+ * maxpacket - The max packet size of the endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_epin_configure(FAR struct stm32_ep_s *privep,
+ uint8_t eptype, uint16_t maxpacket)
+{
+ uint32_t mpsiz;
+ uint32_t regaddr;
+ uint32_t regval;
+
+ usbtrace(TRACE_EPCONFIGURE, privep->epphy);
+
+ /* For EP0, the packet size is encoded */
+
+ if (privep->epphy == EP0)
+ {
+ DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL);
+
+ /* Map the size in bytes to the encoded value in the register */
+
+ switch (maxpacket)
+ {
+ case 8:
+ mpsiz = OTG_DIEPCTL0_MPSIZ_8;
+ break;
+
+ case 16:
+ mpsiz = OTG_DIEPCTL0_MPSIZ_16;
+ break;
+
+ case 32:
+ mpsiz = OTG_DIEPCTL0_MPSIZ_32;
+ break;
+
+ case 64:
+ mpsiz = OTG_DIEPCTL0_MPSIZ_64;
+ break;
+
+ default:
+ uerr("Unsupported maxpacket: %d\n", maxpacket);
+ return -EINVAL;
+ }
+ }
+
+ /* For other endpoints, the packet size is in bytes */
+
+ else
+ {
+ mpsiz = (maxpacket << OTG_DIEPCTL_MPSIZ_SHIFT);
+ }
+
+
+ /* If the endpoint is already active don't change the endpoint control
+ * register.
+ */
+
+ regaddr = STM32_OTG_DIEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ if ((regval & OTG_DIEPCTL_USBAEP) == 0)
+ {
+ if (regval & OTG_DIEPCTL_NAKSTS)
+ {
+ regval |= OTG_DIEPCTL_CNAK;
+ }
+
+ regval &= ~(OTG_DIEPCTL_MPSIZ_MASK | OTG_DIEPCTL_EPTYP_MASK |
+ OTG_DIEPCTL_TXFNUM_MASK);
+ regval |= mpsiz;
+ regval |= (eptype << OTG_DIEPCTL_EPTYP_SHIFT);
+ regval |= (eptype << OTG_DIEPCTL_TXFNUM_SHIFT);
+ regval |= (OTG_DIEPCTL_SD0PID | OTG_DIEPCTL_USBAEP);
+ stm32_putreg(regval, regaddr);
+
+ /* Save the endpoint configuration */
+
+ privep->ep.maxpacket = maxpacket;
+ privep->eptype = eptype;
+ privep->stalled = false;
+ }
+
+ /* Enable the interrupt for this endpoint */
+
+ regval = stm32_getreg(STM32_OTG_DAINTMSK);
+ regval |= OTG_DAINT_IEP(privep->epphy);
+ stm32_putreg(regval, STM32_OTG_DAINTMSK);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_ep_configure
+ *
+ * Description:
+ * Configure endpoint, making it usable
+ *
+ * Input Parameters:
+ * ep - the struct usbdev_ep_s instance obtained from allocep()
+ * desc - A struct usb_epdesc_s instance describing the endpoint
+ * last - true if this this last endpoint to be configured. Some hardware
+ * needs to take special action when all of the endpoints have been
+ * configured.
+ *
+ ****************************************************************************/
+
+static int stm32_ep_configure(FAR struct usbdev_ep_s *ep,
+ FAR const struct usb_epdesc_s *desc,
+ bool last)
+{
+ FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep;
+ uint16_t maxpacket;
+ uint8_t eptype;
+ int ret;
+
+ usbtrace(TRACE_EPCONFIGURE, privep->epphy);
+ DEBUGASSERT(desc->addr == ep->eplog);
+
+ /* Initialize EP capabilities */
+
+ maxpacket = GETUINT16(desc->mxpacketsize);
+ eptype = desc->attr & USB_EP_ATTR_XFERTYPE_MASK;
+
+ /* Setup Endpoint Control Register */
+
+ if (privep->isin)
+ {
+ ret = stm32_epin_configure(privep, eptype, maxpacket);
+ }
+ else
+ {
+ ret = stm32_epout_configure(privep, eptype, maxpacket);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_ep0_configure
+ *
+ * Description:
+ * Reset Usb engine
+ *
+ ****************************************************************************/
+
+static void stm32_ep0_configure(FAR struct stm32_usbdev_s *priv)
+{
+ /* Enable EP0 IN and OUT */
+
+ (void)stm32_epin_configure(&priv->epin[EP0], USB_EP_ATTR_XFER_CONTROL,
+ CONFIG_USBDEV_EP0_MAXSIZE);
+ (void)stm32_epout_configure(&priv->epout[EP0], USB_EP_ATTR_XFER_CONTROL,
+ CONFIG_USBDEV_EP0_MAXSIZE);
+}
+
+/****************************************************************************
+ * Name: stm32_epout_disable
+ *
+ * Description:
+ * Diable an OUT endpoint will no longer be used
+ *
+ ****************************************************************************/
+
+static void stm32_epout_disable(FAR struct stm32_ep_s *privep)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ irqstate_t flags;
+
+ usbtrace(TRACE_EPDISABLE, privep->epphy);
+
+ /* Is this an IN or an OUT endpoint */
+
+ /* Before disabling any OUT endpoint, the application must enable
+ * Global OUT NAK mode in the core.
+ */
+
+ flags = enter_critical_section();
+ stm32_enablegonak(privep);
+
+ /* Disable the required OUT endpoint by setting the EPDIS and SNAK bits
+ * int DOECPTL register.
+ */
+
+ regaddr = STM32_OTG_DOEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval &= ~OTG_DOEPCTL_USBAEP;
+ regval |= (OTG_DOEPCTL_EPDIS | OTG_DOEPCTL_SNAK);
+ stm32_putreg(regval, regaddr);
+
+ /* Wait for the EPDISD interrupt which indicates that the OUT
+ * endpoint is completely disabled.
+ */
+
+#if 0 /* Doesn't happen */
+ regaddr = STM32_OTG_DOEPINT(privep->epphy);
+ while ((stm32_getreg(regaddr) & OTG_DOEPINT_EPDISD) == 0);
+#else
+ /* REVISIT: */
+ up_udelay(10);
+#endif
+
+ /* Clear the EPDISD interrupt indication */
+
+ stm32_putreg(OTG_DOEPINT_EPDISD, STM32_OTG_DOEPINT(privep->epphy));
+
+ /* Then disable the Global OUT NAK mode to continue receiving data
+ * from other non-disabled OUT endpoints.
+ */
+
+ stm32_disablegonak(privep);
+
+ /* Disable endpoint interrupts */
+
+ regval = stm32_getreg(STM32_OTG_DAINTMSK);
+ regval &= ~OTG_DAINT_OEP(privep->epphy);
+ stm32_putreg(regval, STM32_OTG_DAINTMSK);
+
+ /* Cancel any queued read requests */
+
+ stm32_req_cancel(privep, -ESHUTDOWN);
+
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: stm32_epin_disable
+ *
+ * Description:
+ * Disable an IN endpoint when it will no longer be used
+ *
+ ****************************************************************************/
+
+static void stm32_epin_disable(FAR struct stm32_ep_s *privep)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ irqstate_t flags;
+
+ usbtrace(TRACE_EPDISABLE, privep->epphy);
+
+ /* After USB reset, the endpoint will already be deactivated by the
+ * hardware. Trying to disable again will just hang in the wait.
+ */
+
+ regaddr = STM32_OTG_DIEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ if ((regval & OTG_DIEPCTL_USBAEP) == 0)
+ {
+ return;
+ }
+
+ /* This INEPNE wait logic is suggested by reference manual, but seems
+ * to get stuck to infinite loop.
+ */
+
+#if 0
+ /* Make sure that there is no pending IPEPNE interrupt (because we are
+ * to poll this bit below).
+ */
+
+ stm32_putreg(OTG_DIEPINT_INEPNE, STM32_OTG_DIEPINT(privep->epphy));
+
+ /* Set the endpoint in NAK mode */
+
+ regaddr = STM32_OTG_DIEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval &= ~OTG_DIEPCTL_USBAEP;
+ regval |= (OTG_DIEPCTL_EPDIS | OTG_DIEPCTL_SNAK);
+ stm32_putreg(regval, regaddr);
+
+ /* Wait for the INEPNE interrupt that indicates that we are now in NAK mode */
+
+ regaddr = STM32_OTG_DIEPINT(privep->epphy);
+ while ((stm32_getreg(regaddr) & OTG_DIEPINT_INEPNE) == 0);
+
+ /* Clear the INEPNE interrupt indication */
+
+ stm32_putreg(OTG_DIEPINT_INEPNE, regaddr);
+#endif
+
+ /* Deactivate and disable the endpoint by setting the EPDIS and SNAK bits
+ * the DIEPCTLx register.
+ */
+
+ flags = enter_critical_section();
+ regaddr = STM32_OTG_DIEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval &= ~OTG_DIEPCTL_USBAEP;
+ regval |= (OTG_DIEPCTL_EPDIS | OTG_DIEPCTL_SNAK);
+ stm32_putreg(regval, regaddr);
+
+ /* Wait for the EPDISD interrupt which indicates that the IN
+ * endpoint is completely disabled.
+ */
+
+ regaddr = STM32_OTG_DIEPINT(privep->epphy);
+ while ((stm32_getreg(regaddr) & OTG_DIEPINT_EPDISD) == 0);
+
+ /* Clear the EPDISD interrupt indication */
+
+ stm32_putreg(OTG_DIEPINT_EPDISD, stm32_getreg(regaddr));
+
+ /* Flush any data remaining in the TxFIFO */
+
+ stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_D(privep->epphy));
+
+ /* Disable endpoint interrupts */
+
+ regval = stm32_getreg(STM32_OTG_DAINTMSK);
+ regval &= ~OTG_DAINT_IEP(privep->epphy);
+ stm32_putreg(regval, STM32_OTG_DAINTMSK);
+
+ /* Cancel any queued write requests */
+
+ stm32_req_cancel(privep, -ESHUTDOWN);
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: stm32_ep_disable
+ *
+ * Description:
+ * The endpoint will no longer be used
+ *
+ ****************************************************************************/
+
+static int stm32_ep_disable(FAR struct usbdev_ep_s *ep)
+{
+ FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep;
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!ep)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+#endif
+
+ usbtrace(TRACE_EPDISABLE, privep->epphy);
+
+ /* Is this an IN or an OUT endpoint */
+
+ if (privep->isin)
+ {
+ /* Disable the IN endpoint */
+
+ stm32_epin_disable(privep);
+ }
+ else
+ {
+ /* Disable the OUT endpoint */
+
+ stm32_epout_disable(privep);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_ep_allocreq
+ *
+ * Description:
+ * Allocate an I/O request
+ *
+ ****************************************************************************/
+
+static FAR struct usbdev_req_s *stm32_ep_allocreq(FAR struct usbdev_ep_s *ep)
+{
+ FAR struct stm32_req_s *privreq;
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!ep)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ return NULL;
+ }
+#endif
+
+ usbtrace(TRACE_EPALLOCREQ, ((FAR struct stm32_ep_s *)ep)->epphy);
+
+ privreq = (FAR struct stm32_req_s *)kmm_malloc(sizeof(struct stm32_req_s));
+ if (!privreq)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_ALLOCFAIL), 0);
+ return NULL;
+ }
+
+ memset(privreq, 0, sizeof(struct stm32_req_s));
+ return &privreq->req;
+}
+
+/****************************************************************************
+ * Name: stm32_ep_freereq
+ *
+ * Description:
+ * Free an I/O request
+ *
+ ****************************************************************************/
+
+static void stm32_ep_freereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
+{
+ FAR struct stm32_req_s *privreq = (FAR struct stm32_req_s *)req;
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!ep || !req)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ return;
+ }
+#endif
+
+ usbtrace(TRACE_EPFREEREQ, ((FAR struct stm32_ep_s *)ep)->epphy);
+ kmm_free(privreq);
+}
+
+/****************************************************************************
+ * Name: stm32_ep_allocbuffer
+ *
+ * Description:
+ * Allocate an I/O buffer
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_DMA
+static void *stm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes)
+{
+ usbtrace(TRACE_EPALLOCBUFFER, privep->epphy);
+
+#ifdef CONFIG_USBDEV_DMAMEMORY
+ return usbdev_dma_alloc(bytes);
+#else
+ return kmm_malloc(bytes);
+#endif
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_ep_freebuffer
+ *
+ * Description:
+ * Free an I/O buffer
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBDEV_DMA
+static void stm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf)
+{
+ usbtrace(TRACE_EPFREEBUFFER, privep->epphy);
+
+#ifdef CONFIG_USBDEV_DMAMEMORY
+ usbdev_dma_free(buf);
+#else
+ kmm_free(buf);
+#endif
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_ep_submit
+ *
+ * Description:
+ * Submit an I/O request to the endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_ep_submit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
+{
+ FAR struct stm32_req_s *privreq = (FAR struct stm32_req_s *)req;
+ FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep;
+ FAR struct stm32_usbdev_s *priv;
+ irqstate_t flags;
+ int ret = OK;
+
+ /* Some sanity checking */
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!req || !req->callback || !req->buf || !ep)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ uinfo("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep);
+ return -EINVAL;
+ }
+#endif
+
+ usbtrace(TRACE_EPSUBMIT, privep->epphy);
+ priv = privep->dev;
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!priv->driver)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOTCONFIGURED), priv->usbdev.speed);
+ return -ESHUTDOWN;
+ }
+#endif
+
+ /* Handle the request from the class driver */
+
+ req->result = -EINPROGRESS;
+ req->xfrd = 0;
+
+ /* Disable Interrupts */
+
+ flags = enter_critical_section();
+
+ /* If we are stalled, then drop all requests on the floor */
+
+ if (privep->stalled)
+ {
+ ret = -EBUSY;
+ }
+ else
+ {
+ /* Add the new request to the request queue for the endpoint. */
+
+ if (stm32_req_addlast(privep, privreq) && !privep->active)
+ {
+ /* If a request was added to an IN endpoint, then attempt to send
+ * the request data buffer now.
+ */
+
+ if (privep->isin)
+ {
+ usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len);
+
+ /* If the endpoint is not busy with another write request,
+ * then process the newly received write request now.
+ */
+
+ if (!privep->active)
+ {
+ stm32_epin_request(priv, privep);
+ }
+ }
+
+ /* If the request was added to an OUT endpoint, then attempt to
+ * setup a read into the request data buffer now (this will, of
+ * course, fail if there is already a read in place).
+ */
+
+ else
+ {
+ usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len);
+ stm32_epout_request(priv, privep);
+ }
+ }
+ }
+
+ leave_critical_section(flags);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_ep_cancel
+ *
+ * Description:
+ * Cancel an I/O request previously sent to an endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
+{
+ FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep;
+ irqstate_t flags;
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!ep || !req)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+#endif
+
+ usbtrace(TRACE_EPCANCEL, privep->epphy);
+
+ flags = enter_critical_section();
+
+ /* FIXME: if the request is the first, then we need to flush the EP
+ * otherwise just remove it from the list
+ *
+ * but ... all other implementations cancel all requests ...
+ */
+
+ stm32_req_cancel(privep, -ESHUTDOWN);
+ leave_critical_section(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_epout_setstall
+ *
+ * Description:
+ * Stall an OUT endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_epout_setstall(FAR struct stm32_ep_s *privep)
+{
+#if 1
+ /* This implementation follows the requirements from the STM32 F4 reference
+ * manual.
+ */
+
+ uint32_t regaddr;
+ uint32_t regval;
+
+ /* Put the core in the Global OUT NAK mode */
+
+ stm32_enablegonak(privep);
+
+ /* Disable and STALL the OUT endpoint by setting the EPDIS and STALL bits
+ * in the DOECPTL register.
+ */
+
+ regaddr = STM32_OTG_DOEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval |= (OTG_DOEPCTL_EPDIS | OTG_DOEPCTL_STALL);
+ stm32_putreg(regval, regaddr);
+
+ /* Wait for the EPDISD interrupt which indicates that the OUT
+ * endpoint is completely disabled.
+ */
+
+#if 0 /* Doesn't happen */
+ regaddr = STM32_OTG_DOEPINT(privep->epphy);
+ while ((stm32_getreg(regaddr) & OTG_DOEPINT_EPDISD) == 0);
+#else
+ /* REVISIT: */
+ up_udelay(10);
+#endif
+
+ /* Disable Global OUT NAK mode */
+
+ stm32_disablegonak(privep);
+
+ /* The endpoint is now stalled */
+
+ privep->stalled = true;
+ return OK;
+#else
+ /* This implementation follows the STMicro code example. */
+ /* REVISIT: */
+
+ uint32_t regaddr;
+ uint32_t regval;
+
+ /* Stall the OUT endpoint by setting the STALL bit in the DOECPTL register. */
+
+ regaddr = STM32_OTG_DOEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval |= OTG_DOEPCTL_STALL;
+ stm32_putreg(regval, regaddr);
+
+ /* The endpoint is now stalled */
+
+ privep->stalled = true;
+ return OK;
+#endif
+}
+
+/****************************************************************************
+ * Name: stm32_epin_setstall
+ *
+ * Description:
+ * Stall an IN endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_epin_setstall(FAR struct stm32_ep_s *privep)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+
+ /* Get the IN endpoint device control register */
+
+ regaddr = STM32_OTG_DIEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+
+ /* Then stall the endpoint */
+
+ regval |= OTG_DIEPCTL_STALL;
+ stm32_putreg(regval, regaddr);
+
+ /* The endpoint is now stalled */
+
+ privep->stalled = true;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_ep_setstall
+ *
+ * Description:
+ * Stall an endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_ep_setstall(FAR struct stm32_ep_s *privep)
+{
+ usbtrace(TRACE_EPSTALL, privep->epphy);
+
+ /* Is this an IN endpoint? */
+
+ if (privep->isin == 1)
+ {
+ return stm32_epin_setstall(privep);
+ }
+ else
+ {
+ return stm32_epout_setstall(privep);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_ep_clrstall
+ *
+ * Description:
+ * Resume a stalled endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_ep_clrstall(FAR struct stm32_ep_s *privep)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t stallbit;
+ uint32_t data0bit;
+
+ usbtrace(TRACE_EPRESUME, privep->epphy);
+
+ /* Is this an IN endpoint? */
+
+ if (privep->isin == 1)
+ {
+ /* Clear the stall bit in the IN endpoint device control register */
+
+ regaddr = STM32_OTG_DIEPCTL(privep->epphy);
+ stallbit = OTG_DIEPCTL_STALL;
+ data0bit = OTG_DIEPCTL_SD0PID;
+ }
+ else
+ {
+ /* Clear the stall bit in the IN endpoint device control register */
+
+ regaddr = STM32_OTG_DOEPCTL(privep->epphy);
+ stallbit = OTG_DOEPCTL_STALL;
+ data0bit = OTG_DOEPCTL_SD0PID;
+ }
+
+ /* Clear the stall bit */
+
+ regval = stm32_getreg(regaddr);
+ regval &= ~stallbit;
+
+ /* Set the DATA0 pid for interrupt and bulk endpoints */
+
+ if (privep->eptype == USB_EP_ATTR_XFER_INT ||
+ privep->eptype == USB_EP_ATTR_XFER_BULK)
+ {
+ /* Writing this bit sets the DATA0 PID */
+
+ regval |= data0bit;
+ }
+
+ stm32_putreg(regval, regaddr);
+
+ /* The endpoint is no longer stalled */
+
+ privep->stalled = false;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_ep_stall
+ *
+ * Description:
+ * Stall or resume an endpoint
+ *
+ ****************************************************************************/
+
+static int stm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume)
+{
+ FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep;
+ irqstate_t flags;
+ int ret;
+
+ /* Set or clear the stall condition as requested */
+
+ flags = enter_critical_section();
+ if (resume)
+ {
+ ret = stm32_ep_clrstall(privep);
+ }
+ else
+ {
+ ret = stm32_ep_setstall(privep);
+ }
+ leave_critical_section(flags);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_ep0_stall
+ *
+ * Description:
+ * Stall endpoint 0
+ *
+ ****************************************************************************/
+
+static void stm32_ep0_stall(FAR struct stm32_usbdev_s *priv)
+{
+ stm32_epin_setstall(&priv->epin[EP0]);
+ stm32_epout_setstall(&priv->epout[EP0]);
+ priv->stalled = true;
+ stm32_ep0out_ctrlsetup(priv);
+}
+
+/****************************************************************************
+ * Device operations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_ep_alloc
+ *
+ * Description:
+ * Allocate an endpoint matching the parameters.
+ *
+ * Input Parameters:
+ * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means
+ * that any endpoint matching the other requirements will suffice. The
+ * assigned endpoint can be found in the eplog field.
+ * in - true: IN (device-to-host) endpoint requested
+ * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK,
+ * USB_EP_ATTR_XFER_INT}
+ *
+ ****************************************************************************/
+
+static FAR struct usbdev_ep_s *stm32_ep_alloc(FAR struct usbdev_s *dev,
+ uint8_t eplog, bool in,
+ uint8_t eptype)
+{
+ FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev;
+ uint8_t epavail;
+ irqstate_t flags;
+ int epphy;
+ int epno = 0;
+
+ usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog);
+
+ /* Ignore any direction bits in the logical address */
+
+ epphy = USB_EPNO(eplog);
+
+ /* Get the set of available endpoints depending on the direction */
+
+ flags = enter_critical_section();
+ epavail = priv->epavail[in];
+
+ /* A physical address of 0 means that any endpoint will do */
+
+ if (epphy > 0)
+ {
+ /* Otherwise, we will return the endpoint structure only for the requested
+ * 'logical' endpoint. All of the other checks will still be performed.
+ *
+ * First, verify that the logical endpoint is in the range supported by
+ * by the hardware.
+ */
+
+ if (epphy >= STM32_NENDPOINTS)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPNO), (uint16_t)epphy);
+ return NULL;
+ }
+
+ /* Remove all of the candidate endpoints from the bitset except for the
+ * this physical endpoint number.
+ */
+
+ epavail &= (1 << epphy);
+ }
+
+ /* Is there an available endpoint? */
+
+ if (epavail)
+ {
+ /* Yes.. Select the lowest numbered endpoint in the set of available
+ * endpoints.
+ */
+
+ for (epno = 1; epno < STM32_NENDPOINTS; epno++)
+ {
+ uint8_t bit = 1 << epno;
+ if ((epavail & bit) != 0)
+ {
+ /* Mark the endpoint no longer available */
+
+ priv->epavail[in] &= ~(1 << epno);
+
+ /* And return the pointer to the standard endpoint structure */
+
+ leave_critical_section(flags);
+ return in ? &priv->epin[epno].ep : &priv->epout[epno].ep;
+ }
+ }
+
+ /* We should not get here */
+ }
+
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOEP), (uint16_t)eplog);
+ leave_critical_section(flags);
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: stm32_ep_free
+ *
+ * Description:
+ * Free the previously allocated endpoint
+ *
+ ****************************************************************************/
+
+static void stm32_ep_free(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep)
+{
+ FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev;
+ FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep;
+ irqstate_t flags;
+
+ usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy);
+
+ if (priv && privep)
+ {
+ /* Mark the endpoint as available */
+
+ flags = enter_critical_section();
+ priv->epavail[privep->isin] |= (1 << privep->epphy);
+ leave_critical_section(flags);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_getframe
+ *
+ * Description:
+ * Returns the current frame number
+ *
+ ****************************************************************************/
+
+static int stm32_getframe(struct usbdev_s *dev)
+{
+ uint32_t regval;
+
+ usbtrace(TRACE_DEVGETFRAME, 0);
+
+ /* Return the last frame number of the last SOF detected by the hardware */
+
+ regval = stm32_getreg(STM32_OTG_DSTS);
+ return (int)((regval & OTG_DSTS_SOFFN_MASK) >> OTG_DSTS_SOFFN_SHIFT);
+}
+
+/****************************************************************************
+ * Name: stm32_wakeup
+ *
+ * Description:
+ * Exit suspend mode.
+ *
+ ****************************************************************************/
+
+static int stm32_wakeup(struct usbdev_s *dev)
+{
+ FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev;
+ uint32_t regval;
+ irqstate_t flags;
+
+ usbtrace(TRACE_DEVWAKEUP, 0);
+
+ /* Is wakeup enabled? */
+
+ flags = enter_critical_section();
+ if (priv->wakeup)
+ {
+ /* Yes... is the core suspended? */
+
+ regval = stm32_getreg(STM32_OTG_DSTS);
+ if ((regval & OTG_DSTS_SUSPSTS) != 0)
+ {
+ /* Re-start the PHY clock and un-gate USB core clock (HCLK) */
+
+#ifdef CONFIG_USBDEV_LOWPOWER
+ regval = stm32_getreg(STM32_OTG_PCGCCTL);
+ regval &= ~(OTG_PCGCCTL_STPPCLK | OTG_PCGCCTL_GATEHCLK);
+ stm32_putreg(regval, STM32_OTG_PCGCCTL);
+#endif
+ /* Activate Remote wakeup signaling */
+
+ regval = stm32_getreg(STM32_OTG_DCTL);
+ regval |= OTG_DCTL_RWUSIG;
+ stm32_putreg(regval, STM32_OTG_DCTL);
+ up_mdelay(5);
+ regval &= ~OTG_DCTL_RWUSIG;
+ stm32_putreg(regval, STM32_OTG_DCTL);
+ }
+ }
+
+ leave_critical_section(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_selfpowered
+ *
+ * Description:
+ * Sets/clears the device self-powered feature
+ *
+ ****************************************************************************/
+
+static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered)
+{
+ FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev;
+
+ usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered);
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!dev)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ return -ENODEV;
+ }
+#endif
+
+ priv->selfpowered = selfpowered;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_pullup
+ *
+ * Description:
+ * Software-controlled connect to/disconnect from USB host
+ *
+ ****************************************************************************/
+
+static int stm32_pullup(struct usbdev_s *dev, bool enable)
+{
+ uint32_t regval;
+
+ usbtrace(TRACE_DEVPULLUP, (uint16_t)enable);
+
+ irqstate_t flags = enter_critical_section();
+ regval = stm32_getreg(STM32_OTG_DCTL);
+ if (enable)
+ {
+ /* Connect the device by clearing the soft disconnect bit in the DCTL
+ * register
+ */
+
+ regval &= ~OTG_DCTL_SDIS;
+ }
+ else
+ {
+ /* Connect the device by setting the soft disconnect bit in the DCTL
+ * register
+ */
+
+ regval |= OTG_DCTL_SDIS;
+ }
+
+ stm32_putreg(regval, STM32_OTG_DCTL);
+ leave_critical_section(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_setaddress
+ *
+ * Description:
+ * Set the devices USB address
+ *
+ ****************************************************************************/
+
+static void stm32_setaddress(struct stm32_usbdev_s *priv, uint16_t address)
+{
+ uint32_t regval;
+
+ /* Set the device address in the DCFG register */
+
+ regval = stm32_getreg(STM32_OTG_DCFG);
+ regval &= ~OTG_DCFG_DAD_MASK;
+ regval |= ((uint32_t)address << OTG_DCFG_DAD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DCFG);
+
+ /* Are we now addressed? (i.e., do we have a non-NULL device
+ * address?)
+ */
+
+ if (address != 0)
+ {
+ priv->devstate = DEVSTATE_ADDRESSED;
+ priv->addressed = true;
+ }
+ else
+ {
+ priv->devstate = DEVSTATE_DEFAULT;
+ priv->addressed = false;
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_txfifo_flush
+ *
+ * Description:
+ * Flush the specific TX fifo.
+ *
+ ****************************************************************************/
+
+static int stm32_txfifo_flush(uint32_t txfnum)
+{
+ uint32_t regval;
+ uint32_t timeout;
+
+ /* Initiate the TX FIFO flush operation */
+
+ regval = OTG_GRSTCTL_TXFFLSH | txfnum;
+ stm32_putreg(regval, STM32_OTG_GRSTCTL);
+
+ /* Wait for the FLUSH to complete */
+
+ for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++)
+ {
+ regval = stm32_getreg(STM32_OTG_GRSTCTL);
+ if ((regval & OTG_GRSTCTL_TXFFLSH) == 0)
+ {
+ break;
+ }
+ }
+
+ /* Wait for 3 PHY Clocks */
+
+ up_udelay(3);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_rxfifo_flush
+ *
+ * Description:
+ * Flush the RX fifo.
+ *
+ ****************************************************************************/
+
+static int stm32_rxfifo_flush(void)
+{
+ uint32_t regval;
+ uint32_t timeout;
+
+ /* Initiate the RX FIFO flush operation */
+
+ stm32_putreg(OTG_GRSTCTL_RXFFLSH, STM32_OTG_GRSTCTL);
+
+ /* Wait for the FLUSH to complete */
+
+ for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++)
+ {
+ regval = stm32_getreg(STM32_OTG_GRSTCTL);
+ if ((regval & OTG_GRSTCTL_RXFFLSH) == 0)
+ {
+ break;
+ }
+ }
+
+ /* Wait for 3 PHY Clocks */
+
+ up_udelay(3);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_swinitialize
+ *
+ * Description:
+ * Initialize all driver data structures.
+ *
+ ****************************************************************************/
+
+static void stm32_swinitialize(FAR struct stm32_usbdev_s *priv)
+{
+ FAR struct stm32_ep_s *privep;
+ int i;
+
+ /* Initialize the device state structure */
+
+ memset(priv, 0, sizeof(struct stm32_usbdev_s));
+
+ priv->usbdev.ops = &g_devops;
+ priv->usbdev.ep0 = &priv->epin[EP0].ep;
+
+ priv->epavail[0] = STM32_EP_AVAILABLE;
+ priv->epavail[1] = STM32_EP_AVAILABLE;
+
+ priv->epin[EP0].ep.priv = priv;
+ priv->epout[EP0].ep.priv = priv;
+
+ /* Initialize the endpoint lists */
+
+ for (i = 0; i < STM32_NENDPOINTS; i++)
+ {
+ /* Set endpoint operations, reference to driver structure (not
+ * really necessary because there is only one controller), and
+ * the physical endpoint number (which is just the index to the
+ * endpoint).
+ */
+
+ privep = &priv->epin[i];
+ privep->ep.ops = &g_epops;
+ privep->dev = priv;
+ privep->isin = 1;
+
+ /* The index, i, is the physical endpoint address; Map this
+ * to a logical endpoint address usable by the class driver.
+ */
+
+ privep->epphy = i;
+ privep->ep.eplog = STM32_EPPHYIN2LOG(i);
+
+ /* Control until endpoint is activated */
+
+ privep->eptype = USB_EP_ATTR_XFER_CONTROL;
+ privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE;
+ }
+
+ /* Initialize the endpoint lists */
+
+ for (i = 0; i < STM32_NENDPOINTS; i++)
+ {
+ /* Set endpoint operations, reference to driver structure (not
+ * really necessary because there is only one controller), and
+ * the physical endpoint number (which is just the index to the
+ * endpoint).
+ */
+
+ privep = &priv->epout[i];
+ privep->ep.ops = &g_epops;
+ privep->dev = priv;
+
+ /* The index, i, is the physical endpoint address; Map this
+ * to a logical endpoint address usable by the class driver.
+ */
+
+ privep->epphy = i;
+ privep->ep.eplog = STM32_EPPHYOUT2LOG(i);
+
+ /* Control until endpoint is activated */
+
+ privep->eptype = USB_EP_ATTR_XFER_CONTROL;
+ privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE;
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_hwinitialize
+ *
+ * Description:
+ * Configure the OTG core for operation.
+ *
+ ****************************************************************************/
+
+static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
+{
+ uint32_t regval;
+ uint32_t timeout;
+ uint32_t address;
+ int i;
+
+ /* At start-up the core is in FS/HS mode. */
+
+ /* Disable global interrupts by clearing the GINTMASK bit in the GAHBCFG
+ * register; Set the TXFELVL bit in the GAHBCFG register so that TxFIFO
+ * interrupts will occur when the TxFIFO is truly empty (not just half full).
+ */
+
+ stm32_putreg(OTG_GAHBCFG_TXFELVL, STM32_OTG_GAHBCFG);
+
+#if defined(CONFIG_STM32F7_OTGHS)
+ /* Set the PHYSEL bit in the GUSBCFG register to select the OTG HS serial
+ * transceiver: "This bit is always 1 with write-only access"
+ */
+
+ regval = stm32_getreg(STM32_OTG_GUSBCFG);
+ regval |= OTG_GUSBCFG_PHYSEL;
+ stm32_putreg(regval, STM32_OTG_GUSBCFG);
+#endif
+
+ /* Common USB OTG core initialization */
+ /* Reset after a PHY select and set Host mode. First, wait for AHB master
+ * IDLE state.
+ */
+
+ for (timeout = 0; timeout < STM32_READY_DELAY; timeout++)
+ {
+ up_udelay(3);
+ regval = stm32_getreg(STM32_OTG_GRSTCTL);
+ if ((regval & OTG_GRSTCTL_AHBIDL) != 0)
+ {
+ break;
+ }
+ }
+
+ /* Then perform the core soft reset. */
+
+ stm32_putreg(OTG_GRSTCTL_CSRST, STM32_OTG_GRSTCTL);
+ for (timeout = 0; timeout < STM32_READY_DELAY; timeout++)
+ {
+ regval = stm32_getreg(STM32_OTG_GRSTCTL);
+ if ((regval & OTG_GRSTCTL_CSRST) == 0)
+ {
+ break;
+ }
+ }
+
+ /* Wait for 3 PHY Clocks */
+
+ up_udelay(3);
+
+ /* Deactivate the power down */
+
+
+ /* Detection Enable when set
+ */
+
+ regval = OTG_GCCFG_PWRDWN;
+
+# ifdef CONFIG_USBDEV_VBUSSENSING
+ regval |= OTG_GCCFG_VBDEN;
+# endif
+
+
+ stm32_putreg(regval, STM32_OTG_GCCFG);
+ up_mdelay(20);
+
+ /* When VBUS sensing is not used we
+ * need to force the B session valid
+ */
+
+
+# ifndef CONFIG_USBDEV_VBUSSENSING
+ regval = stm32_getreg(STM32_OTG_GOTGCTL);
+ regval |= (OTG_GOTGCTL_BVALOEN | OTG_GOTGCTL_BVALOVAL);
+ stm32_putreg(regval, STM32_OTG_GOTGCTL);
+# endif
+
+
+ /* Force Device Mode */
+
+ regval = stm32_getreg(STM32_OTG_GUSBCFG);
+ regval &= ~OTG_GUSBCFG_FHMOD;
+ regval |= OTG_GUSBCFG_FDMOD;
+ stm32_putreg(regval, STM32_OTG_GUSBCFG);
+ up_mdelay(50);
+
+ /* Initialize device mode */
+ /* Restart the PHY Clock */
+
+ stm32_putreg(0, STM32_OTG_PCGCCTL);
+
+ /* Device configuration register */
+
+ regval = stm32_getreg(STM32_OTG_DCFG);
+ regval &= ~OTG_DCFG_PFIVL_MASK;
+ regval |= OTG_DCFG_PFIVL_80PCT;
+ stm32_putreg(regval, STM32_OTG_DCFG);
+
+ /* Set full speed PHY */
+
+ regval = stm32_getreg(STM32_OTG_DCFG);
+ regval &= ~OTG_DCFG_DSPD_MASK;
+ regval |= OTG_DCFG_DSPD_FS;
+ stm32_putreg(regval, STM32_OTG_DCFG);
+
+ /* Set Rx FIFO size */
+
+ stm32_putreg(STM32_RXFIFO_WORDS, STM32_OTG_GRXFSIZ);
+
+#if STM32_NENDPOINTS > 0
+ address = STM32_RXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF0_TX0FD_SHIFT) |
+ (STM32_EP0_TXFIFO_WORDS << OTG_DIEPTXF0_TX0FSA_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF0);
+#endif
+
+#if STM32_NENDPOINTS > 1
+ address += STM32_EP0_TXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) |
+ (STM32_EP1_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF(1));
+#endif
+
+#if STM32_NENDPOINTS > 2
+ address += STM32_EP1_TXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) |
+ (STM32_EP2_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF(2));
+#endif
+
+#if STM32_NENDPOINTS > 3
+ address += STM32_EP2_TXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) |
+ (STM32_EP3_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF(3));
+#endif
+
+#if STM32_NENDPOINTS > 4
+ address += STM32_EP3_TXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) |
+ (STM32_EP4_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF(4));
+#endif
+
+#if STM32_NENDPOINTS > 5
+ address += STM32_EP4_TXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) |
+ (STM32_EP5_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF(5));
+#endif
+
+#if STM32_NENDPOINTS > 6
+ address += STM32_EP5_TXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) |
+ (STM32_EP6_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF(6));
+#endif
+
+#if STM32_NENDPOINTS > 7
+ address += STM32_EP6_TXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) |
+ (STM32_EP7_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF(7));
+#endif
+
+#if STM32_NENDPOINTS > 8
+ address += STM32_EP7_TXFIFO_WORDS;
+ regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) |
+ (STM32_EP8_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT);
+ stm32_putreg(regval, STM32_OTG_DIEPTXF(8));
+#endif
+
+ /* Flush the FIFOs */
+
+ stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_DALL);
+ stm32_rxfifo_flush();
+
+ /* Clear all pending Device Interrupts */
+
+ stm32_putreg(0, STM32_OTG_DIEPMSK);
+ stm32_putreg(0, STM32_OTG_DOEPMSK);
+ stm32_putreg(0, STM32_OTG_DIEPEMPMSK);
+ stm32_putreg(0xffffffff, STM32_OTG_DAINT);
+ stm32_putreg(0, STM32_OTG_DAINTMSK);
+
+ /* Configure all IN endpoints */
+
+ for (i = 0; i < STM32_NENDPOINTS; i++)
+ {
+ regval = stm32_getreg(STM32_OTG_DIEPCTL(i));
+ if ((regval & OTG_DIEPCTL_EPENA) != 0)
+ {
+ /* The endpoint is already enabled */
+
+ regval = OTG_DIEPCTL_EPENA | OTG_DIEPCTL_SNAK;
+ }
+ else
+ {
+ regval = 0;
+ }
+
+ stm32_putreg(regval, STM32_OTG_DIEPCTL(i));
+ stm32_putreg(0, STM32_OTG_DIEPTSIZ(i));
+ stm32_putreg(0xff, STM32_OTG_DIEPINT(i));
+ }
+
+ /* Configure all OUT endpoints */
+
+ for (i = 0; i < STM32_NENDPOINTS; i++)
+ {
+ regval = stm32_getreg(STM32_OTG_DOEPCTL(i));
+ if ((regval & OTG_DOEPCTL_EPENA) != 0)
+ {
+ /* The endpoint is already enabled */
+
+ regval = OTG_DOEPCTL_EPENA | OTG_DOEPCTL_SNAK;
+ }
+ else
+ {
+ regval = 0;
+ }
+
+ stm32_putreg(regval, STM32_OTG_DOEPCTL(i));
+ stm32_putreg(0, STM32_OTG_DOEPTSIZ(i));
+ stm32_putreg(0xff, STM32_OTG_DOEPINT(i));
+ }
+
+ /* Disable all interrupts. */
+
+ stm32_putreg(0, STM32_OTG_GINTMSK);
+
+ /* Clear any pending USB_OTG Interrupts */
+
+ stm32_putreg(0xffffffff, STM32_OTG_GOTGINT);
+
+ /* Clear any pending interrupts */
+
+ stm32_putreg(0xbfffffff, STM32_OTG_GINTSTS);
+
+#if defined(CONFIG_STM32F7_OTGHS)
+ /* Disable the ULPI Clock enable in RCC AHB1 Register. This must
+ * be done because if both the ULPI and the FS PHY clock enable bits
+ * are set at the same time, the ARM never awakens from WFI due to
+ * some bug / errata in the chip.
+ */
+
+ regval = stm32_getreg(STM32_RCC_AHB1LPENR);
+ regval &= ~RCC_AHB1ENR_OTGULPIEN;
+ stm32_putreg(regval, STM32_RCC_AHB1LPENR);
+#endif
+
+ /* Enable the interrupts in the INTMSK */
+
+ regval = (OTG_GINT_RXFLVL | OTG_GINT_USBSUSP | OTG_GINT_ENUMDNE |
+ OTG_GINT_IEP | OTG_GINT_OEP | OTG_GINT_USBRST);
+
+#ifdef CONFIG_USBDEV_ISOCHRONOUS
+ regval |= (OTG_GINT_IISOIXFR | OTG_GINT_IISOOXFR);
+#endif
+
+#ifdef CONFIG_USBDEV_SOFINTERRUPT
+ regval |= OTG_GINT_SOF;
+#endif
+
+#ifdef CONFIG_USBDEV_VBUSSENSING
+ regval |= (OTG_GINT_OTG | OTG_GINT_SRQ);
+#endif
+
+#ifdef CONFIG_DEBUG_USB
+ regval |= OTG_GINT_MMIS;
+#endif
+
+ stm32_putreg(regval, STM32_OTG_GINTMSK);
+
+ /* Enable the USB global interrupt by setting GINTMSK in the global OTG
+ * AHB configuration register; Set the TXFELVL bit in the GAHBCFG
+ * register so that TxFIFO interrupts will occur when the TxFIFO is truly
+ * empty (not just half full).
+ */
+
+ stm32_putreg(OTG_GAHBCFG_GINTMSK | OTG_GAHBCFG_TXFELVL,
+ STM32_OTG_GAHBCFG);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_usbinitialize
+ *
+ * Description:
+ * Initialize USB hardware.
+ *
+ * Assumptions:
+ * - This function is called very early in the initialization sequence
+ * - PLL and GIO pin initialization is not performed here but should been in
+ * the low-level boot logic: PLL1 must be configured for operation at 48MHz
+ * and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB connect
+ * LED.
+ *
+ ****************************************************************************/
+
+void up_usbinitialize(void)
+{
+ /* At present, there is only a single OTG device support. Hence it is
+ * pre-allocated as g_otghsdev. However, in most code, the private data
+ * structure will be referenced using the 'priv' pointer (rather than the
+ * global data) in order to simplify any future support for multiple
+ * devices.
+ */
+
+ FAR struct stm32_usbdev_s *priv = &g_otghsdev;
+ int ret;
+
+ usbtrace(TRACE_DEVINIT, 0);
+
+ /* Here we assume that:
+ *
+ * 1. GPIOA and OTG peripheral clocking has already been enabled as part
+ * of the boot sequence.
+ * 2. Board-specific logic has already enabled other board specific GPIOs
+ * for things like soft pull-up, VBUS sensing, power controls, and over-
+ * current detection.
+ */
+
+ /* Configure OTG alternate function pins
+ */
+
+ stm32_configgpio(GPIO_OTG_DM);
+ stm32_configgpio(GPIO_OTG_DP);
+ stm32_configgpio(GPIO_OTG_ID); /* Only needed for OTG */
+
+ /* SOF output pin configuration is configurable. */
+
+#ifdef CONFIG_STM32F7_OTG_SOFOUTPUT
+ stm32_configgpio(GPIO_OTG_SOF);
+#endif
+
+ /* Uninitialize the hardware so that we know that we are starting from a
+ * known state. */
+
+ up_usbuninitialize();
+
+ /* Initialie the driver data structure */
+
+ stm32_swinitialize(priv);
+
+ /* Attach the OTG interrupt handler */
+
+ ret = irq_attach(STM32_IRQ_OTG, stm32_usbinterrupt);
+ if (ret < 0)
+ {
+ uerr("irq_attach failed\n", ret);
+ goto errout;
+ }
+
+ /* Initialize the USB OTG core */
+
+ stm32_hwinitialize(priv);
+
+ /* Disconnect device */
+
+ stm32_pullup(&priv->usbdev, false);
+
+ /* Reset/Re-initialize the USB hardware */
+
+ stm32_usbreset(priv);
+
+ /* Enable USB controller interrupts at the NVIC */
+
+ up_enable_irq(STM32_IRQ_OTG);
+
+#ifdef CONFIG_ARCH_IRQPRIO
+ /* Set the interrupt priority */
+
+ up_prioritize_irq(STM32_IRQ_OTG, CONFIG_OTG_PRI);
+#endif
+ return;
+
+errout:
+ up_usbuninitialize();
+}
+
+/****************************************************************************
+ * Name: up_usbuninitialize
+ ****************************************************************************/
+
+void up_usbuninitialize(void)
+{
+ /* At present, there is only a single OTG device support. Hence it is
+ * pre-allocated as g_otghsdev. However, in most code, the private data
+ * structure will be referenced using the 'priv' pointer (rather than the
+ * global data) in order to simplify any future support for multiple devices.
+ */
+
+ FAR struct stm32_usbdev_s *priv = &g_otghsdev;
+ irqstate_t flags;
+ int i;
+
+ usbtrace(TRACE_DEVUNINIT, 0);
+
+ if (priv->driver)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVERREGISTERED), 0);
+ usbdev_unregister(priv->driver);
+ }
+
+ /* Disconnect device */
+
+ flags = enter_critical_section();
+ stm32_pullup(&priv->usbdev, false);
+ priv->usbdev.speed = USB_SPEED_UNKNOWN;
+
+ /* Disable and detach IRQs */
+
+ up_disable_irq(STM32_IRQ_OTG);
+ irq_detach(STM32_IRQ_OTG);
+
+ /* Disable all endpoint interrupts */
+
+ for (i = 0; i < STM32_NENDPOINTS; i++)
+ {
+ stm32_putreg(0xff, STM32_OTG_DIEPINT(i));
+ stm32_putreg(0xff, STM32_OTG_DOEPINT(i));
+ }
+
+ stm32_putreg(0, STM32_OTG_DIEPMSK);
+ stm32_putreg(0, STM32_OTG_DOEPMSK);
+ stm32_putreg(0, STM32_OTG_DIEPEMPMSK);
+ stm32_putreg(0, STM32_OTG_DAINTMSK);
+ stm32_putreg(0xffffffff, STM32_OTG_DAINT);
+
+ /* Flush the FIFOs */
+
+ stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_DALL);
+ stm32_rxfifo_flush();
+
+ /* TODO: Turn off USB power and clocking */
+
+ priv->devstate = DEVSTATE_DEFAULT;
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: usbdev_register
+ *
+ * Description:
+ * Register a USB device class driver. The class driver's bind() method will be
+ * called to bind it to a USB device driver.
+ *
+ ****************************************************************************/
+
+int usbdev_register(struct usbdevclass_driver_s *driver)
+{
+ /* At present, there is only a single OTG device support. Hence it is
+ * pre-allocated as g_otghsdev. However, in most code, the private data
+ * structure will be referenced using the 'priv' pointer (rather than the
+ * global data) in order to simplify any future support for multiple devices.
+ */
+
+ FAR struct stm32_usbdev_s *priv = &g_otghsdev;
+ int ret;
+
+ usbtrace(TRACE_DEVREGISTER, 0);
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!driver || !driver->ops->bind || !driver->ops->unbind ||
+ !driver->ops->disconnect || !driver->ops->setup)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+
+ if (priv->driver)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVER), 0);
+ return -EBUSY;
+ }
+#endif
+
+ /* First hook up the driver */
+
+ priv->driver = driver;
+
+ /* Then bind the class driver */
+
+ ret = CLASS_BIND(driver, &priv->usbdev);
+ if (ret)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BINDFAILED), (uint16_t)-ret);
+ priv->driver = NULL;
+ }
+ else
+ {
+ /* Enable USB controller interrupts */
+
+ up_enable_irq(STM32_IRQ_OTG);
+
+ /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set
+ * the RS bit to enable the controller. It kind of makes sense
+ * to do this after the class has bound to us...
+ * GEN: This bug is really in the class driver. It should make the
+ * soft connect when it is ready to be enumerated. I have added
+ * that logic to the class drivers but left this logic here.
+ */
+
+ stm32_pullup(&priv->usbdev, true);
+ priv->usbdev.speed = USB_SPEED_FULL;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: usbdev_unregister
+ *
+ * Description:
+ * Un-register usbdev class driver.If the USB device is connected to a USB host,
+ * it will first disconnect(). The driver is also requested to unbind() and clean
+ * up any device state, before this procedure finally returns.
+ *
+ ****************************************************************************/
+
+int usbdev_unregister(struct usbdevclass_driver_s *driver)
+{
+ /* At present, there is only a single OTG device support. Hence it is
+ * pre-allocated as g_otghsdev. However, in most code, the private data
+ * structure will be referenced using the 'priv' pointer (rather than the
+ * global data) in order to simplify any future support for multiple devices.
+ */
+
+ FAR struct stm32_usbdev_s *priv = &g_otghsdev;
+ irqstate_t flags;
+
+ usbtrace(TRACE_DEVUNREGISTER, 0);
+
+#ifdef CONFIG_DEBUG_FEATURES
+ if (driver != priv->driver)
+ {
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
+ return -EINVAL;
+ }
+#endif
+
+ /* Reset the hardware and cancel all requests. All requests must be
+ * canceled while the class driver is still bound.
+ */
+
+ flags = enter_critical_section();
+ stm32_usbreset(priv);
+ leave_critical_section(flags);
+
+ /* Unbind the class driver */
+
+ CLASS_UNBIND(driver, &priv->usbdev);
+
+ /* Disable USB controller interrupts */
+
+ flags = enter_critical_section();
+ up_disable_irq(STM32_IRQ_OTG);
+
+ /* Disconnect device */
+
+ stm32_pullup(&priv->usbdev, false);
+
+ /* Unhook the driver */
+
+ priv->driver = NULL;
+ leave_critical_section(flags);
+
+ return OK;
+}
+
+#endif /* CONFIG_USBDEV && CONFIG_STM32F7_OTGDEV */
diff --git a/arch/arm/src/stm32f7/stm32_otghost.c b/arch/arm/src/stm32f7/stm32_otghost.c
new file mode 100644
index 0000000000000000000000000000000000000000..69ac3fbe6875e1ad748c87f9c639d32e4bf32f98
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_otghost.c
@@ -0,0 +1,5304 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_otghost.c
+ *
+ * Copyright (C) 2012-2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "chip.h" /* Includes default GPIO settings */
+#include /* May redefine GPIO settings */
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "stm32_otg.h"
+
+#if defined(CONFIG_USBHOST) && defined(CONFIG_STM32F7_OTGFS)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+/* STM32 USB OTG FS Host Driver Support
+ *
+ * Pre-requisites
+ *
+ * CONFIG_USBHOST - Enable general USB host support
+ * CONFIG_STM32F7_OTGFS - Enable the STM32 USB OTG FS block
+ * CONFIG_STM32F7_SYSCFG - Needed
+ *
+ * Options:
+ *
+ * CONFIG_STM32F7_OTG_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words.
+ * Default 128 (512 bytes)
+ * CONFIG_STM32F7_OTG_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO
+ * in 32-bit words. Default 96 (384 bytes)
+ * CONFIG_STM32F7_OTG_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit
+ * words. Default 96 (384 bytes)
+ * CONFIG_STM32F7_OTG_DESCSIZE - Maximum size of a descriptor. Default: 128
+ * CONFIG_STM32F7_OTG_SOFINTR - Enable SOF interrupts. Why would you ever
+ * want to do that?
+ * CONFIG_STM32F7_USBHOST_REGDEBUG - Enable very low-level register access
+ * debug. Depends on CONFIG_DEBUG_FEATURES.
+ * CONFIG_STM32F7_USBHOST_PKTDUMP - Dump all incoming and outgoing USB
+ * packets. Depends on CONFIG_DEBUG_FEATURES.
+ */
+
+/* Pre-requisites (partial) */
+
+#ifndef CONFIG_STM32F7_SYSCFG
+# error "CONFIG_STM32F7_SYSCFG is required"
+#endif
+
+/* Default RxFIFO size */
+
+#ifndef CONFIG_STM32F7_OTG_RXFIFO_SIZE
+# define CONFIG_STM32F7_OTG_RXFIFO_SIZE 128
+#endif
+
+/* Default host non-periodic Tx FIFO size */
+
+#ifndef CONFIG_STM32F7_OTG_NPTXFIFO_SIZE
+# define CONFIG_STM32F7_OTG_NPTXFIFO_SIZE 96
+#endif
+
+/* Default host periodic Tx fifo size register */
+
+#ifndef CONFIG_STM32F7_OTG_PTXFIFO_SIZE
+# define CONFIG_STM32F7_OTG_PTXFIFO_SIZE 96
+#endif
+
+/* Maximum size of a descriptor */
+
+#ifndef CONFIG_STM32F7_OTG_DESCSIZE
+# define CONFIG_STM32F7_OTG_DESCSIZE 128
+#endif
+
+/* Register/packet debug depends on CONFIG_DEBUG_FEATURES */
+
+#ifndef CONFIG_DEBUG_FEATURES
+# undef CONFIG_STM32F7_USBHOST_REGDEBUG
+# undef CONFIG_STM32F7_USBHOST_PKTDUMP
+#endif
+
+/* HCD Setup ****************************************************************/
+/* Hardware capabilities */
+
+#define STM32_NHOST_CHANNELS 8 /* Number of host channels */
+#define STM32_MAX_PACKET_SIZE 64 /* Full speed max packet size */
+#define STM32_EP0_DEF_PACKET_SIZE 8 /* EP0 default packet size */
+#define STM32_EP0_MAX_PACKET_SIZE 64 /* EP0 FS max packet size */
+#define STM32_MAX_TX_FIFOS 15 /* Max number of TX FIFOs */
+#define STM32_MAX_PKTCOUNT 256 /* Max packet count */
+#define STM32_RETRY_COUNT 3 /* Number of ctrl transfer retries */
+
+/* Delays *******************************************************************/
+
+#define STM32_READY_DELAY 200000 /* In loop counts */
+#define STM32_FLUSH_DELAY 200000 /* In loop counts */
+#define STM32_SETUP_DELAY SEC2TICK(5) /* 5 seconds in system ticks */
+#define STM32_DATANAK_DELAY SEC2TICK(5) /* 5 seconds in system ticks */
+
+/* Ever-present MIN/MAX macros */
+
+#ifndef MIN
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+# define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* The following enumeration represents the various states of the USB host
+ * state machine (for debug purposes only)
+ */
+
+enum stm32_smstate_e
+{
+ SMSTATE_DETACHED = 0, /* Not attached to a device */
+ SMSTATE_ATTACHED, /* Attached to a device */
+ SMSTATE_ENUM, /* Attached, enumerating */
+ SMSTATE_CLASS_BOUND, /* Enumeration complete, class bound */
+};
+
+/* This enumeration provides the reason for the channel halt. */
+
+enum stm32_chreason_e
+{
+ CHREASON_IDLE = 0, /* Inactive (initial state) */
+ CHREASON_FREED, /* Channel is no longer in use */
+ CHREASON_XFRC, /* Transfer complete */
+ CHREASON_NAK, /* NAK received */
+ CHREASON_NYET, /* NotYet received */
+ CHREASON_STALL, /* Endpoint stalled */
+ CHREASON_TXERR, /* Transfer error received */
+ CHREASON_DTERR, /* Data toggle error received */
+ CHREASON_FRMOR, /* Frame overrun */
+ CHREASON_CANCELLED /* Transfer cancelled */
+};
+
+/* This structure retains the state of one host channel. NOTE: Since there
+ * is only one channel operation active at a time, some of the fields in
+ * in the structure could be moved in struct stm32_ubhost_s to achieve
+ * some memory savings.
+ */
+
+struct stm32_chan_s
+{
+ sem_t waitsem; /* Channel wait semaphore */
+ volatile uint8_t result; /* The result of the transfer */
+ volatile uint8_t chreason; /* Channel halt reason. See enum stm32_chreason_e */
+ uint8_t chidx; /* Channel index */
+ uint8_t epno; /* Device endpoint number (0-127) */
+ uint8_t eptype; /* See OTG_EPTYPE_* definitions */
+ uint8_t funcaddr; /* Device function address */
+ uint8_t speed; /* Device speed */
+ uint8_t pid; /* Data PID */
+ uint8_t npackets; /* Number of packets (for data toggle) */
+ bool inuse; /* True: This channel is "in use" */
+ volatile bool indata1; /* IN data toggle. True: DATA01 (Bulk and INTR only) */
+ volatile bool outdata1; /* OUT data toggle. True: DATA01 */
+ bool in; /* True: IN endpoint */
+ volatile bool waiter; /* True: Thread is waiting for a channel event */
+ uint16_t maxpacket; /* Max packet size */
+ uint16_t buflen; /* Buffer length (at start of transfer) */
+ volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */
+ volatile uint16_t inflight; /* Number of Tx bytes "in-flight" */
+ FAR uint8_t *buffer; /* Transfer buffer pointer */
+#ifdef CONFIG_USBHOST_ASYNCH
+ usbhost_asynch_t callback; /* Transfer complete callback */
+ FAR void *arg; /* Argument that accompanies the callback */
+#endif
+};
+
+/* A channel represents on uni-directional endpoint. So, in the case of the
+ * bi-directional, control endpoint, there must be two channels to represent
+ * the endpoint.
+ */
+
+struct stm32_ctrlinfo_s
+{
+ uint8_t inndx; /* EP0 IN control channel index */
+ uint8_t outndx; /* EP0 OUT control channel index */
+};
+
+/* This structure retains the state of the USB host controller */
+
+struct stm32_usbhost_s
+{
+ /* Common device fields. This must be the first thing defined in the
+ * structure so that it is possible to simply cast from struct usbhost_s
+ * to structstm32_usbhost_s.
+ */
+
+ struct usbhost_driver_s drvr;
+
+ /* This is the hub port description understood by class drivers */
+
+ struct usbhost_roothubport_s rhport;
+
+ /* Overall driver status */
+
+ volatile uint8_t smstate; /* The state of the USB host state machine */
+ uint8_t chidx; /* ID of channel waiting for space in Tx FIFO */
+ volatile bool connected; /* Connected to device */
+ volatile bool change; /* Connection change */
+ volatile bool pscwait; /* True: Thread is waiting for a port event */
+ sem_t exclsem; /* Support mutually exclusive access */
+ sem_t pscsem; /* Semaphore to wait for a port event */
+ struct stm32_ctrlinfo_s ep0; /* Root hub port EP0 description */
+
+#ifdef CONFIG_USBHOST_HUB
+ /* Used to pass external hub port events */
+
+ volatile struct usbhost_hubport_s *hport;
+#endif
+
+ /* The state of each host channel */
+
+ struct stm32_chan_s chan[STM32_MAX_TX_FIFOS];
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Register operations ******************************************************/
+
+#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG
+static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite);
+static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite);
+static uint32_t stm32_getreg(uint32_t addr);
+static void stm32_putreg(uint32_t addr, uint32_t value);
+#else
+# define stm32_getreg(addr) getreg32(addr)
+# define stm32_putreg(addr,val) putreg32(val,addr)
+#endif
+
+static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits,
+ uint32_t setbits);
+
+#ifdef CONFIG_STM32F7_USBHOST_PKTDUMP
+# define stm32_pktdump(m,b,n) lib_dumpbuffer(m,b,n)
+#else
+# define stm32_pktdump(m,b,n)
+#endif
+
+/* Semaphores ***************************************************************/
+
+static void stm32_takesem(sem_t *sem);
+#define stm32_givesem(s) sem_post(s);
+
+/* Byte stream access helper functions **************************************/
+
+static inline uint16_t stm32_getle16(const uint8_t *val);
+
+/* Channel management *******************************************************/
+
+static int stm32_chan_alloc(FAR struct stm32_usbhost_s *priv);
+static inline void stm32_chan_free(FAR struct stm32_usbhost_s *priv, int chidx);
+static inline void stm32_chan_freeall(FAR struct stm32_usbhost_s *priv);
+static void stm32_chan_configure(FAR struct stm32_usbhost_s *priv, int chidx);
+static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx,
+ enum stm32_chreason_e chreason);
+static int stm32_chan_waitsetup(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan);
+#ifdef CONFIG_USBHOST_ASYNCH
+static int stm32_chan_asynchsetup(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan,
+ usbhost_asynch_t callback, FAR void *arg);
+#endif
+static int stm32_chan_wait(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan);
+static void stm32_chan_wakeup(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan);
+static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv,
+ uint8_t epno, uint8_t funcaddr, uint8_t speed,
+ FAR struct stm32_ctrlinfo_s *ctrlep);
+static int stm32_ctrlep_alloc(FAR struct stm32_usbhost_s *priv,
+ FAR const struct usbhost_epdesc_s *epdesc,
+ FAR usbhost_ep_t *ep);
+static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv,
+ FAR const struct usbhost_epdesc_s *epdesc,
+ FAR usbhost_ep_t *ep);
+
+/* Control/data transfer logic **********************************************/
+
+static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx);
+#if 0 /* Not used */
+static inline uint16_t stm32_getframe(void);
+#endif
+static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_ctrlinfo_s *ep0,
+ FAR const struct usb_ctrlreq_s *req);
+static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_ctrlinfo_s *ep0,
+ FAR uint8_t *buffer, unsigned int buflen);
+static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_ctrlinfo_s *ep0,
+ FAR uint8_t *buffer, unsigned int buflen);
+static int stm32_in_setup(FAR struct stm32_usbhost_s *priv, int chidx);
+static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen);
+#ifdef CONFIG_USBHOST_ASYNCH
+static void stm32_in_next(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan);
+static int stm32_in_asynch(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen,
+ usbhost_asynch_t callback, FAR void *arg);
+#endif
+static int stm32_out_setup(FAR struct stm32_usbhost_s *priv, int chidx);
+static ssize_t stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen);
+#ifdef CONFIG_USBHOST_ASYNCH
+static void stm32_out_next(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan);
+static int stm32_out_asynch(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen,
+ usbhost_asynch_t callback, FAR void *arg);
+#endif
+
+/* Interrupt handling *******************************************************/
+/* Lower level interrupt handlers */
+
+static void stm32_gint_wrpacket(FAR struct stm32_usbhost_s *priv,
+ FAR uint8_t *buffer, int chidx, int buflen);
+static inline void stm32_gint_hcinisr(FAR struct stm32_usbhost_s *priv,
+ int chidx);
+static inline void stm32_gint_hcoutisr(FAR struct stm32_usbhost_s *priv,
+ int chidx);
+static void stm32_gint_connected(FAR struct stm32_usbhost_s *priv);
+static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv);
+
+/* Second level interrupt handlers */
+
+#ifdef CONFIG_STM32F7_OTG_SOFINTR
+static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv);
+#endif
+static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv);
+static inline void stm32_gint_nptxfeisr(FAR struct stm32_usbhost_s *priv);
+static inline void stm32_gint_ptxfeisr(FAR struct stm32_usbhost_s *priv);
+static inline void stm32_gint_hcisr(FAR struct stm32_usbhost_s *priv);
+static inline void stm32_gint_hprtisr(FAR struct stm32_usbhost_s *priv);
+static inline void stm32_gint_discisr(FAR struct stm32_usbhost_s *priv);
+static inline void stm32_gint_ipxfrisr(FAR struct stm32_usbhost_s *priv);
+
+/* First level, global interrupt handler */
+
+static int stm32_gint_isr(int irq, FAR void *context);
+
+/* Interrupt controls */
+
+static void stm32_gint_enable(void);
+static void stm32_gint_disable(void);
+static inline void stm32_hostinit_enable(void);
+static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx);
+
+/* USB host controller operations *******************************************/
+
+static int stm32_wait(FAR struct usbhost_connection_s *conn,
+ FAR struct usbhost_hubport_s **hport);
+static int stm32_rh_enumerate(FAR struct stm32_usbhost_s *priv,
+ FAR struct usbhost_connection_s *conn,
+ FAR struct usbhost_hubport_s *hport);
+static int stm32_enumerate(FAR struct usbhost_connection_s *conn,
+ FAR struct usbhost_hubport_s *hport);
+
+static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr,
+ usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed,
+ uint16_t maxpacketsize);
+static int stm32_epalloc(FAR struct usbhost_driver_s *drvr,
+ FAR const FAR struct usbhost_epdesc_s *epdesc,
+ FAR usbhost_ep_t *ep);
+static int stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
+static int stm32_alloc(FAR struct usbhost_driver_s *drvr,
+ FAR uint8_t **buffer, FAR size_t *maxlen);
+static int stm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
+static int stm32_ioalloc(FAR struct usbhost_driver_s *drvr,
+ FAR uint8_t **buffer, size_t buflen);
+static int stm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
+static int stm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
+ const struct usb_ctrlreq_s *req,
+ FAR uint8_t *buffer);
+static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR const uint8_t *buffer);
+static ssize_t stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
+ FAR uint8_t *buffer, size_t buflen);
+#ifdef CONFIG_USBHOST_ASYNCH
+static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
+ FAR uint8_t *buffer, size_t buflen,
+ usbhost_asynch_t callback, FAR void *arg);
+#endif
+static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
+#ifdef CONFIG_USBHOST_HUB
+static int stm32_connect(FAR struct usbhost_driver_s *drvr,
+ FAR struct usbhost_hubport_s *hport,
+ bool connected);
+#endif
+static void stm32_disconnect(FAR struct usbhost_driver_s *drvr,
+ FAR struct usbhost_hubport_s *hport);
+
+/* Initialization ***********************************************************/
+
+static void stm32_portreset(FAR struct stm32_usbhost_s *priv);
+static void stm32_flush_txfifos(uint32_t txfnum);
+static void stm32_flush_rxfifo(void);
+static void stm32_vbusdrive(FAR struct stm32_usbhost_s *priv, bool state);
+static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv);
+
+static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv);
+static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* In this driver implementation, support is provided for only a single a single
+ * USB device. All status information can be simply retained in a single global
+ * instance.
+ */
+
+static struct stm32_usbhost_s g_usbhost;
+
+/* This is the connection/enumeration interface */
+
+static struct usbhost_connection_s g_usbconn =
+{
+ .wait = stm32_wait,
+ .enumerate = stm32_enumerate,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_printreg
+ *
+ * Description:
+ * Print the contents of an STM32xx register operation
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG
+static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite)
+{
+ llerr("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_checkreg
+ *
+ * Description:
+ * Get the contents of an STM32 register
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG
+static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite)
+{
+ static uint32_t prevaddr = 0;
+ static uint32_t preval = 0;
+ static uint32_t count = 0;
+ static bool prevwrite = false;
+
+ /* Is this the same value that we read from/wrote to the same register last time?
+ * Are we polling the register? If so, suppress the output.
+ */
+
+ if (addr == prevaddr && val == preval && prevwrite == iswrite)
+ {
+ /* Yes.. Just increment the count */
+
+ count++;
+ }
+ else
+ {
+ /* No this is a new address or value or operation. Were there any
+ * duplicate accesses before this one?
+ */
+
+ if (count > 0)
+ {
+ /* Yes.. Just one? */
+
+ if (count == 1)
+ {
+ /* Yes.. Just one */
+
+ stm32_printreg(prevaddr, preval, prevwrite);
+ }
+ else
+ {
+ /* No.. More than one. */
+
+ llerr("[repeats %d more times]\n", count);
+ }
+ }
+
+ /* Save the new address, value, count, and operation for next time */
+
+ prevaddr = addr;
+ preval = val;
+ count = 0;
+ prevwrite = iswrite;
+
+ /* Show the new regisgter access */
+
+ stm32_printreg(addr, val, iswrite);
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_getreg
+ *
+ * Description:
+ * Get the contents of an STM32 register
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG
+static uint32_t stm32_getreg(uint32_t addr)
+{
+ /* Read the value from the register */
+
+ uint32_t val = getreg32(addr);
+
+ /* Check if we need to print this value */
+
+ stm32_checkreg(addr, val, false);
+ return val;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_putreg
+ *
+ * Description:
+ * Set the contents of an STM32 register to a value
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG
+static void stm32_putreg(uint32_t addr, uint32_t val)
+{
+ /* Check if we need to print this value */
+
+ stm32_checkreg(addr, val, true);
+
+ /* Write the value */
+
+ putreg32(val, addr);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_modifyreg
+ *
+ * Description:
+ * Modify selected bits of an STM32 register.
+ *
+ ****************************************************************************/
+
+static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits,
+ uint32_t setbits)
+{
+ stm32_putreg(addr, (((stm32_getreg(addr)) & ~clrbits) | setbits));
+}
+
+/****************************************************************************
+ * Name: stm32_takesem
+ *
+ * Description:
+ * This is just a wrapper to handle the annoying behavior of semaphore
+ * waits that return due to the receipt of a signal.
+ *
+ ****************************************************************************/
+
+static void stm32_takesem(sem_t *sem)
+{
+ /* Take the semaphore (perhaps waiting) */
+
+ while (sem_wait(sem) != 0)
+ {
+ /* The only case that an error should occr here is if the wait was
+ * awakened by a signal.
+ */
+
+ ASSERT(errno == EINTR);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_getle16
+ *
+ * Description:
+ * Get a (possibly unaligned) 16-bit little endian value.
+ *
+ ****************************************************************************/
+
+static inline uint16_t stm32_getle16(const uint8_t *val)
+{
+ return (uint16_t)val[1] << 8 | (uint16_t)val[0];
+}
+
+/****************************************************************************
+ * Name: stm32_chan_alloc
+ *
+ * Description:
+ * Allocate a channel.
+ *
+ ****************************************************************************/
+
+static int stm32_chan_alloc(FAR struct stm32_usbhost_s *priv)
+{
+ int chidx;
+
+ /* Search the table of channels */
+
+ for (chidx = 0; chidx < STM32_NHOST_CHANNELS; chidx++)
+ {
+ /* Is this channel available? */
+
+ if (!priv->chan[chidx].inuse)
+ {
+ /* Yes... make it "in use" and return the index */
+
+ priv->chan[chidx].inuse = true;
+ return chidx;
+ }
+ }
+
+ /* All of the channels are "in-use" */
+
+ return -EBUSY;
+}
+
+/****************************************************************************
+ * Name: stm32_chan_free
+ *
+ * Description:
+ * Free a previoiusly allocated channel.
+ *
+ ****************************************************************************/
+
+static void stm32_chan_free(FAR struct stm32_usbhost_s *priv, int chidx)
+{
+ DEBUGASSERT((unsigned)chidx < STM32_NHOST_CHANNELS);
+
+ /* Halt the channel */
+
+ stm32_chan_halt(priv, chidx, CHREASON_FREED);
+
+ /* Mark the channel available */
+
+ priv->chan[chidx].inuse = false;
+}
+
+/****************************************************************************
+ * Name: stm32_chan_freeall
+ *
+ * Description:
+ * Free all channels.
+ *
+ ****************************************************************************/
+
+static inline void stm32_chan_freeall(FAR struct stm32_usbhost_s *priv)
+{
+ uint8_t chidx;
+
+ /* Free all host channels */
+
+ for (chidx = 2; chidx < STM32_NHOST_CHANNELS; chidx ++)
+ {
+ stm32_chan_free(priv, chidx);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_chan_configure
+ *
+ * Description:
+ * Configure or re-configure a host channel. Host channels are configured
+ * when endpoint is allocated and EP0 (only) is re-configured with the
+ * max packet size or device address changes.
+ *
+ ****************************************************************************/
+
+static void stm32_chan_configure(FAR struct stm32_usbhost_s *priv, int chidx)
+{
+ FAR struct stm32_chan_s *chan = &priv->chan[chidx];
+ uint32_t regval;
+
+ /* Clear any old pending interrupts for this host channel. */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), 0xffffffff);
+
+ /* Enable channel interrupts required for transfers on this channel. */
+
+ regval = 0;
+
+ switch (chan->eptype)
+ {
+ case OTG_EPTYPE_CTRL:
+ case OTG_EPTYPE_BULK:
+ {
+#ifdef HAVE_USBHOST_TRACE_VERBOSE
+ uint16_t intrace;
+ uint16_t outtrace;
+
+ /* Determine the definitive trace ID to use below */
+
+ if (chan->eptype == OTG_EPTYPE_CTRL)
+ {
+ intrace = OTG_VTRACE2_CHANCONF_CTRL_IN;
+ outtrace = OTG_VTRACE2_CHANCONF_CTRL_OUT;
+ }
+ else
+ {
+ intrace = OTG_VTRACE2_CHANCONF_BULK_IN;
+ outtrace = OTG_VTRACE2_CHANCONF_BULK_OUT;
+ }
+#endif
+
+ /* Interrupts required for CTRL and BULK endpoints */
+
+ regval |= (OTG_HCINT_XFRC | OTG_HCINT_STALL | OTG_HCINT_NAK |
+ OTG_HCINT_TXERR | OTG_HCINT_DTERR);
+
+ /* Additional setting for IN/OUT endpoints */
+
+ if (chan->in)
+ {
+ usbhost_vtrace2(intrace, chidx, chan->epno);
+ regval |= OTG_HCINT_BBERR;
+ }
+ else
+ {
+ usbhost_vtrace2(outtrace, chidx, chan->epno);
+ regval |= OTG_HCINT_NYET;
+ }
+ }
+ break;
+
+ case OTG_EPTYPE_INTR:
+ {
+ /* Interrupts required for INTR endpoints */
+
+ regval |= (OTG_HCINT_XFRC | OTG_HCINT_STALL | OTG_HCINT_NAK |
+ OTG_HCINT_TXERR | OTG_HCINT_FRMOR | OTG_HCINT_DTERR);
+
+ /* Additional setting for IN endpoints */
+
+ if (chan->in)
+ {
+ usbhost_vtrace2(OTG_VTRACE2_CHANCONF_INTR_IN, chidx,
+ chan->epno);
+ regval |= OTG_HCINT_BBERR;
+ }
+#ifdef HAVE_USBHOST_TRACE_VERBOSE
+ else
+ {
+ usbhost_vtrace2(OTG_VTRACE2_CHANCONF_INTR_OUT, chidx,
+ chan->epno);
+ }
+#endif
+ }
+ break;
+
+ case OTG_EPTYPE_ISOC:
+ {
+ /* Interrupts required for ISOC endpoints */
+
+ regval |= (OTG_HCINT_XFRC | OTG_HCINT_ACK | OTG_HCINT_FRMOR);
+
+ /* Additional setting for IN endpoints */
+
+ if (chan->in)
+ {
+ usbhost_vtrace2(OTG_VTRACE2_CHANCONF_ISOC_IN, chidx,
+ chan->epno);
+ regval |= (OTG_HCINT_TXERR | OTG_HCINT_BBERR);
+ }
+#ifdef HAVE_USBHOST_TRACE_VERBOSE
+ else
+ {
+ usbhost_vtrace2(OTG_VTRACE2_CHANCONF_ISOC_OUT, chidx,
+ chan->epno);
+ }
+#endif
+ }
+ break;
+ }
+
+ stm32_putreg(STM32_OTG_HCINTMSK(chidx), regval);
+
+ /* Enable the top level host channel interrupt. */
+
+ stm32_modifyreg(STM32_OTG_HAINTMSK, 0, OTG_HAINT(chidx));
+
+ /* Make sure host channel interrupts are enabled. */
+
+ stm32_modifyreg(STM32_OTG_GINTMSK, 0, OTG_GINT_HC);
+
+ /* Program the HCCHAR register */
+
+ regval = ((uint32_t)chan->maxpacket << OTG_HCCHAR_MPSIZ_SHIFT) |
+ ((uint32_t)chan->epno << OTG_HCCHAR_EPNUM_SHIFT) |
+ ((uint32_t)chan->eptype << OTG_HCCHAR_EPTYP_SHIFT) |
+ ((uint32_t)chan->funcaddr << OTG_HCCHAR_DAD_SHIFT);
+
+ /* Special case settings for low speed devices */
+
+ if (chan->speed == USB_SPEED_LOW)
+ {
+ regval |= OTG_HCCHAR_LSDEV;
+ }
+
+ /* Special case settings for IN endpoints */
+
+ if (chan->in)
+ {
+ regval |= OTG_HCCHAR_EPDIR_IN;
+ }
+
+ /* Special case settings for INTR endpoints */
+
+ if (chan->eptype == OTG_EPTYPE_INTR)
+ {
+ regval |= OTG_HCCHAR_ODDFRM;
+ }
+
+ /* Write the channel configuration */
+
+ stm32_putreg(STM32_OTG_HCCHAR(chidx), regval);
+}
+
+/****************************************************************************
+ * Name: stm32_chan_halt
+ *
+ * Description:
+ * Halt the channel associated with 'chidx' by setting the CHannel DISable
+ * (CHDIS) bit in in the HCCHAR register.
+ *
+ ****************************************************************************/
+
+static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx,
+ enum stm32_chreason_e chreason)
+{
+ uint32_t hcchar;
+ uint32_t intmsk;
+ uint32_t eptype;
+ unsigned int avail;
+
+ /* Save the reason for the halt. We need this in the channel halt interrupt
+ * handling logic to know what to do next.
+ */
+
+ usbhost_vtrace2(OTG_VTRACE2_CHANHALT, chidx, chreason);
+
+ priv->chan[chidx].chreason = (uint8_t)chreason;
+
+ /* "The application can disable any channel by programming the OTG_FS_HCCHARx
+ * register with the CHDIS and CHENA bits set to 1. This enables the OTG_FS
+ * host to flush the posted requests (if any) and generates a channel halted
+ * interrupt. The application must wait for the CHH interrupt in OTG_FS_HCINTx
+ * before reallocating the channel for other transactions. The OTG_FS host
+ * does not interrupt the transaction that has already been started on the
+ * USB."
+ */
+
+ hcchar = stm32_getreg(STM32_OTG_HCCHAR(chidx));
+ hcchar |= (OTG_HCCHAR_CHDIS | OTG_HCCHAR_CHENA);
+
+ /* Get the endpoint type from the HCCHAR register */
+
+ eptype = hcchar & OTG_HCCHAR_EPTYP_MASK;
+
+ /* Check for space in the Tx FIFO to issue the halt.
+ *
+ * "Before disabling a channel, the application must ensure that there is at
+ * least one free space available in the non-periodic request queue (when
+ * disabling a non-periodic channel) or the periodic request queue (when
+ * disabling a periodic channel). The application can simply flush the
+ * posted requests when the Request queue is full (before disabling the
+ * channel), by programming the OTG_FS_HCCHARx register with the CHDIS bit
+ * set to 1, and the CHENA bit cleared to 0.
+ */
+
+ if (eptype == OTG_HCCHAR_EPTYP_CTRL || eptype == OTG_HCCHAR_EPTYP_BULK)
+ {
+ /* Get the number of words available in the non-periodic Tx FIFO. */
+
+ avail = stm32_getreg(STM32_OTG_HNPTXSTS) & OTG_HNPTXSTS_NPTXFSAV_MASK;
+ }
+ else /* if (eptype == OTG_HCCHAR_EPTYP_ISOC || eptype == OTG_HCCHAR_EPTYP_INTR) */
+ {
+ /* Get the number of words available in the non-periodic Tx FIFO. */
+
+ avail = stm32_getreg(STM32_OTG_HPTXSTS) & OTG_HPTXSTS_PTXFSAVL_MASK;
+ }
+
+ /* Check if there is any space available in the Tx FIFO. */
+
+ if (avail == 0)
+ {
+ /* The Tx FIFO is full... disable the channel to flush the requests */
+
+ hcchar &= ~OTG_HCCHAR_CHENA;
+ }
+
+ /* Unmask the CHannel Halted (CHH) interrupt */
+
+ intmsk = stm32_getreg(STM32_OTG_HCINTMSK(chidx));
+ intmsk |= OTG_HCINT_CHH;
+ stm32_putreg(STM32_OTG_HCINTMSK(chidx), intmsk);
+
+ /* Halt the channel by setting CHDIS (and maybe CHENA) in the HCCHAR */
+
+ stm32_putreg(STM32_OTG_HCCHAR(chidx), hcchar);
+}
+
+/****************************************************************************
+ * Name: stm32_chan_waitsetup
+ *
+ * Description:
+ * Set the request for the transfer complete event well BEFORE enabling
+ * the transfer (as soon as we are absolutely committed to the transfer).
+ * We do this to minimize race conditions. This logic would have to be
+ * expanded if we want to have more than one packet in flight at a time!
+ *
+ * Assumptions:
+ * Called from a normal thread context BEFORE the transfer has been started.
+ *
+ ****************************************************************************/
+
+static int stm32_chan_waitsetup(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan)
+{
+ irqstate_t flags = enter_critical_section();
+ int ret = -ENODEV;
+
+ /* Is the device still connected? */
+
+ if (priv->connected)
+ {
+ /* Yes.. then set waiter to indicate that we expect to be informed when
+ * either (1) the device is disconnected, or (2) the transfer completed.
+ */
+
+ chan->waiter = true;
+#ifdef CONFIG_USBHOST_ASYNCH
+ chan->callback = NULL;
+ chan->arg = NULL;
+#endif
+ ret = OK;
+ }
+
+ leave_critical_section(flags);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_chan_asynchsetup
+ *
+ * Description:
+ * Set the request for the transfer complete event well BEFORE enabling the
+ * transfer (as soon as we are absolutely committed to the to avoid transfer).
+ * We do this to minimize race conditions. This logic would have to be expanded
+ * if we want to have more than one packet in flight at a time!
+ *
+ * Assumptions:
+ * Might be called from the level of an interrupt handler
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST_ASYNCH
+static int stm32_chan_asynchsetup(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan,
+ usbhost_asynch_t callback, FAR void *arg)
+{
+ irqstate_t flags = enter_critical_section();
+ int ret = -ENODEV;
+
+ /* Is the device still connected? */
+
+ if (priv->connected)
+ {
+ /* Yes.. then set waiter to indicate that we expect to be informed when
+ * either (1) the device is disconnected, or (2) the transfer completed.
+ */
+
+ chan->waiter = false;
+ chan->callback = callback;
+ chan->arg = arg;
+ ret = OK;
+ }
+
+ leave_critical_section(flags);
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_chan_wait
+ *
+ * Description:
+ * Wait for a transfer on a channel to complete.
+ *
+ * Assumptions:
+ * Called from a normal thread context
+ *
+ ****************************************************************************/
+
+static int stm32_chan_wait(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan)
+{
+ irqstate_t flags;
+ int ret;
+
+ /* Disable interrupts so that the following operations will be atomic. On
+ * the OTG FS global interrupt needs to be disabled. However, here we
+ * disable all interrupts to exploit that fact that interrupts will be re-
+ * enabled while we wait.
+ */
+
+ flags = enter_critical_section();
+
+ /* Loop, testing for an end of transfer condition. The channel 'result'
+ * was set to EBUSY and 'waiter' was set to true before the transfer; 'waiter'
+ * will be set to false and 'result' will be set appropriately when the
+ * transfer is completed.
+ */
+
+ do
+ {
+ /* Wait for the transfer to complete. NOTE the transfer may already
+ * completed before we get here or the transfer may complete while we
+ * wait here.
+ */
+
+ ret = sem_wait(&chan->waitsem);
+
+ /* sem_wait should succeed. But it is possible that we could be
+ * awakened by a signal too.
+ */
+
+ DEBUGASSERT(ret == OK || get_errno() == EINTR);
+ }
+ while (chan->waiter);
+
+ /* The transfer is complete re-enable interrupts and return the result */
+
+ ret = -(int)chan->result;
+ leave_critical_section(flags);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_chan_wakeup
+ *
+ * Description:
+ * A channel transfer has completed... wakeup any threads waiting for the
+ * transfer to complete.
+ *
+ * Assumptions:
+ * This function is called from the transfer complete interrupt handler for
+ * the channel. Interrupts are disabled.
+ *
+ ****************************************************************************/
+
+static void stm32_chan_wakeup(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan)
+{
+ /* Is the transfer complete? */
+
+ if (chan->result != EBUSY)
+ {
+ /* Is there a thread waiting for this transfer to complete? */
+
+ if (chan->waiter)
+ {
+#ifdef CONFIG_USBHOST_ASYNCH
+ /* Yes.. there should not also be a callback scheduled */
+
+ DEBUGASSERT(chan->callback == NULL);
+#endif
+ /* Wake'em up! */
+
+ usbhost_vtrace2(chan->in ? OTG_VTRACE2_CHANWAKEUP_IN :
+ OTG_VTRACE2_CHANWAKEUP_OUT,
+ chan->epno, chan->result);
+
+ stm32_givesem(&chan->waitsem);
+ chan->waiter = false;
+ }
+
+#ifdef CONFIG_USBHOST_ASYNCH
+ /* No.. is an asynchronous callback expected when the transfer
+ * completes?
+ */
+
+ else if (chan->callback)
+ {
+ /* Handle continuation of IN/OUT pipes */
+
+ if (chan->in)
+ {
+ stm32_in_next(priv, chan);
+ }
+ else
+ {
+ stm32_out_next(priv, chan);
+ }
+ }
+#endif
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_ctrlchan_alloc
+ *
+ * Description:
+ * Allocate and configured channels for a control pipe.
+ *
+ ****************************************************************************/
+
+static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv,
+ uint8_t epno, uint8_t funcaddr, uint8_t speed,
+ FAR struct stm32_ctrlinfo_s *ctrlep)
+{
+ FAR struct stm32_chan_s *chan;
+ int inndx;
+ int outndx;
+
+ outndx = stm32_chan_alloc(priv);
+ if (outndx < 0)
+ {
+ return -ENOMEM;
+ }
+
+ ctrlep->outndx = outndx;
+ chan = &priv->chan[outndx];
+ chan->epno = epno;
+ chan->in = false;
+ chan->eptype = OTG_EPTYPE_CTRL;
+ chan->funcaddr = funcaddr;
+ chan->speed = speed;
+ chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
+ chan->indata1 = false;
+ chan->outdata1 = false;
+
+ /* Configure control OUT channels */
+
+ stm32_chan_configure(priv, outndx);
+
+ /* Allocate and initialize the control IN channel */
+
+ inndx = stm32_chan_alloc(priv);
+ if (inndx < 0)
+ {
+ stm32_chan_free(priv, outndx);
+ return -ENOMEM;
+ }
+
+ ctrlep->inndx = inndx;
+ chan = &priv->chan[inndx];
+ chan->epno = epno;
+ chan->in = true;
+ chan->eptype = OTG_EPTYPE_CTRL;
+ chan->funcaddr = funcaddr;
+ chan->speed = speed;
+ chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE;
+ chan->indata1 = false;
+ chan->outdata1 = false;
+
+ /* Configure control IN channels */
+
+ stm32_chan_configure(priv, inndx);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_ctrlep_alloc
+ *
+ * Description:
+ * Allocate a container and channels for control pipe.
+ *
+ * Input Parameters:
+ * priv - The private USB host driver state.
+ * epdesc - Describes the endpoint to be allocated.
+ * ep - A memory location provided by the caller in which to receive the
+ * allocated endpoint descriptor.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value
+ * is returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int stm32_ctrlep_alloc(FAR struct stm32_usbhost_s *priv,
+ FAR const struct usbhost_epdesc_s *epdesc,
+ FAR usbhost_ep_t *ep)
+{
+ FAR struct usbhost_hubport_s *hport;
+ FAR struct stm32_ctrlinfo_s *ctrlep;
+ int ret;
+
+ /* Sanity check. NOTE that this method should only be called if a device is
+ * connected (because we need a valid low speed indication).
+ */
+
+ DEBUGASSERT(epdesc->hport != NULL);
+ hport = epdesc->hport;
+
+ /* Allocate a container for the control endpoint */
+
+ ctrlep = (FAR struct stm32_ctrlinfo_s *)kmm_malloc(sizeof(struct stm32_ctrlinfo_s));
+ if (ctrlep == NULL)
+ {
+ uerr("ERROR: Failed to allocate control endpoint container\n");
+ return -ENOMEM;
+ }
+
+ /* Then allocate and configure the IN/OUT channnels */
+
+ ret = stm32_ctrlchan_alloc(priv, epdesc->addr & USB_EPNO_MASK,
+ hport->funcaddr, hport->speed, ctrlep);
+ if (ret < 0)
+ {
+ uerr("ERROR: stm32_ctrlchan_alloc failed: %d\n", ret);
+ kmm_free(ctrlep);
+ return ret;
+ }
+
+ /* Return a pointer to the control pipe container as the pipe "handle" */
+
+ *ep = (usbhost_ep_t)ctrlep;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_xfrep_alloc
+ *
+ * Description:
+ * Allocate and configure one unidirectional endpoint.
+ *
+ * Input Parameters:
+ * priv - The private USB host driver state.
+ * epdesc - Describes the endpoint to be allocated.
+ * ep - A memory location provided by the caller in which to receive the
+ * allocated endpoint descriptor.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value
+ * is returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv,
+ FAR const struct usbhost_epdesc_s *epdesc,
+ FAR usbhost_ep_t *ep)
+{
+ struct usbhost_hubport_s *hport;
+ FAR struct stm32_chan_s *chan;
+ int chidx;
+
+ /* Sanity check. NOTE that this method should only be called if a device is
+ * connected (because we need a valid low speed indication).
+ */
+
+ DEBUGASSERT(epdesc->hport != NULL);
+ hport = epdesc->hport;
+
+ /* Allocate a host channel for the endpoint */
+
+ chidx = stm32_chan_alloc(priv);
+ if (chidx < 0)
+ {
+ uerr("ERROR: Failed to allocate a host channel\n");
+ return -ENOMEM;
+ }
+
+ /* Decode the endpoint descriptor to initialize the channel data structures.
+ * Note: Here we depend on the fact that the endpoint point type is
+ * encoded in the same way in the endpoint descriptor as it is in the OTG
+ * HS hardware.
+ */
+
+ chan = &priv->chan[chidx];
+ chan->epno = epdesc->addr & USB_EPNO_MASK;
+ chan->in = epdesc->in;
+ chan->eptype = epdesc->xfrtype;
+ chan->funcaddr = hport->funcaddr;
+ chan->speed = hport->speed;
+ chan->maxpacket = epdesc->mxpacketsize;
+ chan->indata1 = false;
+ chan->outdata1 = false;
+
+ /* Then configure the endpoint */
+
+ stm32_chan_configure(priv, chidx);
+
+ /* Return the index to the allocated channel as the endpoint "handle" */
+
+ *ep = (usbhost_ep_t)chidx;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_transfer_start
+ *
+ * Description:
+ * Start at transfer on the select IN or OUT channel.
+ *
+ ****************************************************************************/
+
+static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx)
+{
+ FAR struct stm32_chan_s *chan;
+ uint32_t regval;
+ unsigned int npackets;
+ unsigned int maxpacket;
+ unsigned int avail;
+ unsigned int wrsize;
+ unsigned int minsize;
+
+ /* Set up the initial state of the transfer */
+
+ chan = &priv->chan[chidx];
+
+ usbhost_vtrace2(OTG_VTRACE2_STARTTRANSFER, chidx, chan->buflen);
+
+ chan->result = EBUSY;
+ chan->inflight = 0;
+ chan->xfrd = 0;
+ priv->chidx = chidx;
+
+ /* Compute the expected number of packets associated to the transfer.
+ * If the transfer length is zero (or less than the size of one maximum
+ * size packet), then one packet is expected.
+ */
+
+ /* If the transfer size is greater than one packet, then calculate the
+ * number of packets that will be received/sent, including any partial
+ * final packet.
+ */
+
+ maxpacket = chan->maxpacket;
+
+ if (chan->buflen > maxpacket)
+ {
+ npackets = (chan->buflen + maxpacket - 1) / maxpacket;
+
+ /* Clip if the buffer length if it exceeds the maximum number of
+ * packets that can be transferred (this should not happen).
+ */
+
+ if (npackets > STM32_MAX_PKTCOUNT)
+ {
+ npackets = STM32_MAX_PKTCOUNT;
+ chan->buflen = STM32_MAX_PKTCOUNT * maxpacket;
+ usbhost_trace2(OTG_TRACE2_CLIP, chidx, chan->buflen);
+ }
+ }
+ else
+ {
+ /* One packet will be sent/received (might be a zero length packet) */
+
+ npackets = 1;
+ }
+
+ /* If it is an IN transfer, then adjust the size of the buffer UP to
+ * a full number of packets. Hmmm... couldn't this cause an overrun
+ * into unallocated memory?
+ */
+
+#if 0 /* Think about this */
+ if (chan->in)
+ {
+ /* Force the buffer length to an even multiple of maxpacket */
+
+ chan->buflen = npackets * maxpacket;
+ }
+#endif
+
+ /* Save the number of packets in the transfer. We will need this in
+ * order to set the next data toggle correctly when the transfer
+ * completes.
+ */
+
+ chan->npackets = (uint8_t)npackets;
+
+ /* Setup the HCTSIZn register */
+
+ regval = ((uint32_t)chan->buflen << OTG_HCTSIZ_XFRSIZ_SHIFT) |
+ ((uint32_t)npackets << OTG_HCTSIZ_PKTCNT_SHIFT) |
+ ((uint32_t)chan->pid << OTG_HCTSIZ_DPID_SHIFT);
+ stm32_putreg(STM32_OTG_HCTSIZ(chidx), regval);
+
+ /* Setup the HCCHAR register: Frame oddness and host channel enable */
+
+ regval = stm32_getreg(STM32_OTG_HCCHAR(chidx));
+
+ /* Set/clear the Odd Frame bit. Check for an even frame; if so set Odd
+ * Frame. This field is applicable for only periodic (isochronous and
+ * interrupt) channels.
+ */
+
+ if ((stm32_getreg(STM32_OTG_HFNUM) & 1) == 0)
+ {
+ regval |= OTG_HCCHAR_ODDFRM;
+ }
+ else
+ {
+ regval &= ~OTG_HCCHAR_ODDFRM;
+ }
+
+ regval &= ~OTG_HCCHAR_CHDIS;
+ regval |= OTG_HCCHAR_CHENA;
+ stm32_putreg(STM32_OTG_HCCHAR(chidx), regval);
+
+ /* If this is an out transfer, then we need to do more.. we need to copy
+ * the outgoing data into the correct TxFIFO.
+ */
+
+ if (!chan->in && chan->buflen > 0)
+ {
+ /* Handle non-periodic (CTRL and BULK) OUT transfers differently than
+ * periodic (INTR and ISOC) OUT transfers.
+ */
+
+ minsize = MIN(chan->buflen, chan->maxpacket);
+
+ switch (chan->eptype)
+ {
+ case OTG_EPTYPE_CTRL: /* Non periodic transfer */
+ case OTG_EPTYPE_BULK:
+ {
+ /* Read the Non-periodic Tx FIFO status register */
+
+ regval = stm32_getreg(STM32_OTG_HNPTXSTS);
+ avail = ((regval & OTG_HNPTXSTS_NPTXFSAV_MASK) >> OTG_HNPTXSTS_NPTXFSAV_SHIFT) << 2;
+ }
+ break;
+
+ /* Periodic transfer */
+
+ case OTG_EPTYPE_INTR:
+ case OTG_EPTYPE_ISOC:
+ {
+ /* Read the Non-periodic Tx FIFO status register */
+
+ regval = stm32_getreg(STM32_OTG_HPTXSTS);
+ avail = ((regval & OTG_HPTXSTS_PTXFSAVL_MASK) >> OTG_HPTXSTS_PTXFSAVL_SHIFT) << 2;
+ }
+ break;
+
+ default:
+ DEBUGASSERT(false);
+ return;
+ }
+
+ /* Is there space in the TxFIFO to hold the minimum size packet? */
+
+ if (minsize <= avail)
+ {
+ /* Yes.. Get the size of the biggest thing that we can put in the Tx FIFO now */
+
+ wrsize = chan->buflen;
+ if (wrsize > avail)
+ {
+ /* Clip the write size to the number of full, max sized packets
+ * that will fit in the Tx FIFO.
+ */
+
+ unsigned int wrpackets = avail / chan->maxpacket;
+ wrsize = wrpackets * chan->maxpacket;
+ }
+
+ /* Write packet into the Tx FIFO. */
+
+ stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize);
+ }
+
+ /* Did we put the entire buffer into the Tx FIFO? */
+
+ if (chan->buflen > avail)
+ {
+ /* No, there was insufficient space to hold the entire transfer ...
+ * Enable the Tx FIFO interrupt to handle the transfer when the Tx
+ * FIFO becomes empty.
+ */
+
+ stm32_txfe_enable(priv, chidx);
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_getframe
+ *
+ * Description:
+ * Get the current frame number. The frame number (FRNUM) field increments
+ * when a new SOF is transmitted on the USB, and is cleared to 0 when it
+ * reaches 0x3fff.
+ *
+ ****************************************************************************/
+
+#if 0 /* Not used */
+static inline uint16_t stm32_getframe(void)
+{
+ return (uint16_t)(stm32_getreg(STM32_OTG_HFNUM) & OTG_HFNUM_FRNUM_MASK);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_ctrl_sendsetup
+ *
+ * Description:
+ * Send an IN/OUT SETUP packet.
+ *
+ ****************************************************************************/
+
+static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_ctrlinfo_s *ep0,
+ FAR const struct usb_ctrlreq_s *req)
+{
+ FAR struct stm32_chan_s *chan;
+ systime_t start;
+ systime_t elapsed;
+ int ret;
+
+ /* Loop while the device reports NAK (and a timeout is not exceeded */
+
+ chan = &priv->chan[ep0->outndx];
+ start = clock_systimer();
+
+ do
+ {
+ /* Send the SETUP packet */
+
+ chan->pid = OTG_PID_SETUP;
+ chan->buffer = (FAR uint8_t *)req;
+ chan->buflen = USB_SIZEOF_CTRLREQ;
+ chan->xfrd = 0;
+
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0);
+ return ret;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, ep0->outndx);
+
+ /* Wait for the transfer to complete */
+
+ ret = stm32_chan_wait(priv, chan);
+
+ /* Return on success and for all failures other than EAGAIN. EAGAIN
+ * means that the device NAKed the SETUP command and that we should
+ * try a few more times.
+ */
+
+ if (ret != -EAGAIN)
+ {
+ /* Output some debug information if the transfer failed */
+
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_TRNSFRFAILED, ret);
+ }
+
+ /* Return the result in any event */
+
+ return ret;
+ }
+
+ /* Get the elapsed time (in frames) */
+
+ elapsed = clock_systimer() - start;
+ }
+ while (elapsed < STM32_SETUP_DELAY);
+
+ return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: stm32_ctrl_senddata
+ *
+ * Description:
+ * Send data in the data phase of an OUT control transfer. Or send status
+ * in the status phase of an IN control transfer
+ *
+ ****************************************************************************/
+
+static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_ctrlinfo_s *ep0,
+ FAR uint8_t *buffer, unsigned int buflen)
+{
+ FAR struct stm32_chan_s *chan = &priv->chan[ep0->outndx];
+ int ret;
+
+ /* Save buffer information */
+
+ chan->buffer = buffer;
+ chan->buflen = buflen;
+ chan->xfrd = 0;
+
+ /* Set the DATA PID */
+
+ if (buflen == 0)
+ {
+ /* For status OUT stage with buflen == 0, set PID DATA1 */
+
+ chan->outdata1 = true;
+ }
+
+ /* Set the Data PID as per the outdata1 boolean */
+
+ chan->pid = chan->outdata1 ? OTG_PID_DATA1 : OTG_PID_DATA0;
+
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0);
+ return ret;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, ep0->outndx);
+
+ /* Wait for the transfer to complete and return the result */
+
+ return stm32_chan_wait(priv, chan);
+}
+
+/****************************************************************************
+ * Name: stm32_ctrl_recvdata
+ *
+ * Description:
+ * Receive data in the data phase of an IN control transfer. Or receive status
+ * in the status phase of an OUT control transfer
+ *
+ ****************************************************************************/
+
+static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_ctrlinfo_s *ep0,
+ FAR uint8_t *buffer, unsigned int buflen)
+{
+ FAR struct stm32_chan_s *chan = &priv->chan[ep0->inndx];
+ int ret;
+
+ /* Save buffer information */
+
+ chan->pid = OTG_PID_DATA1;
+ chan->buffer = buffer;
+ chan->buflen = buflen;
+ chan->xfrd = 0;
+
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0);
+ return ret;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, ep0->inndx);
+
+ /* Wait for the transfer to complete and return the result */
+
+ return stm32_chan_wait(priv, chan);
+}
+
+/****************************************************************************
+ * Name: stm32_in_setup
+ *
+ * Description:
+ * Initiate an IN transfer on an bulk, interrupt, or isochronous pipe.
+ *
+ ****************************************************************************/
+
+static int stm32_in_setup(FAR struct stm32_usbhost_s *priv, int chidx)
+{
+ FAR struct stm32_chan_s *chan;
+
+ /* Set up for the transfer based on the direction and the endpoint type */
+
+ chan = &priv->chan[chidx];
+ switch (chan->eptype)
+ {
+ default:
+ case OTG_EPTYPE_CTRL: /* Control */
+ {
+ /* This kind of transfer on control endpoints other than EP0 are not
+ * currently supported
+ */
+
+ return -ENOSYS;
+ }
+
+ case OTG_EPTYPE_ISOC: /* Isochronous */
+ {
+ /* Set up the IN data PID */
+
+ usbhost_vtrace2(OTG_VTRACE2_ISOCIN, chidx, chan->buflen);
+ chan->pid = OTG_PID_DATA0;
+ }
+ break;
+
+ case OTG_EPTYPE_BULK: /* Bulk */
+ {
+ /* Setup the IN data PID */
+
+ usbhost_vtrace2(OTG_VTRACE2_BULKIN, chidx, chan->buflen);
+ chan->pid = chan->indata1 ? OTG_PID_DATA1 : OTG_PID_DATA0;
+ }
+ break;
+
+ case OTG_EPTYPE_INTR: /* Interrupt */
+ {
+ /* Setup the IN data PID */
+
+ usbhost_vtrace2(OTG_VTRACE2_INTRIN, chidx, chan->buflen);
+ chan->pid = chan->indata1 ? OTG_PID_DATA1 : OTG_PID_DATA0;
+ }
+ break;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, chidx);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_in_transfer
+ *
+ * Description:
+ * Transfer 'buflen' bytes into 'buffer' from an IN channel.
+ *
+ ****************************************************************************/
+
+static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen)
+{
+ FAR struct stm32_chan_s *chan;
+ systime_t start;
+ systime_t elapsed;
+ int ret;
+
+ /* Loop until the transfer completes (i.e., buflen is decremented to zero)
+ * or a fatal error occurs (any error other than a simple NAK)
+ */
+
+ chan = &priv->chan[chidx];
+ chan->buffer = buffer;
+ chan->buflen = buflen;
+ chan->xfrd = 0;
+
+ start = clock_systimer();
+ while (chan->xfrd < chan->buflen)
+ {
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0);
+ return (ssize_t)ret;
+ }
+
+ /* Set up for the transfer based on the direction and the endpoint type */
+
+ ret = stm32_in_setup(priv, chidx);
+ if (ret < 0)
+ {
+ uerr("ERROR: stm32_in_setup failed: %d\n", ret);
+ return (ssize_t)ret;
+ }
+
+ /* Wait for the transfer to complete and get the result */
+
+ ret = stm32_chan_wait(priv, chan);
+
+ /* EAGAIN indicates that the device NAKed the transfer and we need
+ * do try again. Anything else (success or other errors) will
+ * cause use to return
+ */
+
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_TRNSFRFAILED, ret);
+
+ /* Check for a special case: If (1) the transfer was NAKed and (2)
+ * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we
+ * should be able to just flush the Rx and Tx FIFOs and try again.
+ * We can detect this latter case because the then the transfer
+ * buffer pointer and buffer size will be unaltered.
+ */
+
+ elapsed = clock_systimer() - start;
+ if (ret != -EAGAIN || /* Not a NAK condition OR */
+ elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */
+ chan->xfrd > 0) /* Data has been partially transferred */
+ {
+ /* Break out and return the error */
+
+ uerr("ERROR: stm32_chan_wait failed: %d\n", ret);
+ return (ssize_t)ret;
+ }
+ }
+ }
+
+ return (ssize_t)chan->xfrd;
+}
+
+/****************************************************************************
+ * Name: stm32_in_next
+ *
+ * Description:
+ * Initiate the next of a sequence of asynchronous transfers.
+ *
+ * Assumptions:
+ * This function is always called from an interrupt handler
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST_ASYNCH
+static void stm32_in_next(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan)
+{
+ usbhost_asynch_t callback;
+ FAR void *arg;
+ ssize_t nbytes;
+ int result;
+ int ret;
+
+ /* Is the full transfer complete? Did the last chunk transfer complete OK? */
+
+ result = -(int)chan->result;
+ if (chan->xfrd < chan->buflen && result == OK)
+ {
+ /* Yes.. Set up for the next transfer based on the direction and the
+ * endpoint type
+ */
+
+ ret = stm32_in_setup(priv, chan->chidx);
+ if (ret >= 0)
+ {
+ return;
+ }
+
+ uerr("ERROR: stm32_in_setup failed: %d\n", ret);
+ result = ret;
+ }
+
+ /* The transfer is complete, with or without an error */
+
+ uinfo("Transfer complete: %d\n", result);
+
+ /* Extract the callback information */
+
+ callback = chan->callback;
+ arg = chan->arg;
+ nbytes = chan->xfrd;
+
+ chan->callback = NULL;
+ chan->arg = NULL;
+ chan->xfrd = 0;
+
+ /* Then perform the callback */
+
+ if (result < 0)
+ {
+ nbytes = (ssize_t)result;
+ }
+
+ callback(arg, nbytes);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_in_asynch
+ *
+ * Description:
+ * Initiate the first of a sequence of asynchronous transfers.
+ *
+ * Assumptions:
+ * This function is never called from an interrupt handler
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST_ASYNCH
+static int stm32_in_asynch(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen,
+ usbhost_asynch_t callback, FAR void *arg)
+{
+ FAR struct stm32_chan_s *chan;
+ int ret;
+
+ /* Set up for the transfer data and callback BEFORE starting the first transfer */
+
+ chan = &priv->chan[chidx];
+ chan->buffer = buffer;
+ chan->buflen = buflen;
+ chan->xfrd = 0;
+
+ ret = stm32_chan_asynchsetup(priv, chan, callback, arg);
+ if (ret < 0)
+ {
+ uerr("ERROR: stm32_chan_asynchsetup failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Set up for the transfer based on the direction and the endpoint type */
+
+ ret = stm32_in_setup(priv, chidx);
+ if (ret < 0)
+ {
+ uerr("ERROR: stm32_in_setup failed: %d\n", ret);
+ }
+
+ /* And return with the transfer pending */
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_out_setup
+ *
+ * Description:
+ * Initiate an OUT transfer on an bulk, interrupt, or isochronous pipe.
+ *
+ ****************************************************************************/
+
+static int stm32_out_setup(FAR struct stm32_usbhost_s *priv, int chidx)
+{
+ FAR struct stm32_chan_s *chan;
+
+ /* Set up for the transfer based on the direction and the endpoint type */
+
+ chan = &priv->chan[chidx];
+ switch (chan->eptype)
+ {
+ default:
+ case OTG_EPTYPE_CTRL: /* Control */
+ {
+ /* This kind of transfer on control endpoints other than EP0 are not
+ * currently supported
+ */
+
+ return -ENOSYS;
+ }
+
+ case OTG_EPTYPE_ISOC: /* Isochronous */
+ {
+ /* Set up the OUT data PID */
+
+ usbhost_vtrace2(OTG_VTRACE2_ISOCOUT, chidx, chan->buflen);
+ chan->pid = OTG_PID_DATA0;
+ }
+ break;
+
+ case OTG_EPTYPE_BULK: /* Bulk */
+ {
+ /* Setup the OUT data PID */
+
+ usbhost_vtrace2(OTG_VTRACE2_BULKOUT, chidx, chan->buflen);
+ chan->pid = chan->outdata1 ? OTG_PID_DATA1 : OTG_PID_DATA0;
+ }
+ break;
+
+ case OTG_EPTYPE_INTR: /* Interrupt */
+ {
+ /* Setup the OUT data PID */
+
+ usbhost_vtrace2(OTG_VTRACE2_INTROUT, chidx, chan->buflen);
+ chan->pid = chan->outdata1 ? OTG_PID_DATA1 : OTG_PID_DATA0;
+
+ /* Toggle the OUT data PID for the next transfer */
+
+ chan->outdata1 ^= true;
+ }
+ break;
+ }
+
+ /* Start the transfer */
+
+ stm32_transfer_start(priv, chidx);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_out_transfer
+ *
+ * Description:
+ * Transfer the 'buflen' bytes in 'buffer' through an OUT channel.
+ *
+ ****************************************************************************/
+
+static ssize_t stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen)
+{
+ FAR struct stm32_chan_s *chan;
+ systime_t start;
+ systime_t elapsed;
+ size_t xfrlen;
+ ssize_t xfrd;
+ int ret;
+
+ /* Loop until the transfer completes (i.e., buflen is decremented to zero)
+ * or a fatal error occurs (any error other than a simple NAK)
+ */
+
+ chan = &priv->chan[chidx];
+ start = clock_systimer();
+ xfrd = 0;
+
+ while (buflen > 0)
+ {
+ /* Transfer one packet at a time. The hardware is capable of queueing
+ * multiple OUT packets, but I just haven't figured out how to handle
+ * the case where a single OUT packet in the group is NAKed.
+ */
+
+ xfrlen = MIN(chan->maxpacket, buflen);
+ chan->buffer = buffer;
+ chan->buflen = xfrlen;
+ chan->xfrd = 0;
+
+ /* Set up for the wait BEFORE starting the transfer */
+
+ ret = stm32_chan_waitsetup(priv, chan);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0);
+ return (ssize_t)ret;
+ }
+
+ /* Set up for the transfer based on the direction and the endpoint type */
+
+ ret = stm32_out_setup(priv, chidx);
+ if (ret < 0)
+ {
+ uerr("ERROR: stm32_out_setup failed: %d\n", ret);
+ return (ssize_t)ret;
+ }
+
+ /* Wait for the transfer to complete and get the result */
+
+ ret = stm32_chan_wait(priv, chan);
+
+ /* Handle transfer failures */
+
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_TRNSFRFAILED, ret);
+
+ /* Check for a special case: If (1) the transfer was NAKed and (2)
+ * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we
+ * should be able to just flush the Rx and Tx FIFOs and try again.
+ * We can detect this latter case because the then the transfer
+ * buffer pointer and buffer size will be unaltered.
+ */
+
+ elapsed = clock_systimer() - start;
+ if (ret != -EAGAIN || /* Not a NAK condition OR */
+ elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */
+ chan->xfrd > 0) /* Data has been partially transferred */
+ {
+ /* Break out and return the error */
+
+ uerr("ERROR: stm32_chan_wait failed: %d\n", ret);
+ return (ssize_t)ret;
+ }
+
+ /* Is this flush really necessary? What does the hardware do with the
+ * data in the FIFO when the NAK occurs? Does it discard it?
+ */
+
+ stm32_flush_txfifos(OTG_GRSTCTL_TXFNUM_HALL);
+
+ /* Get the device a little time to catch up. Then retry the transfer
+ * using the same buffer pointer and length.
+ */
+
+ usleep(20*1000);
+ }
+ else
+ {
+ /* Successfully transferred. Update the buffer pointer and length */
+
+ buffer += xfrlen;
+ buflen -= xfrlen;
+ xfrd += chan->xfrd;
+ }
+ }
+
+ return xfrd;
+}
+
+/****************************************************************************
+ * Name: stm32_out_next
+ *
+ * Description:
+ * Initiate the next of a sequence of asynchronous transfers.
+ *
+ * Assumptions:
+ * This function is always called from an interrupt handler
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST_ASYNCH
+static void stm32_out_next(FAR struct stm32_usbhost_s *priv,
+ FAR struct stm32_chan_s *chan)
+{
+ usbhost_asynch_t callback;
+ FAR void *arg;
+ ssize_t nbytes;
+ int result;
+ int ret;
+
+ /* Is the full transfer complete? Did the last chunk transfer complete OK? */
+
+ result = -(int)chan->result;
+ if (chan->xfrd < chan->buflen && result == OK)
+ {
+ /* Yes.. Set up for the next transfer based on the direction and the
+ * endpoint type
+ */
+
+ ret = stm32_out_setup(priv, chan->chidx);
+ if (ret >= 0)
+ {
+ return;
+ }
+
+ uerr("ERROR: stm32_out_setup failed: %d\n", ret);
+ result = ret;
+ }
+
+ /* The transfer is complete, with or without an error */
+
+ uinfo("Transfer complete: %d\n", result);
+
+ /* Extract the callback information */
+
+ callback = chan->callback;
+ arg = chan->arg;
+ nbytes = chan->xfrd;
+
+ chan->callback = NULL;
+ chan->arg = NULL;
+ chan->xfrd = 0;
+
+ /* Then perform the callback */
+
+ if (result < 0)
+ {
+ nbytes = (ssize_t)result;
+ }
+
+ callback(arg, nbytes);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_out_asynch
+ *
+ * Description:
+ * Initiate the first of a sequence of asynchronous transfers.
+ *
+ * Assumptions:
+ * This function is never called from an interrupt handler
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST_ASYNCH
+static int stm32_out_asynch(FAR struct stm32_usbhost_s *priv, int chidx,
+ FAR uint8_t *buffer, size_t buflen,
+ usbhost_asynch_t callback, FAR void *arg)
+{
+ FAR struct stm32_chan_s *chan;
+ int ret;
+
+ /* Set up for the transfer data and callback BEFORE starting the first transfer */
+
+ chan = &priv->chan[chidx];
+ chan->buffer = buffer;
+ chan->buflen = buflen;
+ chan->xfrd = 0;
+
+ ret = stm32_chan_asynchsetup(priv, chan, callback, arg);
+ if (ret < 0)
+ {
+ uerr("ERROR: stm32_chan_asynchsetup failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Set up for the transfer based on the direction and the endpoint type */
+
+ ret = stm32_out_setup(priv, chidx);
+ if (ret < 0)
+ {
+ uerr("ERROR: stm32_out_setup failed: %d\n", ret);
+ }
+
+ /* And return with the transfer pending */
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_gint_wrpacket
+ *
+ * Description:
+ * Transfer the 'buflen' bytes in 'buffer' to the Tx FIFO associated with
+ * 'chidx' (non-DMA).
+ *
+ ****************************************************************************/
+
+static void stm32_gint_wrpacket(FAR struct stm32_usbhost_s *priv,
+ FAR uint8_t *buffer, int chidx, int buflen)
+{
+ FAR uint32_t *src;
+ uint32_t fifo;
+ int buflen32;
+
+ stm32_pktdump("Sending", buffer, buflen);
+
+ /* Get the number of 32-byte words associated with this byte size */
+
+ buflen32 = (buflen + 3) >> 2;
+
+ /* Get the address of the Tx FIFO associated with this channel */
+
+ fifo = STM32_OTG_DFIFO_HCH(chidx);
+
+ /* Transfer all of the data into the Tx FIFO */
+
+ src = (FAR uint32_t *)buffer;
+ for (; buflen32 > 0; buflen32--)
+ {
+ uint32_t data = *src++;
+ stm32_putreg(fifo, data);
+ }
+
+ /* Increment the count of bytes "in-flight" in the Tx FIFO */
+
+ priv->chan[chidx].inflight += buflen;
+}
+
+/****************************************************************************
+ * Name: stm32_gint_hcinisr
+ *
+ * Description:
+ * USB OTG FS host IN channels interrupt handler
+ *
+ * One the completion of the transfer, the channel result byte may be set as
+ * follows:
+ *
+ * OK - Transfer completed successfully
+ * EAGAIN - If devices NAKs the transfer or NYET occurs
+ * EPERM - If the endpoint stalls
+ * EIO - On a TX or data toggle error
+ * EPIPE - Frame overrun
+ *
+ * EBUSY in the result field indicates that the transfer has not completed.
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_hcinisr(FAR struct stm32_usbhost_s *priv,
+ int chidx)
+{
+ FAR struct stm32_chan_s *chan = &priv->chan[chidx];
+ uint32_t regval;
+ uint32_t pending;
+
+ /* Read the HCINT register to get the pending HC interrupts. Read the
+ * HCINTMSK register to get the set of enabled HC interrupts.
+ */
+
+ pending = stm32_getreg(STM32_OTG_HCINT(chidx));
+ regval = stm32_getreg(STM32_OTG_HCINTMSK(chidx));
+
+ /* AND the two to get the set of enabled, pending HC interrupts */
+
+ pending &= regval;
+ uinfo("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending);
+
+ /* Check for a pending ACK response received/transmitted (ACK) interrupt */
+
+ if ((pending & OTG_HCINT_ACK) != 0)
+ {
+ /* Clear the pending the ACK response received/transmitted (ACK) interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_ACK);
+ }
+
+ /* Check for a pending STALL response receive (STALL) interrupt */
+
+ else if ((pending & OTG_HCINT_STALL) != 0)
+ {
+ /* Clear the NAK and STALL Conditions. */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), (OTG_HCINT_NAK | OTG_HCINT_STALL));
+
+ /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is
+ * received on the channel.
+ */
+
+ stm32_chan_halt(priv, chidx, CHREASON_STALL);
+
+ /* When there is a STALL, clear any pending NAK so that it is not
+ * processed below.
+ */
+
+ pending &= ~OTG_HCINT_NAK;
+ }
+
+ /* Check for a pending Data Toggle ERRor (DTERR) interrupt */
+
+ else if ((pending & OTG_HCINT_DTERR) != 0)
+ {
+ /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is
+ * received on the channel.
+ */
+
+ stm32_chan_halt(priv, chidx, CHREASON_DTERR);
+
+ /* Clear the NAK and data toggle error conditions */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), (OTG_HCINT_NAK | OTG_HCINT_DTERR));
+ }
+
+ /* Check for a pending FRaMe OverRun (FRMOR) interrupt */
+
+ if ((pending & OTG_HCINT_FRMOR) != 0)
+ {
+ /* Halt the channel -- the CHH interrupt is expected next */
+
+ stm32_chan_halt(priv, chidx, CHREASON_FRMOR);
+
+ /* Clear the FRaMe OverRun (FRMOR) condition */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_FRMOR);
+ }
+
+ /* Check for a pending TransFeR Completed (XFRC) interrupt */
+
+ else if ((pending & OTG_HCINT_XFRC) != 0)
+ {
+ /* Clear the TransFeR Completed (XFRC) condition */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_XFRC);
+
+ /* Then handle the transfer completion event based on the endpoint type */
+
+ if (chan->eptype == OTG_EPTYPE_CTRL || chan->eptype == OTG_EPTYPE_BULK)
+ {
+ /* Halt the channel -- the CHH interrupt is expected next */
+
+ stm32_chan_halt(priv, chidx, CHREASON_XFRC);
+
+ /* Clear any pending NAK condition. The 'indata1' data toggle
+ * should have been appropriately updated by the RxFIFO
+ * logic as each packet was received.
+ */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_NAK);
+ }
+ else if (chan->eptype == OTG_EPTYPE_INTR)
+ {
+ /* Force the next transfer on an ODD frame */
+
+ regval = stm32_getreg(STM32_OTG_HCCHAR(chidx));
+ regval |= OTG_HCCHAR_ODDFRM;
+ stm32_putreg(STM32_OTG_HCCHAR(chidx), regval);
+
+ /* Set the request done state */
+
+ chan->result = OK;
+ }
+ }
+
+ /* Check for a pending CHannel Halted (CHH) interrupt */
+
+ else if ((pending & OTG_HCINT_CHH) != 0)
+ {
+ /* Mask the CHannel Halted (CHH) interrupt */
+
+ regval = stm32_getreg(STM32_OTG_HCINTMSK(chidx));
+ regval &= ~OTG_HCINT_CHH;
+ stm32_putreg(STM32_OTG_HCINTMSK(chidx), regval);
+
+ /* Update the request state based on the host state machine state */
+
+ if (chan->chreason == CHREASON_XFRC)
+ {
+ /* Set the request done result */
+
+ chan->result = OK;
+ }
+ else if (chan->chreason == CHREASON_STALL)
+ {
+ /* Set the request stall result */
+
+ chan->result = EPERM;
+ }
+ else if ((chan->chreason == CHREASON_TXERR) ||
+ (chan->chreason == CHREASON_DTERR))
+ {
+ /* Set the request I/O error result */
+
+ chan->result = EIO;
+ }
+ else if (chan->chreason == CHREASON_NAK)
+ {
+ /* Halt on NAK only happens on an INTR channel. Fetch the HCCHAR
+ * register and check for an interrupt endpoint.
+ */
+
+ regval = stm32_getreg(STM32_OTG_HCCHAR(chidx));
+ if ((regval & OTG_HCCHAR_EPTYP_MASK) == OTG_HCCHAR_EPTYP_INTR)
+ {
+ /* Toggle the IN data toggle (Used by Bulk and INTR only) */
+
+ chan->indata1 ^= true;
+ }
+
+ /* Set the NAK error result */
+
+ chan->result = EAGAIN;
+ }
+ else /* if (chan->chreason == CHREASON_FRMOR) */
+ {
+ /* Set the frame overrun error result */
+
+ chan->result = EPIPE;
+ }
+
+ /* Clear the CHannel Halted (CHH) condition */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_CHH);
+ }
+
+ /* Check for a pending Transaction ERror (TXERR) interrupt */
+
+ else if ((pending & OTG_HCINT_TXERR) != 0)
+ {
+ /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is
+ * received on the channel.
+ */
+
+ stm32_chan_halt(priv, chidx, CHREASON_TXERR);
+
+ /* Clear the Transaction ERror (TXERR) condition */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_TXERR);
+ }
+
+ /* Check for a pending NAK response received (NAK) interrupt */
+
+ else if ((pending & OTG_HCINT_NAK) != 0)
+ {
+ /* For a BULK transfer, the hardware is capable of retrying
+ * automatically on a NAK. However, this is not always
+ * what we need to do. So we always halt the transfer and
+ * return control to high level logic in the event of a NAK.
+ */
+
+#if 1
+ /* Halt the interrupt channel */
+
+ if (chan->eptype == OTG_EPTYPE_INTR)
+ {
+ /* Halt the channel -- the CHH interrupt is expected next */
+
+ stm32_chan_halt(priv, chidx, CHREASON_NAK);
+ }
+
+ /* Re-activate CTRL and BULK channels.
+ * REVISIT: This can cause a lot of interrupts!
+ */
+
+ else if (chan->eptype == OTG_EPTYPE_CTRL ||
+ chan->eptype == OTG_EPTYPE_BULK)
+ {
+ /* Re-activate the channel by clearing CHDIS and assuring that
+ * CHENA is set
+ */
+
+ regval = stm32_getreg(STM32_OTG_HCCHAR(chidx));
+ regval |= OTG_HCCHAR_CHENA;
+ regval &= ~OTG_HCCHAR_CHDIS;
+ stm32_putreg(STM32_OTG_HCCHAR(chidx), regval);
+ }
+#else
+ /* Halt all transfers on the NAK -- the CHH interrupt is expected next */
+
+ stm32_chan_halt(priv, chidx, CHREASON_NAK);
+#endif
+
+ /* Clear the NAK condition */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_NAK);
+ }
+
+ /* Check for a transfer complete event */
+
+ stm32_chan_wakeup(priv, chan);
+}
+
+/****************************************************************************
+ * Name: stm32_gint_hcoutisr
+ *
+ * Description:
+ * USB OTG FS host OUT channels interrupt handler
+ *
+ * One the completion of the transfer, the channel result byte may be set as
+ * follows:
+ *
+ * OK - Transfer completed successfully
+ * EAGAIN - If devices NAKs the transfer or NYET occurs
+ * EPERM - If the endpoint stalls
+ * EIO - On a TX or data toggle error
+ * EPIPE - Frame overrun
+ *
+ * EBUSY in the result field indicates that the transfer has not completed.
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_hcoutisr(FAR struct stm32_usbhost_s *priv,
+ int chidx)
+{
+ FAR struct stm32_chan_s *chan = &priv->chan[chidx];
+ uint32_t regval;
+ uint32_t pending;
+
+ /* Read the HCINT register to get the pending HC interrupts. Read the
+ * HCINTMSK register to get the set of enabled HC interrupts.
+ */
+
+ pending = stm32_getreg(STM32_OTG_HCINT(chidx));
+ regval = stm32_getreg(STM32_OTG_HCINTMSK(chidx));
+
+ /* AND the two to get the set of enabled, pending HC interrupts */
+
+ pending &= regval;
+ uinfo("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending);
+
+ /* Check for a pending ACK response received/transmitted (ACK) interrupt */
+
+ if ((pending & OTG_HCINT_ACK) != 0)
+ {
+ /* Clear the pending the ACK response received/transmitted (ACK) interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_ACK);
+ }
+
+ /* Check for a pending FRaMe OverRun (FRMOR) interrupt */
+
+ else if ((pending & OTG_HCINT_FRMOR) != 0)
+ {
+ /* Halt the channel (probably not necessary for FRMOR) */
+
+ stm32_chan_halt(priv, chidx, CHREASON_FRMOR);
+
+ /* Clear the pending the FRaMe OverRun (FRMOR) interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_FRMOR);
+ }
+
+ /* Check for a pending TransFeR Completed (XFRC) interrupt */
+
+ else if ((pending & OTG_HCINT_XFRC) != 0)
+ {
+ /* Decrement the number of bytes remaining by the number of
+ * bytes that were "in-flight".
+ */
+
+ priv->chan[chidx].buffer += priv->chan[chidx].inflight;
+ priv->chan[chidx].xfrd += priv->chan[chidx].inflight;
+ priv->chan[chidx].inflight = 0;
+
+ /* Halt the channel -- the CHH interrupt is expected next */
+
+ stm32_chan_halt(priv, chidx, CHREASON_XFRC);
+
+ /* Clear the pending the TransFeR Completed (XFRC) interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_XFRC);
+ }
+
+ /* Check for a pending STALL response receive (STALL) interrupt */
+
+ else if ((pending & OTG_HCINT_STALL) != 0)
+ {
+ /* Clear the pending the STALL response receiv (STALL) interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_STALL);
+
+ /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is
+ * received on the channel.
+ */
+
+ stm32_chan_halt(priv, chidx, CHREASON_STALL);
+ }
+
+ /* Check for a pending NAK response received (NAK) interrupt */
+
+ else if ((pending & OTG_HCINT_NAK) != 0)
+ {
+ /* Halt the channel -- the CHH interrupt is expected next */
+
+ stm32_chan_halt(priv, chidx, CHREASON_NAK);
+
+ /* Clear the pending the NAK response received (NAK) interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_NAK);
+ }
+
+ /* Check for a pending Transaction ERror (TXERR) interrupt */
+
+ else if ((pending & OTG_HCINT_TXERR) != 0)
+ {
+ /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is
+ * received on the channel.
+ */
+
+ stm32_chan_halt(priv, chidx, CHREASON_TXERR);
+
+ /* Clear the pending the Transaction ERror (TXERR) interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_TXERR);
+ }
+
+ /* Check for a NYET interrupt */
+
+#if 0 /* NYET is a reserved bit in the HCINT register */
+ else if ((pending & OTG_HCINT_NYET) != 0)
+ {
+ /* Halt the channel */
+
+ stm32_chan_halt(priv, chidx, CHREASON_NYET);
+
+ /* Clear the pending the NYET interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_NYET);
+ }
+#endif
+
+ /* Check for a pending Data Toggle ERRor (DTERR) interrupt */
+
+ else if (pending & OTG_HCINT_DTERR)
+ {
+ /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is
+ * received on the channel.
+ */
+
+ stm32_chan_halt(priv, chidx, CHREASON_DTERR);
+
+ /* Clear the pending the Data Toggle ERRor (DTERR) and NAK interrupts */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), (OTG_HCINT_DTERR | OTG_HCINT_NAK));
+ }
+
+ /* Check for a pending CHannel Halted (CHH) interrupt */
+
+ else if ((pending & OTG_HCINT_CHH) != 0)
+ {
+ /* Mask the CHannel Halted (CHH) interrupt */
+
+ regval = stm32_getreg(STM32_OTG_HCINTMSK(chidx));
+ regval &= ~OTG_HCINT_CHH;
+ stm32_putreg(STM32_OTG_HCINTMSK(chidx), regval);
+
+ if (chan->chreason == CHREASON_XFRC)
+ {
+ /* Set the request done result */
+
+ chan->result = OK;
+
+ /* Read the HCCHAR register to get the HCCHAR register to get
+ * the endpoint type.
+ */
+
+ regval = stm32_getreg(STM32_OTG_HCCHAR(chidx));
+
+ /* Is it a bulk endpoint? Were an odd number of packets
+ * transferred?
+ */
+
+ if ((regval & OTG_HCCHAR_EPTYP_MASK) == OTG_HCCHAR_EPTYP_BULK &&
+ (chan->npackets & 1) != 0)
+ {
+ /* Yes to both... toggle the data out PID */
+
+ chan->outdata1 ^= true;
+ }
+ }
+ else if (chan->chreason == CHREASON_NAK ||
+ chan->chreason == CHREASON_NYET)
+ {
+ /* Set the try again later result */
+
+ chan->result = EAGAIN;
+ }
+ else if (chan->chreason == CHREASON_STALL)
+ {
+ /* Set the request stall result */
+
+ chan->result = EPERM;
+ }
+ else if ((chan->chreason == CHREASON_TXERR) ||
+ (chan->chreason == CHREASON_DTERR))
+ {
+ /* Set the I/O failure result */
+
+ chan->result = EIO;
+ }
+ else /* if (chan->chreason == CHREASON_FRMOR) */
+ {
+ /* Set the frame error result */
+
+ chan->result = EPIPE;
+ }
+
+ /* Clear the pending the CHannel Halted (CHH) interrupt */
+
+ stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_CHH);
+ }
+
+ /* Check for a transfer complete event */
+
+ stm32_chan_wakeup(priv, chan);
+}
+
+/****************************************************************************
+ * Name: stm32_gint_connected
+ *
+ * Description:
+ * Handle a connection event.
+ *
+ ****************************************************************************/
+
+static void stm32_gint_connected(FAR struct stm32_usbhost_s *priv)
+{
+ /* We we previously disconnected? */
+
+ if (!priv->connected)
+ {
+ /* Yes.. then now we are connected */
+
+ usbhost_vtrace1(OTG_VTRACE1_CONNECTED, 0);
+ priv->connected = true;
+ priv->change = true;
+ DEBUGASSERT(priv->smstate == SMSTATE_DETACHED);
+
+ /* Notify any waiters */
+
+ priv->smstate = SMSTATE_ATTACHED;
+ if (priv->pscwait)
+ {
+ stm32_givesem(&priv->pscsem);
+ priv->pscwait = false;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_gint_disconnected
+ *
+ * Description:
+ * Handle a disconnection event.
+ *
+ ****************************************************************************/
+
+static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv)
+{
+ /* Were we previously connected? */
+
+ if (priv->connected)
+ {
+ /* Yes.. then we no longer connected */
+
+ usbhost_vtrace1(OTG_VTRACE1_DISCONNECTED, 0);
+
+ /* Are we bound to a class driver? */
+
+ if (priv->rhport.hport.devclass)
+ {
+ /* Yes.. Disconnect the class driver */
+
+ CLASS_DISCONNECTED(priv->rhport.hport.devclass);
+ priv->rhport.hport.devclass = NULL;
+ }
+
+ /* Re-Initialize Host for new Enumeration */
+
+ priv->smstate = SMSTATE_DETACHED;
+ priv->connected = false;
+ priv->change = true;
+ stm32_chan_freeall(priv);
+
+ priv->rhport.hport.speed = USB_SPEED_FULL;
+
+ /* Notify any waiters that there is a change in the connection state */
+
+ if (priv->pscwait)
+ {
+ stm32_givesem(&priv->pscsem);
+ priv->pscwait = false;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_gint_sofisr
+ *
+ * Description:
+ * USB OTG FS start-of-frame interrupt handler
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32F7_OTG_SOFINTR
+static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv)
+{
+ /* Handle SOF interrupt */
+#warning "Do what?"
+
+ /* Clear pending SOF interrupt */
+
+ stm32_putreg(STM32_OTG_GINTSTS, OTG_GINT_SOF);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_gint_rxflvlisr
+ *
+ * Description:
+ * USB OTG FS RxFIFO non-empty interrupt handler
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv)
+{
+ FAR uint32_t *dest;
+ uint32_t grxsts;
+ uint32_t intmsk;
+ uint32_t hcchar;
+ uint32_t hctsiz;
+ uint32_t fifo;
+ int bcnt;
+ int bcnt32;
+ int chidx;
+ int i;
+
+ /* Disable the RxFIFO non-empty interrupt */
+
+ intmsk = stm32_getreg(STM32_OTG_GINTMSK);
+ intmsk &= ~OTG_GINT_RXFLVL;
+ stm32_putreg(STM32_OTG_GINTMSK, intmsk);
+
+ /* Read and pop the next status from the Rx FIFO */
+
+ grxsts = stm32_getreg(STM32_OTG_GRXSTSP);
+ uinfo("GRXSTS: %08x\n", grxsts);
+
+ /* Isolate the channel number/index in the status word */
+
+ chidx = (grxsts & OTG_GRXSTSH_CHNUM_MASK) >> OTG_GRXSTSH_CHNUM_SHIFT;
+
+ /* Get the host channel characteristics register (HCCHAR) for this channel */
+
+ hcchar = stm32_getreg(STM32_OTG_HCCHAR(chidx));
+
+ /* Then process the interrupt according to the packet status */
+
+ switch (grxsts & OTG_GRXSTSH_PKTSTS_MASK)
+ {
+ case OTG_GRXSTSH_PKTSTS_INRECVD: /* IN data packet received */
+ {
+ /* Read the data into the host buffer. */
+
+ bcnt = (grxsts & OTG_GRXSTSH_BCNT_MASK) >> OTG_GRXSTSH_BCNT_SHIFT;
+ if (bcnt > 0 && priv->chan[chidx].buffer != NULL)
+ {
+ /* Transfer the packet from the Rx FIFO into the user buffer */
+
+ dest = (FAR uint32_t *)priv->chan[chidx].buffer;
+ fifo = STM32_OTG_DFIFO_HCH(0);
+ bcnt32 = (bcnt + 3) >> 2;
+
+ for (i = 0; i < bcnt32; i++)
+ {
+ *dest++ = stm32_getreg(fifo);
+ }
+
+ stm32_pktdump("Received", priv->chan[chidx].buffer, bcnt);
+
+ /* Toggle the IN data pid (Used by Bulk and INTR only) */
+
+ priv->chan[chidx].indata1 ^= true;
+
+ /* Manage multiple packet transfers */
+
+ priv->chan[chidx].buffer += bcnt;
+ priv->chan[chidx].xfrd += bcnt;
+
+ /* Check if more packets are expected */
+
+ hctsiz = stm32_getreg(STM32_OTG_HCTSIZ(chidx));
+ if ((hctsiz & OTG_HCTSIZ_PKTCNT_MASK) != 0)
+ {
+ /* Re-activate the channel when more packets are expected */
+
+ hcchar |= OTG_HCCHAR_CHENA;
+ hcchar &= ~OTG_HCCHAR_CHDIS;
+ stm32_putreg(STM32_OTG_HCCHAR(chidx), hcchar);
+ }
+ }
+ }
+ break;
+
+ case OTG_GRXSTSH_PKTSTS_INDONE: /* IN transfer completed */
+ case OTG_GRXSTSH_PKTSTS_DTOGERR: /* Data toggle error */
+ case OTG_GRXSTSH_PKTSTS_HALTED: /* Channel halted */
+ default:
+ break;
+ }
+
+ /* Re-enable the RxFIFO non-empty interrupt */
+
+ intmsk |= OTG_GINT_RXFLVL;
+ stm32_putreg(STM32_OTG_GINTMSK, intmsk);
+}
+
+/****************************************************************************
+ * Name: stm32_gint_nptxfeisr
+ *
+ * Description:
+ * USB OTG FS non-periodic TxFIFO empty interrupt handler
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_nptxfeisr(FAR struct stm32_usbhost_s *priv)
+{
+ FAR struct stm32_chan_s *chan;
+ uint32_t regval;
+ unsigned int wrsize;
+ unsigned int avail;
+ unsigned int chidx;
+
+ /* Recover the index of the channel that is waiting for space in the Tx
+ * FIFO.
+ */
+
+ chidx = priv->chidx;
+ chan = &priv->chan[chidx];
+
+ /* Reduce the buffer size by the number of bytes that were previously placed
+ * in the Tx FIFO.
+ */
+
+ chan->buffer += chan->inflight;
+ chan->xfrd += chan->inflight;
+ chan->inflight = 0;
+
+ /* If we have now transferred the entire buffer, then this transfer is
+ * complete (this case really should never happen because we disable
+ * the NPTXFE interrupt on the final packet).
+ */
+
+ if (chan->xfrd >= chan->buflen)
+ {
+ /* Disable further Tx FIFO empty interrupts and bail. */
+
+ stm32_modifyreg(STM32_OTG_GINTMSK, OTG_GINT_NPTXFE, 0);
+ return;
+ }
+
+ /* Read the status from the top of the non-periodic TxFIFO */
+
+ regval = stm32_getreg(STM32_OTG_HNPTXSTS);
+
+ /* Extract the number of bytes available in the non-periodic Tx FIFO. */
+
+ avail = ((regval & OTG_HNPTXSTS_NPTXFSAV_MASK) >> OTG_HNPTXSTS_NPTXFSAV_SHIFT) << 2;
+
+ /* Get the size to put in the Tx FIFO now */
+
+ wrsize = chan->buflen - chan->xfrd;
+
+ /* Get minimal size packet that can be sent. Something is seriously
+ * configured wrong if one packet will not fit into the empty Tx FIFO.
+ */
+
+ DEBUGASSERT(wrsize > 0 && avail >= MIN(wrsize, chan->maxpacket));
+ if (wrsize > avail)
+ {
+ /* Clip the write size to the number of full, max sized packets
+ * that will fit in the Tx FIFO.
+ */
+
+ unsigned int wrpackets = avail / chan->maxpacket;
+ wrsize = wrpackets * chan->maxpacket;
+ }
+
+ /* Otherwise, this will be the last packet to be sent in this transaction.
+ * We now need to disable further NPTXFE interrupts.
+ */
+
+ else
+ {
+ stm32_modifyreg(STM32_OTG_GINTMSK, OTG_GINT_NPTXFE, 0);
+ }
+
+ /* Write the next group of packets into the Tx FIFO */
+
+ uinfo("HNPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n",
+ regval, chidx, avail, chan->buflen, chan->xfrd, wrsize);
+
+ stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize);
+}
+
+/****************************************************************************
+ * Name: stm32_gint_ptxfeisr
+ *
+ * Description:
+ * USB OTG FS periodic TxFIFO empty interrupt handler
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_ptxfeisr(FAR struct stm32_usbhost_s *priv)
+{
+ FAR struct stm32_chan_s *chan;
+ uint32_t regval;
+ unsigned int wrsize;
+ unsigned int avail;
+ unsigned int chidx;
+
+ /* Recover the index of the channel that is waiting for space in the Tx
+ * FIFO.
+ */
+
+ chidx = priv->chidx;
+ chan = &priv->chan[chidx];
+
+ /* Reduce the buffer size by the number of bytes that were previously placed
+ * in the Tx FIFO.
+ */
+
+ chan->buffer += chan->inflight;
+ chan->xfrd += chan->inflight;
+ chan->inflight = 0;
+
+ /* If we have now transfered the entire buffer, then this transfer is
+ * complete (this case really should never happen because we disable
+ * the PTXFE interrupt on the final packet).
+ */
+
+ if (chan->xfrd >= chan->buflen)
+ {
+ /* Disable further Tx FIFO empty interrupts and bail. */
+
+ stm32_modifyreg(STM32_OTG_GINTMSK, OTG_GINT_PTXFE, 0);
+ return;
+ }
+
+ /* Read the status from the top of the periodic TxFIFO */
+
+ regval = stm32_getreg(STM32_OTG_HPTXSTS);
+
+ /* Extract the number of bytes available in the periodic Tx FIFO. */
+
+ avail = ((regval & OTG_HPTXSTS_PTXFSAVL_MASK) >> OTG_HPTXSTS_PTXFSAVL_SHIFT) << 2;
+
+ /* Get the size to put in the Tx FIFO now */
+
+ wrsize = chan->buflen - chan->xfrd;
+
+ /* Get minimal size packet that can be sent. Something is seriously
+ * configured wrong if one packet will not fit into the empty Tx FIFO.
+ */
+
+ DEBUGASSERT(wrsize && avail >= MIN(wrsize, chan->maxpacket));
+ if (wrsize > avail)
+ {
+ /* Clip the write size to the number of full, max sized packets
+ * that will fit in the Tx FIFO.
+ */
+
+ unsigned int wrpackets = avail / chan->maxpacket;
+ wrsize = wrpackets * chan->maxpacket;
+ }
+
+ /* Otherwise, this will be the last packet to be sent in this transaction.
+ * We now need to disable further PTXFE interrupts.
+ */
+
+ else
+ {
+ stm32_modifyreg(STM32_OTG_GINTMSK, OTG_GINT_PTXFE, 0);
+ }
+
+ /* Write the next group of packets into the Tx FIFO */
+
+ uinfo("HPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n",
+ regval, chidx, avail, chan->buflen, chan->xfrd, wrsize);
+
+ stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize);
+}
+
+/****************************************************************************
+ * Name: stm32_gint_hcisr
+ *
+ * Description:
+ * USB OTG FS host channels interrupt handler
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_hcisr(FAR struct stm32_usbhost_s *priv)
+{
+ uint32_t haint;
+ uint32_t hcchar;
+ int i = 0;
+
+ /* Read the Host all channels interrupt register and test each bit in the
+ * register. Each bit i, i=0...(STM32_NHOST_CHANNELS-1), corresponds to
+ * a pending interrupt on channel i.
+ */
+
+ haint = stm32_getreg(STM32_OTG_HAINT);
+ for (i = 0; i < STM32_NHOST_CHANNELS; i++)
+ {
+ /* Is an interrupt pending on this channel? */
+
+ if ((haint & OTG_HAINT(i)) != 0)
+ {
+ /* Yes... read the HCCHAR register to get the direction bit */
+
+ hcchar = stm32_getreg(STM32_OTG_HCCHAR(i));
+
+ /* Was this an interrupt on an IN or an OUT channel? */
+
+ if ((hcchar & OTG_HCCHAR_EPDIR) != 0)
+ {
+ /* Handle the HC IN channel interrupt */
+
+ stm32_gint_hcinisr(priv, i);
+ }
+ else
+ {
+ /* Handle the HC OUT channel interrupt */
+
+ stm32_gint_hcoutisr(priv, i);
+ }
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_gint_hprtisr
+ *
+ * Description:
+ * USB OTG FS host port interrupt handler
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_hprtisr(FAR struct stm32_usbhost_s *priv)
+{
+ uint32_t hprt;
+ uint32_t newhprt;
+ uint32_t hcfg;
+
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT, 0);
+ /* Read the port status and control register (HPRT) */
+
+ hprt = stm32_getreg(STM32_OTG_HPRT);
+
+ /* Setup to clear the interrupt bits in GINTSTS by setting the corresponding
+ * bits in the HPRT. The HCINT interrupt bit is cleared when the appropriate
+ * status bits in the HPRT register are cleared.
+ */
+
+ newhprt = hprt & ~(OTG_HPRT_PENA | OTG_HPRT_PCDET |
+ OTG_HPRT_PENCHNG | OTG_HPRT_POCCHNG);
+
+ /* Check for Port Overcurrent CHaNGe (POCCHNG) */
+
+ if ((hprt & OTG_HPRT_POCCHNG) != 0)
+ {
+ /* Set up to clear the POCCHNG status in the new HPRT contents. */
+
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_POCCHNG, 0);
+ newhprt |= OTG_HPRT_POCCHNG;
+ }
+
+ /* Check for Port Connect DETected (PCDET). The core sets this bit when a
+ * device connection is detected.
+ */
+
+ if ((hprt & OTG_HPRT_PCDET) != 0)
+ {
+ /* Set up to clear the PCDET status in the new HPRT contents. Then
+ * process the new connection event.
+ */
+
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_PCDET, 0);
+ newhprt |= OTG_HPRT_PCDET;
+ stm32_portreset(priv);
+ stm32_gint_connected(priv);
+ }
+
+ /* Check for Port Enable CHaNGed (PENCHNG) */
+
+ if ((hprt & OTG_HPRT_PENCHNG) != 0)
+ {
+ /* Set up to clear the PENCHNG status in the new HPRT contents. */
+
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_PENCHNG, 0);
+ newhprt |= OTG_HPRT_PENCHNG;
+
+ /* Was the port enabled? */
+
+ if ((hprt & OTG_HPRT_PENA) != 0)
+ {
+ /* Yes.. handle the new connection event */
+
+ stm32_gint_connected(priv);
+
+ /* Check the Host ConFiGuration register (HCFG) */
+
+ hcfg = stm32_getreg(STM32_OTG_HCFG);
+
+ /* Is this a low speed or full speed connection (OTG FS does not
+ * support high speed)
+ */
+
+ if ((hprt & OTG_HPRT_PSPD_MASK) == OTG_HPRT_PSPD_LS)
+ {
+ /* Set the Host Frame Interval Register for the 6KHz speed */
+
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_LSDEV, 0);
+ stm32_putreg(STM32_OTG_HFIR, 6000);
+
+ /* Are we switching from FS to LS? */
+
+ if ((hcfg & OTG_HCFG_FSLSPCS_MASK) != OTG_HCFG_FSLSPCS_LS6MHz)
+ {
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_FSLSSW, 0);
+
+ /* Yes... configure for LS */
+
+ hcfg &= ~OTG_HCFG_FSLSPCS_MASK;
+ hcfg |= OTG_HCFG_FSLSPCS_LS6MHz;
+ stm32_putreg(STM32_OTG_HCFG, hcfg);
+
+ /* And reset the port */
+
+ stm32_portreset(priv);
+ }
+ }
+ else /* if ((hprt & OTG_HPRT_PSPD_MASK) == OTG_HPRT_PSPD_FS) */
+ {
+
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_FSDEV, 0);
+ stm32_putreg(STM32_OTG_HFIR, 48000);
+
+ /* Are we switching from LS to FS? */
+
+ if ((hcfg & OTG_HCFG_FSLSPCS_MASK) != OTG_HCFG_FSLSPCS_FS48MHz)
+ {
+
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_LSFSSW, 0);
+ /* Yes... configure for FS */
+
+ hcfg &= ~OTG_HCFG_FSLSPCS_MASK;
+ hcfg |= OTG_HCFG_FSLSPCS_FS48MHz;
+ stm32_putreg(STM32_OTG_HCFG, hcfg);
+
+ /* And reset the port */
+
+ stm32_portreset(priv);
+ }
+ }
+ }
+ }
+
+ /* Clear port interrupts by setting bits in the HPRT */
+
+ stm32_putreg(STM32_OTG_HPRT, newhprt);
+}
+
+/****************************************************************************
+ * Name: stm32_gint_discisr
+ *
+ * Description:
+ * USB OTG FS disconnect detected interrupt handler
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_discisr(FAR struct stm32_usbhost_s *priv)
+{
+ /* Handle the disconnection event */
+
+ stm32_gint_disconnected(priv);
+
+ /* Clear the dicsonnect interrupt */
+
+ stm32_putreg(STM32_OTG_GINTSTS, OTG_GINT_DISC);
+}
+
+/****************************************************************************
+ * Name: stm32_gint_ipxfrisr
+ *
+ * Description:
+ * USB OTG FS incomplete periodic interrupt handler
+ *
+ ****************************************************************************/
+
+static inline void stm32_gint_ipxfrisr(FAR struct stm32_usbhost_s *priv)
+{
+ uint32_t regval;
+
+ /* CHENA : Set to enable the channel
+ * CHDIS : Set to stop transmitting/receiving data on a channel
+ */
+
+ regval = stm32_getreg(STM32_OTG_HCCHAR(0));
+ regval |= (OTG_HCCHAR_CHDIS | OTG_HCCHAR_CHENA);
+ stm32_putreg(STM32_OTG_HCCHAR(0), regval);
+
+ /* Clear the incomplete isochronous OUT interrupt */
+
+ stm32_putreg(STM32_OTG_GINTSTS, OTG_GINT_IPXFR);
+}
+
+/****************************************************************************
+ * Name: stm32_gint_isr
+ *
+ * Description:
+ * USB OTG FS global interrupt handler
+ *
+ ****************************************************************************/
+
+static int stm32_gint_isr(int irq, FAR void *context)
+{
+ /* At present, there is only support for a single OTG FS host. Hence it is
+ * pre-allocated as g_usbhost. However, in most code, the private data
+ * structure will be referenced using the 'priv' pointer (rather than the
+ * global data) in order to simplify any future support for multiple devices.
+ */
+
+ FAR struct stm32_usbhost_s *priv = &g_usbhost;
+ uint32_t pending;
+
+ /* If OTG were supported, we would need to check if we are in host or
+ * device mode when the global interrupt occurs. Here we support only
+ * host mode
+ */
+
+ /* Loop while there are pending interrupts to process. This loop may save a
+ * little interrupt handling overhead.
+ */
+
+ for (; ; )
+ {
+ /* Get the unmasked bits in the GINT status */
+
+ pending = stm32_getreg(STM32_OTG_GINTSTS);
+ pending &= stm32_getreg(STM32_OTG_GINTMSK);
+
+ /* Return from the interrupt when there are no further pending
+ * interrupts.
+ */
+
+ if (pending == 0)
+ {
+ return OK;
+ }
+
+ /* Otherwise, process each pending, unmasked GINT interrupts */
+ /* Handle the start of frame interrupt */
+
+#ifdef CONFIG_STM32F7_OTG_SOFINTR
+ if ((pending & OTG_GINT_SOF) != 0)
+ {
+ usbhost_vtrace1(OTG_VTRACE1_GINT_SOF, 0);
+ stm32_gint_sofisr(priv);
+ }
+#endif
+
+ /* Handle the RxFIFO non-empty interrupt */
+
+ if ((pending & OTG_GINT_RXFLVL) != 0)
+ {
+ usbhost_vtrace1(OTG_VTRACE1_GINT_RXFLVL, 0);
+ stm32_gint_rxflvlisr(priv);
+ }
+
+ /* Handle the non-periodic TxFIFO empty interrupt */
+
+ if ((pending & OTG_GINT_NPTXFE) != 0)
+ {
+ usbhost_vtrace1(OTG_VTRACE1_GINT_NPTXFE, 0);
+ stm32_gint_nptxfeisr(priv);
+ }
+
+ /* Handle the periodic TxFIFO empty interrupt */
+
+ if ((pending & OTG_GINT_PTXFE) != 0)
+ {
+ usbhost_vtrace1(OTG_VTRACE1_GINT_PTXFE, 0);
+ stm32_gint_ptxfeisr(priv);
+ }
+
+ /* Handle the host channels interrupt */
+
+ if ((pending & OTG_GINT_HC) != 0)
+ {
+ usbhost_vtrace1(OTG_VTRACE1_GINT_HC, 0);
+ stm32_gint_hcisr(priv);
+ }
+
+ /* Handle the host port interrupt */
+
+ if ((pending & OTG_GINT_HPRT) != 0)
+ {
+ stm32_gint_hprtisr(priv);
+ }
+
+ /* Handle the disconnect detected interrupt */
+
+ if ((pending & OTG_GINT_DISC) != 0)
+ {
+ usbhost_vtrace1(OTG_VTRACE1_GINT_DISC, 0);
+ stm32_gint_discisr(priv);
+ }
+
+ /* Handle the incomplete periodic transfer */
+
+ if ((pending & OTG_GINT_IPXFR) != 0)
+ {
+ usbhost_vtrace1(OTG_VTRACE1_GINT_IPXFR, 0);
+ stm32_gint_ipxfrisr(priv);
+ }
+ }
+
+ /* We won't get here */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_gint_enable and stm32_gint_disable
+ *
+ * Description:
+ * Respectively enable or disable the global OTG FS interrupt.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void stm32_gint_enable(void)
+{
+ uint32_t regval;
+
+ /* Set the GINTMSK bit to unmask the interrupt */
+
+ regval = stm32_getreg(STM32_OTG_GAHBCFG);
+ regval |= OTG_GAHBCFG_GINTMSK;
+ stm32_putreg(STM32_OTG_GAHBCFG, regval);
+}
+
+static void stm32_gint_disable(void)
+{
+ uint32_t regval;
+
+ /* Clear the GINTMSK bit to mask the interrupt */
+
+ regval = stm32_getreg(STM32_OTG_GAHBCFG);
+ regval &= ~OTG_GAHBCFG_GINTMSK;
+ stm32_putreg(STM32_OTG_GAHBCFG, regval);
+}
+
+/****************************************************************************
+ * Name: stm32_hostinit_enable
+ *
+ * Description:
+ * Enable host interrupts.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void stm32_hostinit_enable(void)
+{
+ uint32_t regval;
+
+ /* Disable all interrupts. */
+
+ stm32_putreg(STM32_OTG_GINTMSK, 0);
+
+ /* Clear any pending interrupts. */
+
+ stm32_putreg(STM32_OTG_GINTSTS, 0xffffffff);
+
+ /* Clear any pending USB OTG Interrupts (should be done elsewhere if OTG is supported) */
+
+ stm32_putreg(STM32_OTG_GOTGINT, 0xffffffff);
+
+ /* Clear any pending USB OTG interrupts */
+
+ stm32_putreg(STM32_OTG_GINTSTS, 0xbfffffff);
+
+ /* Enable the host interrupts */
+ /* Common interrupts:
+ *
+ * OTG_GINT_WKUP : Resume/remote wakeup detected interrupt
+ * OTG_GINT_USBSUSP : USB suspend
+ */
+
+ regval = (OTG_GINT_WKUP | OTG_GINT_USBSUSP);
+
+ /* If OTG were supported, we would need to enable the following as well:
+ *
+ * OTG_GINT_OTG : OTG interrupt
+ * OTG_GINT_SRQ : Session request/new session detected interrupt
+ * OTG_GINT_CIDSCHG : Connector ID status change
+ */
+
+ /* Host-specific interrupts
+ *
+ * OTG_GINT_SOF : Start of frame
+ * OTG_GINT_RXFLVL : RxFIFO non-empty
+ * OTG_GINT_IISOOXFR : Incomplete isochronous OUT transfer
+ * OTG_GINT_HPRT : Host port interrupt
+ * OTG_GINT_HC : Host channels interrupt
+ * OTG_GINT_DISC : Disconnect detected interrupt
+ */
+
+#ifdef CONFIG_STM32F7_OTG_SOFINTR
+ regval |= (OTG_GINT_SOF | OTG_GINT_RXFLVL | OTG_GINT_IISOOXFR |
+ OTG_GINT_HPRT | OTG_GINT_HC | OTG_GINT_DISC);
+#else
+ regval |= (OTG_GINT_RXFLVL | OTG_GINT_IPXFR | OTG_GINT_HPRT |
+ OTG_GINT_HC | OTG_GINT_DISC);
+#endif
+ stm32_putreg(STM32_OTG_GINTMSK, regval);
+}
+
+/****************************************************************************
+ * Name: stm32_txfe_enable
+ *
+ * Description:
+ * Enable Tx FIFO empty interrupts. This is necessary when the entire
+ * transfer will not fit into Tx FIFO. The transfer will then be completed
+ * when the Tx FIFO is empty. NOTE: The Tx FIFO interrupt is disabled
+ * the fifo empty interrupt handler when the transfer is complete.
+ *
+ * Input Parameters:
+ * priv - Driver state structure reference
+ * chidx - The channel that requires the Tx FIFO empty interrupt
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Called from user task context. Interrupts must be disabled to assure
+ * exclusive access to the GINTMSK register.
+ *
+ ****************************************************************************/
+
+static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx)
+{
+ FAR struct stm32_chan_s *chan = &priv->chan[chidx];
+ irqstate_t flags;
+ uint32_t regval;
+
+ /* Disable all interrupts so that we have exclusive access to the GINTMSK
+ * (it would be sufficent just to disable the GINT interrupt).
+ */
+
+ flags = enter_critical_section();
+
+ /* Should we enable the periodic or non-peridic Tx FIFO empty interrupts */
+
+ regval = stm32_getreg(STM32_OTG_GINTMSK);
+ switch (chan->eptype)
+ {
+ default:
+ case OTG_EPTYPE_CTRL: /* Non periodic transfer */
+ case OTG_EPTYPE_BULK:
+ regval |= OTG_GINT_NPTXFE;
+ break;
+
+ case OTG_EPTYPE_INTR: /* Periodic transfer */
+ case OTG_EPTYPE_ISOC:
+ regval |= OTG_GINT_PTXFE;
+ break;
+ }
+
+ /* Enable interrupts */
+
+ stm32_putreg(STM32_OTG_GINTMSK, regval);
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * USB Host Controller Operations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_wait
+ *
+ * Description:
+ * Wait for a device to be connected or disconnected to/from a hub port.
+ *
+ * Input Parameters:
+ * conn - The USB host connection instance obtained as a parameter from the call to
+ * the USB driver initialization logic.
+ * hport - The location to return the hub port descriptor that detected the
+ * connection related event.
+ *
+ * Returned Values:
+ * Zero (OK) is returned on success when a device in connected or
+ * disconnected. This function will not return until either (1) a device is
+ * connected or disconnect to/from any hub port or until (2) some failure
+ * occurs. On a failure, a negated errno value is returned indicating the
+ * nature of the failure
+ *
+ * Assumptions:
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int stm32_wait(FAR struct usbhost_connection_s *conn,
+ FAR struct usbhost_hubport_s **hport)
+{
+ FAR struct stm32_usbhost_s *priv = &g_usbhost;
+ struct usbhost_hubport_s *connport;
+ irqstate_t flags;
+
+ /* Loop until a change in connection state is detected */
+
+ flags = enter_critical_section();
+ for (; ; )
+ {
+ /* Is there a change in the connection state of the single root hub
+ * port?
+ */
+
+ if (priv->change)
+ {
+ connport = &priv->rhport.hport;
+
+ /* Yes. Remember the new state */
+
+ connport->connected = priv->connected;
+ priv->change = false;
+
+ /* And return the root hub port */
+
+ *hport = connport;
+ leave_critical_section(flags);
+
+ uinfo("RHport Connected: %s\n", connport->connected ? "YES" : "NO");
+ return OK;
+ }
+
+#ifdef CONFIG_USBHOST_HUB
+ /* Is a device connected to an external hub? */
+
+ if (priv->hport)
+ {
+ /* Yes.. return the external hub port */
+
+ connport = (struct usbhost_hubport_s *)priv->hport;
+ priv->hport = NULL;
+
+ *hport = connport;
+ leave_critical_section(flags);
+
+ uinfo("Hub port Connected: %s\n", connport->connected ? "YES" : "NO");
+ return OK;
+ }
+#endif
+
+ /* Wait for the next connection event */
+
+ priv->pscwait = true;
+ stm32_takesem(&priv->pscsem);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_enumerate
+ *
+ * Description:
+ * Enumerate the connected device. As part of this enumeration process,
+ * the driver will (1) get the device's configuration descriptor, (2)
+ * extract the class ID info from the configuration descriptor, (3) call
+ * usbhost_findclass() to find the class that supports this device, (4)
+ * call the create() method on the struct usbhost_registry_s interface
+ * to get a class instance, and finally (5) call the connect() method
+ * of the struct usbhost_class_s interface. After that, the class is in
+ * charge of the sequence of operations.
+ *
+ * Input Parameters:
+ * conn - The USB host connection instance obtained as a parameter from
+ * the call to the USB driver initialization logic.
+ * hport - The descriptor of the hub port that has the newly connected
+ * device.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int stm32_rh_enumerate(FAR struct stm32_usbhost_s *priv,
+ FAR struct usbhost_connection_s *conn,
+ FAR struct usbhost_hubport_s *hport)
+{
+ uint32_t regval;
+ int ret;
+
+ DEBUGASSERT(conn != NULL && hport != NULL && hport->port == 0);
+
+ /* Are we connected to a device? The caller should have called the wait()
+ * method first to be assured that a device is connected.
+ */
+
+ while (!priv->connected)
+ {
+ /* No, return an error */
+
+ usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0);
+ return -ENODEV;
+ }
+
+ DEBUGASSERT(priv->smstate == SMSTATE_ATTACHED);
+
+ /* USB 2.0 spec says at least 50ms delay before port reset. We wait 100ms. */
+
+ usleep(100*1000);
+
+ /* Reset the host port */
+
+ stm32_portreset(priv);
+
+ /* Get the current device speed */
+
+ regval = stm32_getreg(STM32_OTG_HPRT);
+ if ((regval & OTG_HPRT_PSPD_MASK) == OTG_HPRT_PSPD_LS)
+ {
+ priv->rhport.hport.speed = USB_SPEED_LOW;
+ }
+ else
+ {
+ priv->rhport.hport.speed = USB_SPEED_FULL;
+ }
+
+ /* Allocate and initialize the root hub port EP0 channels */
+
+ ret = stm32_ctrlchan_alloc(priv, 0, 0, priv->rhport.hport.speed, &priv->ep0);
+ if (ret < 0)
+ {
+ uerr("ERROR: Failed to allocate a control endpoint: %d\n", ret);
+ }
+
+ return ret;
+}
+
+static int stm32_enumerate(FAR struct usbhost_connection_s *conn,
+ FAR struct usbhost_hubport_s *hport)
+{
+ FAR struct stm32_usbhost_s *priv = &g_usbhost;
+ int ret;
+
+ DEBUGASSERT(hport);
+
+ /* If this is a connection on the root hub, then we need to go to
+ * little more effort to get the device speed. If it is a connection
+ * on an external hub, then we already have that information.
+ */
+
+#ifdef CONFIG_USBHOST_HUB
+ if (ROOTHUB(hport))
+#endif
+ {
+ ret = stm32_rh_enumerate(priv, conn, hport);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ }
+
+ /* Then let the common usbhost_enumerate do the real enumeration. */
+
+ uinfo("Enumerate the device\n");
+ priv->smstate = SMSTATE_ENUM;
+ ret = usbhost_enumerate(hport, &hport->devclass);
+
+ /* The enumeration may fail either because of some HCD interfaces failure
+ * or because the device class is not supported. In either case, we just
+ * need to perform the disconnection operation and make ready for a new
+ * enumeration.
+ */
+
+ if (ret < 0)
+ {
+ /* Return to the disconnected state */
+
+ uerr("ERROR: Enumeration failed: %d\n", ret);
+ stm32_gint_disconnected(priv);
+ }
+
+ return ret;
+}
+
+/************************************************************************************
+ * Name: stm32_ep0configure
+ *
+ * Description:
+ * Configure endpoint 0. This method is normally used internally by the
+ * enumerate() method but is made available at the interface to support an
+ * external implementation of the enumeration logic.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * ep0 - The (opaque) EP0 endpoint instance
+ * funcaddr - The USB address of the function containing the endpoint that EP0
+ * controls
+ * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH
+ * maxpacketsize - The maximum number of bytes that can be sent to or
+ * received from the endpoint in a single data packet
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ************************************************************************************/
+
+static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
+ uint8_t funcaddr, uint8_t speed,
+ uint16_t maxpacketsize)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0;
+ FAR struct stm32_chan_s *chan;
+
+ DEBUGASSERT(drvr != NULL && ep0info != NULL && funcaddr < 128 &&
+ maxpacketsize <= 64);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Configure the EP0 OUT channel */
+
+ chan = &priv->chan[ep0info->outndx];
+ chan->funcaddr = funcaddr;
+ chan->speed = speed;
+ chan->maxpacket = maxpacketsize;
+
+ stm32_chan_configure(priv, ep0info->outndx);
+
+ /* Configure the EP0 IN channel */
+
+ chan = &priv->chan[ep0info->inndx];
+ chan->funcaddr = funcaddr;
+ chan->speed = speed;
+ chan->maxpacket = maxpacketsize;
+
+ stm32_chan_configure(priv, ep0info->inndx);
+
+ stm32_givesem(&priv->exclsem);
+ return OK;
+}
+
+/************************************************************************************
+ * Name: stm32_epalloc
+ *
+ * Description:
+ * Allocate and configure one endpoint.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * epdesc - Describes the endpoint to be allocated.
+ * ep - A memory location provided by the caller in which to receive the
+ * allocated endpoint descriptor.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ************************************************************************************/
+
+static int stm32_epalloc(FAR struct usbhost_driver_s *drvr,
+ FAR const struct usbhost_epdesc_s *epdesc,
+ FAR usbhost_ep_t *ep)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ int ret;
+
+ /* Sanity check. NOTE that this method should only be called if a device is
+ * connected (because we need a valid low speed indication).
+ */
+
+ DEBUGASSERT(drvr != 0 && epdesc != NULL && ep != NULL);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Handler control pipes differently from other endpoint types. This is
+ * because the normal, "transfer" endpoints are unidirectional an require
+ * only a single channel. Control endpoints, however, are bi-diretional
+ * and require two channels, one for the IN and one for the OUT direction.
+ */
+
+ if (epdesc->xfrtype == OTG_EPTYPE_CTRL)
+ {
+ ret = stm32_ctrlep_alloc(priv, epdesc, ep);
+ }
+ else
+ {
+ ret = stm32_xfrep_alloc(priv, epdesc, ep);
+ }
+
+ stm32_givesem(&priv->exclsem);
+ return ret;
+}
+
+/************************************************************************************
+ * Name: stm32_epfree
+ *
+ * Description:
+ * Free and endpoint previously allocated by DRVR_EPALLOC.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * ep - The endpoint to be freed.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ************************************************************************************/
+
+static int stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+
+ DEBUGASSERT(priv);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* A single channel is represent by an index in the range of 0 to STM32_MAX_TX_FIFOS.
+ * Otherwise, the ep must be a pointer to an allocated control endpoint structure.
+ */
+
+ if ((uintptr_t)ep < STM32_MAX_TX_FIFOS)
+ {
+ /* Halt the channel and mark the channel available */
+
+ stm32_chan_free(priv, (int)ep);
+ }
+ else
+ {
+ /* Halt both control channel and mark the channels available */
+
+ FAR struct stm32_ctrlinfo_s *ctrlep = (FAR struct stm32_ctrlinfo_s *)ep;
+ stm32_chan_free(priv, ctrlep->inndx);
+ stm32_chan_free(priv, ctrlep->outndx);
+
+ /* And free the control endpoint container */
+
+ kmm_free(ctrlep);
+ }
+
+ stm32_givesem(&priv->exclsem);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_alloc
+ *
+ * Description:
+ * Some hardware supports special memory in which request and descriptor data can
+ * be accessed more efficiently. This method provides a mechanism to allocate
+ * the request/descriptor memory. If the underlying hardware does not support
+ * such "special" memory, this functions may simply map to kmm_malloc.
+ *
+ * This interface was optimized under a particular assumption. It was assumed
+ * that the driver maintains a pool of small, pre-allocated buffers for descriptor
+ * traffic. NOTE that size is not an input, but an output: The size of the
+ * pre-allocated buffer is returned.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * buffer - The address of a memory location provided by the caller in which to
+ * return the allocated buffer memory address.
+ * maxlen - The address of a memory location provided by the caller in which to
+ * return the maximum size of the allocated buffer memory.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int stm32_alloc(FAR struct usbhost_driver_s *drvr,
+ FAR uint8_t **buffer, FAR size_t *maxlen)
+{
+ FAR uint8_t *alloc;
+
+ DEBUGASSERT(drvr && buffer && maxlen);
+
+ /* There is no special memory requirement for the STM32. */
+
+ alloc = (FAR uint8_t *)kmm_malloc(CONFIG_STM32F7_OTG_DESCSIZE);
+ if (!alloc)
+ {
+ return -ENOMEM;
+ }
+
+ /* Return the allocated address and size of the descriptor buffer */
+
+ *buffer = alloc;
+ *maxlen = CONFIG_STM32F7_OTG_DESCSIZE;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_free
+ *
+ * Description:
+ * Some hardware supports special memory in which request and descriptor data can
+ * be accessed more efficiently. This method provides a mechanism to free that
+ * request/descriptor memory. If the underlying hardware does not support
+ * such "special" memory, this functions may simply map to kmm_free().
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * buffer - The address of the allocated buffer memory to be freed.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * - Never called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int stm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer)
+{
+ /* There is no special memory requirement */
+
+ DEBUGASSERT(drvr && buffer);
+ kmm_free(buffer);
+ return OK;
+}
+
+/************************************************************************************
+ * Name: stm32_ioalloc
+ *
+ * Description:
+ * Some hardware supports special memory in which larger IO buffers can
+ * be accessed more efficiently. This method provides a mechanism to allocate
+ * the request/descriptor memory. If the underlying hardware does not support
+ * such "special" memory, this functions may simply map to kmm_malloc.
+ *
+ * This interface differs from DRVR_ALLOC in that the buffers are variable-sized.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * buffer - The address of a memory location provided by the caller in which to
+ * return the allocated buffer memory address.
+ * buflen - The size of the buffer required.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ************************************************************************************/
+
+static int stm32_ioalloc(FAR struct usbhost_driver_s *drvr,
+ FAR uint8_t **buffer, size_t buflen)
+{
+ FAR uint8_t *alloc;
+
+ DEBUGASSERT(drvr && buffer && buflen > 0);
+
+ /* There is no special memory requirement */
+
+ alloc = (FAR uint8_t *)kmm_malloc(buflen);
+ if (!alloc)
+ {
+ return -ENOMEM;
+ }
+
+ /* Return the allocated buffer */
+
+ *buffer = alloc;
+ return OK;
+}
+
+/************************************************************************************
+ * Name: stm32_iofree
+ *
+ * Description:
+ * Some hardware supports special memory in which IO data can be accessed more
+ * efficiently. This method provides a mechanism to free that IO buffer
+ * memory. If the underlying hardware does not support such "special" memory,
+ * this functions may simply map to kmm_free().
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * buffer - The address of the allocated buffer memory to be freed.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * This function will *not* be called from an interrupt handler.
+ *
+ ************************************************************************************/
+
+static int stm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer)
+{
+ /* There is no special memory requirement */
+
+ DEBUGASSERT(drvr && buffer);
+ kmm_free(buffer);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_ctrlin and stm32_ctrlout
+ *
+ * Description:
+ * Process a IN or OUT request on the control endpoint. These methods
+ * will enqueue the request and wait for it to complete. Only one transfer may be
+ * queued; Neither these methods nor the transfer() method can be called again
+ * until the control transfer functions returns.
+ *
+ * These are blocking methods; these functions will not return until the
+ * control transfer has completed.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * ep0 - The control endpoint to send/receive the control request.
+ * req - Describes the request to be sent. This request must lie in memory
+ * created by DRVR_ALLOC.
+ * buffer - A buffer used for sending the request and for returning any
+ * responses. This buffer must be large enough to hold the length value
+ * in the request description. buffer must have been allocated using DRVR_ALLOC.
+ *
+ * NOTE: On an IN transaction, req and buffer may refer to the same allocated
+ * memory.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static int stm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR uint8_t *buffer)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0;
+ uint16_t buflen;
+ systime_t start;
+ systime_t elapsed;
+ int retries;
+ int ret;
+
+ DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL);
+ usbhost_vtrace2(OTG_VTRACE2_CTRLIN, req->type, req->req);
+ uinfo("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n",
+ req->type, req->req, req->value[1], req->value[0],
+ req->index[1], req->index[0], req->len[1], req->len[0]);
+
+ /* Extract values from the request */
+
+ buflen = stm32_getle16(req->len);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Loop, retrying until the retry time expires */
+
+ for (retries = 0; retries < STM32_RETRY_COUNT; retries++)
+ {
+ /* Send the SETUP request */
+
+ ret = stm32_ctrl_sendsetup(priv, ep0info, req);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_SENDSETUP, -ret);
+ continue;
+ }
+
+ /* Get the start time. Loop again until the timeout expires */
+
+ start = clock_systimer();
+ do
+ {
+ /* Handle the IN data phase (if any) */
+
+ if (buflen > 0)
+ {
+ ret = stm32_ctrl_recvdata(priv, ep0info, buffer, buflen);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_RECVDATA, -ret);
+ }
+ }
+
+ /* Handle the status OUT phase */
+
+ if (ret == OK)
+ {
+ priv->chan[ep0info->outndx].outdata1 ^= true;
+ ret = stm32_ctrl_senddata(priv, ep0info, NULL, 0);
+ if (ret == OK)
+ {
+ /* All success transactions exit here */
+
+ stm32_givesem(&priv->exclsem);
+ return OK;
+ }
+
+ usbhost_trace1(OTG_TRACE1_SENDDATA, ret < 0 ? -ret : ret);
+ }
+
+ /* Get the elapsed time (in frames) */
+
+ elapsed = clock_systimer() - start;
+ }
+ while (elapsed < STM32_DATANAK_DELAY);
+ }
+
+ /* All failures exit here after all retries and timeouts have been exhausted */
+
+ stm32_givesem(&priv->exclsem);
+ return -ETIMEDOUT;
+}
+
+static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
+ FAR const struct usb_ctrlreq_s *req,
+ FAR const uint8_t *buffer)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0;
+ uint16_t buflen;
+ systime_t start;
+ systime_t elapsed;
+ int retries;
+ int ret;
+
+ DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL);
+ usbhost_vtrace2(OTG_VTRACE2_CTRLOUT, req->type, req->req);
+ uinfo("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n",
+ req->type, req->req, req->value[1], req->value[0],
+ req->index[1], req->index[0], req->len[1], req->len[0]);
+
+ /* Extract values from the request */
+
+ buflen = stm32_getle16(req->len);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Loop, retrying until the retry time expires */
+
+ for (retries = 0; retries < STM32_RETRY_COUNT; retries++)
+ {
+ /* Send the SETUP request */
+
+ ret = stm32_ctrl_sendsetup(priv, ep0info, req);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_SENDSETUP, -ret);
+ continue;
+ }
+
+ /* Get the start time. Loop again until the timeout expires */
+
+ start = clock_systimer();
+ do
+ {
+ /* Handle the data OUT phase (if any) */
+
+ if (buflen > 0)
+ {
+ /* Start DATA out transfer (only one DATA packet) */
+
+ priv->chan[ep0info->outndx].outdata1 = true;
+ ret = stm32_ctrl_senddata(priv, ep0info, NULL, 0);
+ if (ret < 0)
+ {
+ usbhost_trace1(OTG_TRACE1_SENDDATA, -ret);
+ }
+ }
+
+ /* Handle the status IN phase */
+
+ if (ret == OK)
+ {
+ ret = stm32_ctrl_recvdata(priv, ep0info, NULL, 0);
+ if (ret == OK)
+ {
+ /* All success transactins exit here */
+
+ stm32_givesem(&priv->exclsem);
+ return OK;
+ }
+
+ usbhost_trace1(OTG_TRACE1_RECVDATA, ret < 0 ? -ret : ret);
+ }
+
+ /* Get the elapsed time (in frames) */
+
+ elapsed = clock_systimer() - start;
+ }
+ while (elapsed < STM32_DATANAK_DELAY);
+ }
+
+ /* All failures exit here after all retries and timeouts have been exhausted */
+
+ stm32_givesem(&priv->exclsem);
+ return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: stm32_transfer
+ *
+ * Description:
+ * Process a request to handle a transfer descriptor. This method will
+ * enqueue the transfer request, blocking until the transfer completes. Only
+ * one transfer may be queued; Neither this method nor the ctrlin or
+ * ctrlout methods can be called again until this function returns.
+ *
+ * This is a blocking method; this functions will not return until the
+ * transfer has completed.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * ep - The IN or OUT endpoint descriptor for the device endpoint on which to
+ * perform the transfer.
+ * buffer - A buffer containing the data to be sent (OUT endpoint) or received
+ * (IN endpoint). buffer must have been allocated using DRVR_ALLOC
+ * buflen - The length of the data to be sent or received.
+ *
+ * Returned Values:
+ * On success, a non-negative value is returned that indicates the number
+ * of bytes successfully transferred. On a failure, a negated errno value is
+ * returned that indicates the nature of the failure:
+ *
+ * EAGAIN - If devices NAKs the transfer (or NYET or other error where
+ * it may be appropriate to restart the entire transaction).
+ * EPERM - If the endpoint stalls
+ * EIO - On a TX or data toggle error
+ * EPIPE - Overrun errors
+ *
+ * Assumptions:
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static ssize_t stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
+ FAR uint8_t *buffer, size_t buflen)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ unsigned int chidx = (unsigned int)ep;
+ ssize_t nbytes;
+
+ uinfo("chidx: %d buflen: %d\n", (unsigned int)ep, buflen);
+
+ DEBUGASSERT(priv && buffer && chidx < STM32_MAX_TX_FIFOS && buflen > 0);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Handle IN and OUT transfer slightly differently */
+
+ if (priv->chan[chidx].in)
+ {
+ nbytes = stm32_in_transfer(priv, chidx, buffer, buflen);
+ }
+ else
+ {
+ nbytes = stm32_out_transfer(priv, chidx, buffer, buflen);
+ }
+
+ stm32_givesem(&priv->exclsem);
+ return nbytes;
+}
+
+/****************************************************************************
+ * Name: stm32_asynch
+ *
+ * Description:
+ * Process a request to handle a transfer descriptor. This method will
+ * enqueue the transfer request and return immediately. When the transfer
+ * completes, the the callback will be invoked with the provided transfer.
+ * This method is useful for receiving interrupt transfers which may come
+ * infrequently.
+ *
+ * Only one transfer may be queued; Neither this method nor the ctrlin or
+ * ctrlout methods can be called again until the transfer completes.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * ep - The IN or OUT endpoint descriptor for the device endpoint on which to
+ * perform the transfer.
+ * buffer - A buffer containing the data to be sent (OUT endpoint) or received
+ * (IN endpoint). buffer must have been allocated using DRVR_ALLOC
+ * buflen - The length of the data to be sent or received.
+ * callback - This function will be called when the transfer completes.
+ * arg - The arbitrary parameter that will be passed to the callback function
+ * when the transfer completes.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure
+ *
+ * Assumptions:
+ * - Called from a single thread so no mutual exclusion is required.
+ * - Never called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_USBHOST_ASYNCH
+static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
+ FAR uint8_t *buffer, size_t buflen,
+ usbhost_asynch_t callback, FAR void *arg)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ unsigned int chidx = (unsigned int)ep;
+ int ret;
+
+ uinfo("chidx: %d buflen: %d\n", (unsigned int)ep, buflen);
+
+ DEBUGASSERT(priv && buffer && chidx < STM32_MAX_TX_FIFOS && buflen > 0);
+
+ /* We must have exclusive access to the USB host hardware and state structures */
+
+ stm32_takesem(&priv->exclsem);
+
+ /* Handle IN and OUT transfer slightly differently */
+
+ if (priv->chan[chidx].in)
+ {
+ ret = stm32_in_asynch(priv, chidx, buffer, buflen, callback, arg);
+ }
+ else
+ {
+ ret = stm32_out_asynch(priv, chidx, buffer, buflen, callback, arg);
+ }
+
+ stm32_givesem(&priv->exclsem);
+ return ret;
+}
+#endif /* CONFIG_USBHOST_ASYNCH */
+
+/************************************************************************************
+ * Name: stm32_cancel
+ *
+ * Description:
+ * Cancel a pending transfer on an endpoint. Cancelled synchronous or
+ * asynchronous transfer will complete normally with the error -ESHUTDOWN.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * ep - The IN or OUT endpoint descriptor for the device endpoint on which an
+ * asynchronous transfer should be transferred.
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure.
+ *
+ ************************************************************************************/
+
+static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ FAR struct stm32_chan_s *chan;
+ unsigned int chidx = (unsigned int)ep;
+ irqstate_t flags;
+
+ uinfo("chidx: %u: %d\n", chidx);
+
+ DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS);
+ chan = &priv->chan[chidx];
+
+ /* We need to disable interrupts to avoid race conditions with the asynchronous
+ * completion of the transfer being cancelled.
+ */
+
+ flags = enter_critical_section();
+
+ /* Halt the channel */
+
+ stm32_chan_halt(priv, chidx, CHREASON_CANCELLED);
+ chan->result = -ESHUTDOWN;
+
+ /* Is there a thread waiting for this transfer to complete? */
+
+ if (chan->waiter)
+ {
+#ifdef CONFIG_USBHOST_ASYNCH
+ /* Yes.. there should not also be a callback scheduled */
+
+ DEBUGASSERT(chan->callback == NULL);
+#endif
+
+ /* Wake'em up! */
+
+ stm32_givesem(&chan->waitsem);
+ chan->waiter = false;
+ }
+
+#ifdef CONFIG_USBHOST_ASYNCH
+ /* No.. is an asynchronous callback expected when the transfer
+ * completes?
+ */
+
+ else if (chan->callback)
+ {
+ usbhost_asynch_t callback;
+ FAR void *arg;
+
+ /* Extract the callback information */
+
+ callback = chan->callback;
+ arg = chan->arg;
+
+ chan->callback = NULL;
+ chan->arg = NULL;
+ chan->xfrd = 0;
+
+ /* Then perform the callback */
+
+ callback(arg, -ESHUTDOWN);
+ }
+#endif
+
+ leave_critical_section(flags);
+ return OK;
+}
+
+/************************************************************************************
+ * Name: stm32_connect
+ *
+ * Description:
+ * New connections may be detected by an attached hub. This method is the
+ * mechanism that is used by the hub class to introduce a new connection
+ * and port description to the system.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * hport - The descriptor of the hub port that detected the connection
+ * related event
+ * connected - True: device connected; false: device disconnected
+ *
+ * Returned Values:
+ * On success, zero (OK) is returned. On a failure, a negated errno value is
+ * returned indicating the nature of the failure.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_USBHOST_HUB
+static int stm32_connect(FAR struct usbhost_driver_s *drvr,
+ FAR struct usbhost_hubport_s *hport,
+ bool connected)
+{
+ FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
+ irqstate_t flags;
+
+ DEBUGASSERT(priv != NULL && hport != NULL);
+
+ /* Set the connected/disconnected flag */
+
+ hport->connected = connected;
+ uinfo("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO");
+
+ /* Report the connection event */
+
+ flags = enter_critical_section();
+ priv->hport = hport;
+ if (priv->pscwait)
+ {
+ priv->pscwait = false;
+ stm32_givesem(&priv->pscsem);
+ }
+
+ leave_critical_section(flags);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_disconnect
+ *
+ * Description:
+ * Called by the class when an error occurs and driver has been disconnected.
+ * The USB host driver should discard the handle to the class instance (it is
+ * stale) and not attempt any further interaction with the class driver instance
+ * (until a new instance is received from the create() method). The driver
+ * should not called the class' disconnected() method.
+ *
+ * Input Parameters:
+ * drvr - The USB host driver instance obtained as a parameter from the call to
+ * the class create() method.
+ * hport - The port from which the device is being disconnected. Might be a port
+ * on a hub.
+ *
+ * Returned Values:
+ * None
+ *
+ * Assumptions:
+ * - Only a single class bound to a single device is supported.
+ * - Never called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static void stm32_disconnect(FAR struct usbhost_driver_s *drvr,
+ FAR struct usbhost_hubport_s *hport)
+{
+ DEBUGASSERT(hport != NULL);
+ hport->devclass = NULL;
+}
+
+/****************************************************************************
+ * Initialization
+ ****************************************************************************/
+/****************************************************************************
+ * Name: stm32_portreset
+ *
+ * Description:
+ * Reset the USB host port.
+ *
+ * NOTE: "Before starting to drive a USB reset, the application waits for the
+ * OTG interrupt triggered by the debounce done bit (DBCDNE bit in
+ * OTG_FS_GOTGINT), which indicates that the bus is stable again after the
+ * electrical debounce caused by the attachment of a pull-up resistor on DP
+ * (FS) or DM (LS).
+ *
+ * Input Parameters:
+ * priv -- USB host driver private data structure.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void stm32_portreset(FAR struct stm32_usbhost_s *priv)
+{
+ uint32_t regval;
+
+ regval = stm32_getreg(STM32_OTG_HPRT);
+ regval &= ~(OTG_HPRT_PENA | OTG_HPRT_PCDET | OTG_HPRT_PENCHNG |
+ OTG_HPRT_POCCHNG);
+ regval |= OTG_HPRT_PRST;
+ stm32_putreg(STM32_OTG_HPRT, regval);
+
+ up_mdelay(20);
+
+ regval &= ~OTG_HPRT_PRST;
+ stm32_putreg(STM32_OTG_HPRT, regval);
+
+ up_mdelay(20);
+}
+
+/****************************************************************************
+ * Name: stm32_flush_txfifos
+ *
+ * Description:
+ * Flush the selected Tx FIFO.
+ *
+ * Input Parameters:
+ * txfnum -- USB host driver private data structure.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void stm32_flush_txfifos(uint32_t txfnum)
+{
+ uint32_t regval;
+ uint32_t timeout;
+
+ /* Initiate the TX FIFO flush operation */
+
+ regval = OTG_GRSTCTL_TXFFLSH | txfnum;
+ stm32_putreg(STM32_OTG_GRSTCTL, regval);
+
+ /* Wait for the FLUSH to complete */
+
+ for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++)
+ {
+ regval = stm32_getreg(STM32_OTG_GRSTCTL);
+ if ((regval & OTG_GRSTCTL_TXFFLSH) == 0)
+ {
+ break;
+ }
+ }
+
+ /* Wait for 3 PHY Clocks */
+
+ up_udelay(3);
+}
+
+/****************************************************************************
+ * Name: stm32_flush_rxfifo
+ *
+ * Description:
+ * Flush the Rx FIFO.
+ *
+ * Input Parameters:
+ * priv -- USB host driver private data structure.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void stm32_flush_rxfifo(void)
+{
+ uint32_t regval;
+ uint32_t timeout;
+
+ /* Initiate the RX FIFO flush operation */
+
+ stm32_putreg(STM32_OTG_GRSTCTL, OTG_GRSTCTL_RXFFLSH);
+
+ /* Wait for the FLUSH to complete */
+
+ for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++)
+ {
+ regval = stm32_getreg(STM32_OTG_GRSTCTL);
+ if ((regval & OTG_GRSTCTL_RXFFLSH) == 0)
+ {
+ break;
+ }
+ }
+
+ /* Wait for 3 PHY Clocks */
+
+ up_udelay(3);
+}
+
+/****************************************************************************
+ * Name: stm32_vbusdrive
+ *
+ * Description:
+ * Drive the Vbus +5V.
+ *
+ * Input Parameters:
+ * priv - USB host driver private data structure.
+ * state - True: Drive, False: Don't drive
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void stm32_vbusdrive(FAR struct stm32_usbhost_s *priv, bool state)
+{
+ uint32_t regval;
+
+ /* Enable/disable the external charge pump */
+
+ stm32_usbhost_vbusdrive(0, state);
+
+ /* Turn on the Host port power. */
+
+ regval = stm32_getreg(STM32_OTG_HPRT);
+ regval &= ~(OTG_HPRT_PENA | OTG_HPRT_PCDET | OTG_HPRT_PENCHNG |
+ OTG_HPRT_POCCHNG);
+
+ if (((regval & OTG_HPRT_PPWR) == 0) && state)
+ {
+ regval |= OTG_HPRT_PPWR;
+ stm32_putreg(STM32_OTG_HPRT, regval);
+ }
+
+ if (((regval & OTG_HPRT_PPWR) != 0) && !state)
+ {
+ regval &= ~OTG_HPRT_PPWR;
+ stm32_putreg(STM32_OTG_HPRT, regval);
+ }
+
+ up_mdelay(200);
+}
+
+/****************************************************************************
+ * Name: stm32_host_initialize
+ *
+ * Description:
+ * Initialize/re-initialize hardware for host mode operation. At present,
+ * this function is called only from stm32_hw_initialize(). But if OTG mode
+ * were supported, this function would also be called to swtich between
+ * host and device modes on a connector ID change interrupt.
+ *
+ * Input Parameters:
+ * priv -- USB host driver private data structure.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv)
+{
+ uint32_t regval;
+ uint32_t offset;
+ int i;
+
+ /* Restart the PHY Clock */
+
+ stm32_putreg(STM32_OTG_PCGCCTL, 0);
+
+ /* Initialize Host Configuration (HCFG) register */
+
+ regval = stm32_getreg(STM32_OTG_HCFG);
+ regval &= ~OTG_HCFG_FSLSPCS_MASK;
+ regval |= OTG_HCFG_FSLSPCS_FS48MHz;
+ stm32_putreg(STM32_OTG_HCFG, regval);
+
+ /* Reset the host port */
+
+ stm32_portreset(priv);
+
+ /* Clear the FS-/LS-only support bit in the HCFG register */
+
+ regval = stm32_getreg(STM32_OTG_HCFG);
+ regval &= ~OTG_HCFG_FSLSS;
+ stm32_putreg(STM32_OTG_HCFG, regval);
+
+ /* Carve up FIFO memory for the Rx FIFO and the periodic and non-periodic Tx FIFOs */
+ /* Configure Rx FIFO size (GRXFSIZ) */
+
+ stm32_putreg(STM32_OTG_GRXFSIZ, CONFIG_STM32F7_OTG_RXFIFO_SIZE);
+ offset = CONFIG_STM32F7_OTG_RXFIFO_SIZE;
+
+ /* Setup the host non-periodic Tx FIFO size (HNPTXFSIZ) */
+
+ regval = (offset | (CONFIG_STM32F7_OTG_NPTXFIFO_SIZE << OTG_HNPTXFSIZ_NPTXFD_SHIFT));
+ stm32_putreg(STM32_OTG_HNPTXFSIZ, regval);
+ offset += CONFIG_STM32F7_OTG_NPTXFIFO_SIZE;
+
+ /* Set up the host periodic Tx fifo size register (HPTXFSIZ) */
+
+ regval = (offset | (CONFIG_STM32F7_OTG_PTXFIFO_SIZE << OTG_HPTXFSIZ_PTXFD_SHIFT));
+ stm32_putreg(STM32_OTG_HPTXFSIZ, regval);
+
+ /* If OTG were supported, we sould need to clear HNP enable bit in the
+ * USB_OTG control register about here.
+ */
+
+ /* Flush all FIFOs */
+
+ stm32_flush_txfifos(OTG_GRSTCTL_TXFNUM_HALL);
+ stm32_flush_rxfifo();
+
+ /* Clear all pending HC Interrupts */
+
+ for (i = 0; i < STM32_NHOST_CHANNELS; i++)
+ {
+ stm32_putreg(STM32_OTG_HCINT(i), 0xffffffff);
+ stm32_putreg(STM32_OTG_HCINTMSK(i), 0);
+ }
+
+ /* Driver Vbus +5V (the smoke test). Should be done elsewhere in OTG
+ * mode.
+ */
+
+ stm32_vbusdrive(priv, true);
+
+ /* Enable host interrupts */
+
+ stm32_hostinit_enable();
+}
+
+/****************************************************************************
+ * Name: stm32_sw_initialize
+ *
+ * Description:
+ * One-time setup of the host driver state structure.
+ *
+ * Input Parameters:
+ * priv -- USB host driver private data structure.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv)
+{
+ FAR struct usbhost_driver_s *drvr;
+ FAR struct usbhost_hubport_s *hport;
+ int i;
+
+ /* Initialize the device operations */
+
+ drvr = &priv->drvr;
+ drvr->ep0configure = stm32_ep0configure;
+ drvr->epalloc = stm32_epalloc;
+ drvr->epfree = stm32_epfree;
+ drvr->alloc = stm32_alloc;
+ drvr->free = stm32_free;
+ drvr->ioalloc = stm32_ioalloc;
+ drvr->iofree = stm32_iofree;
+ drvr->ctrlin = stm32_ctrlin;
+ drvr->ctrlout = stm32_ctrlout;
+ drvr->transfer = stm32_transfer;
+#ifdef CONFIG_USBHOST_ASYNCH
+ drvr->asynch = stm32_asynch;
+#endif
+ drvr->cancel = stm32_cancel;
+#ifdef CONFIG_USBHOST_HUB
+ drvr->connect = stm32_connect;
+#endif
+ drvr->disconnect = stm32_disconnect;
+
+ /* Initialize the public port representation */
+
+ hport = &priv->rhport.hport;
+ hport->drvr = drvr;
+#ifdef CONFIG_USBHOST_HUB
+ hport->parent = NULL;
+#endif
+ hport->ep0 = (usbhost_ep_t)&priv->ep0;
+ hport->speed = USB_SPEED_FULL;
+
+ /* Initialize function address generation logic */
+
+ usbhost_devaddr_initialize(&priv->rhport);
+
+ /* Initialize semaphores */
+
+ sem_init(&priv->pscsem, 0, 0);
+ sem_init(&priv->exclsem, 0, 1);
+
+ /* Initialize the driver state data */
+
+ priv->smstate = SMSTATE_DETACHED;
+ priv->connected = false;
+ priv->change = false;
+
+ /* Put all of the channels back in their initial, allocated state */
+
+ memset(priv->chan, 0, STM32_MAX_TX_FIFOS * sizeof(struct stm32_chan_s));
+
+ /* Initialize each channel */
+
+ for (i = 0; i < STM32_MAX_TX_FIFOS; i++)
+ {
+ FAR struct stm32_chan_s *chan = &priv->chan[i];
+ chan->chidx = i;
+ sem_init(&chan->waitsem, 0, 0);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_hw_initialize
+ *
+ * Description:
+ * One-time setup of the host controller harware for normal operations.
+ *
+ * Input Parameters:
+ * priv -- USB host driver private data structure.
+ *
+ * Returned Value:
+ * Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv)
+{
+ uint32_t regval;
+ unsigned long timeout;
+
+ /* Set the PHYSEL bit in the GUSBCFG register to select the OTG FS serial
+ * transceiver: "This bit is always 1 with write-only access"
+ */
+
+ regval = stm32_getreg(STM32_OTG_GUSBCFG);
+ regval |= OTG_GUSBCFG_PHYSEL;
+ stm32_putreg(STM32_OTG_GUSBCFG, regval);
+
+ /* Reset after a PHY select and set Host mode. First, wait for AHB master
+ * IDLE state.
+ */
+
+ for (timeout = 0; timeout < STM32_READY_DELAY; timeout++)
+ {
+ up_udelay(3);
+ regval = stm32_getreg(STM32_OTG_GRSTCTL);
+ if ((regval & OTG_GRSTCTL_AHBIDL) != 0)
+ {
+ break;
+ }
+ }
+
+ /* Then perform the core soft reset. */
+
+ stm32_putreg(STM32_OTG_GRSTCTL, OTG_GRSTCTL_CSRST);
+ for (timeout = 0; timeout < STM32_READY_DELAY; timeout++)
+ {
+ regval = stm32_getreg(STM32_OTG_GRSTCTL);
+ if ((regval & OTG_GRSTCTL_CSRST) == 0)
+ {
+ break;
+ }
+ }
+
+ /* Wait for 3 PHY Clocks */
+
+ up_udelay(3);
+
+ /* Deactivate the power down */
+
+ regval = (OTG_GCCFG_PWRDWN | OTG_GCCFG_VBUSASEN | OTG_GCCFG_VBUSBSEN);
+#ifndef CONFIG_USBDEV_VBUSSENSING
+ regval |= OTG_GCCFG_NOVBUSSENS;
+#endif
+#ifdef CONFIG_STM32F7_OTG_SOFOUTPUT
+ regval |= OTG_GCCFG_SOFOUTEN;
+#endif
+ stm32_putreg(STM32_OTG_GCCFG, regval);
+ up_mdelay(20);
+
+ /* Initialize OTG features: In order to support OTP, the HNPCAP and SRPCAP
+ * bits would need to be set in the GUSBCFG register about here.
+ */
+
+ /* Force Host Mode */
+
+ regval = stm32_getreg(STM32_OTG_GUSBCFG);
+ regval &= ~OTG_GUSBCFG_FDMOD;
+ regval |= OTG_GUSBCFG_FHMOD;
+ stm32_putreg(STM32_OTG_GUSBCFG, regval);
+ up_mdelay(50);
+
+ /* Initialize host mode and return success */
+
+ stm32_host_initialize(priv);
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_otgfshost_initialize
+ *
+ * Description:
+ * Initialize USB host device controller hardware.
+ *
+ * Input Parameters:
+ * controller -- If the device supports more than USB host controller, then
+ * this identifies which controller is being initialized. Normally, this
+ * is just zero.
+ *
+ * Returned Value:
+ * And instance of the USB host interface. The controlling task should
+ * use this interface to (1) call the wait() method to wait for a device
+ * to be connected, and (2) call the enumerate() method to bind the device
+ * to a class driver.
+ *
+ * Assumptions:
+ * - This function should called in the initialization sequence in order
+ * to initialize the USB device functionality.
+ * - Class drivers should be initialized prior to calling this function.
+ * Otherwise, there is a race condition if the device is already connected.
+ *
+ ****************************************************************************/
+
+FAR struct usbhost_connection_s *stm32_otgfshost_initialize(int controller)
+{
+ /* At present, there is only support for a single OTG FS host. Hence it is
+ * pre-allocated as g_usbhost. However, in most code, the private data
+ * structure will be referenced using the 'priv' pointer (rather than the
+ * global data) in order to simplify any future support for multiple devices.
+ */
+
+ FAR struct stm32_usbhost_s *priv = &g_usbhost;
+
+ /* Sanity checks */
+
+ DEBUGASSERT(controller == 0);
+
+ /* Make sure that interrupts from the OTG FS core are disabled */
+
+ stm32_gint_disable();
+
+ /* Reset the state of the host driver */
+
+ stm32_sw_initialize(priv);
+
+ /* Alternate function pin configuration. Here we assume that:
+ *
+ * 1. GPIOA, SYSCFG, and OTG FS peripheral clocking have already been\
+ * enabled as part of the boot sequence.
+ * 2. Board-specific logic has already enabled other board specific GPIOs
+ * for things like soft pull-up, VBUS sensing, power controls, and over-
+ * current detection.
+ */
+
+ /* Configure OTG FS alternate function pins for DM, DP, ID, and SOF.
+ *
+ * PIN* SIGNAL DIRECTION
+ * ---- ----------- ----------
+ * PA8 OTG_FS_SOF SOF clock output
+ * PA9 OTG_FS_VBUS VBUS input for device, Driven by external regulator by
+ * host (not an alternate function)
+ * PA10 OTG_FS_ID OTG ID pin (only needed in Dual mode)
+ * PA11 OTG_FS_DM D- I/O
+ * PA12 OTG_FS_DP D+ I/O
+ *
+ * *Pins may vary from device-to-device.
+ */
+
+ stm32_configgpio(GPIO_OTG_DM);
+ stm32_configgpio(GPIO_OTG_DP);
+ stm32_configgpio(GPIO_OTG_ID); /* Only needed for OTG */
+
+ /* SOF output pin configuration is configurable */
+
+#ifdef CONFIG_STM32F7_OTG_SOFOUTPUT
+ stm32_configgpio(GPIO_OTG_SOF);
+#endif
+
+ /* Initialize the USB OTG FS core */
+
+ stm32_hw_initialize(priv);
+
+ /* Attach USB host controller interrupt handler */
+
+ if (irq_attach(STM32_IRQ_OTGFS, stm32_gint_isr) != 0)
+ {
+ usbhost_trace1(OTG_TRACE1_IRQATTACH, 0);
+ return NULL;
+ }
+
+ /* Enable USB OTG FS global interrupts */
+
+ stm32_gint_enable();
+
+ /* Enable interrupts at the interrupt controller */
+
+ up_enable_irq(STM32_IRQ_OTGFS);
+ return &g_usbconn;
+}
+
+#endif /* CONFIG_USBHOST && CONFIG_STM32F7_OTGFS */
diff --git a/arch/arm/src/stm32f7/stm32_pwr.c b/arch/arm/src/stm32f7/stm32_pwr.c
new file mode 100644
index 0000000000000000000000000000000000000000..961eaf438097dd6bea8cb31309bca0d5ba498d00
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_pwr.c
@@ -0,0 +1,260 @@
+/************************************************************************************
+ * arch/arm/src/stm32f7/stm32_pwr.c
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved.
+ * Authors: Uros Platise
+ * Gregory Nutt
+ * David Sidrane
+ *
+ * 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
+#include
+
+#include
+#include
+#include
+
+#include "up_arch.h"
+#include "stm32_pwr.h"
+
+#if defined(CONFIG_STM32F7_PWR)
+
+/************************************************************************************
+ * Private Functions
+ ************************************************************************************/
+
+static inline uint16_t stm32_pwr_getreg(uint8_t offset)
+{
+ return (uint16_t)getreg32(STM32_PWR_BASE + (uint32_t)offset);
+}
+
+static inline void stm32_pwr_putreg(uint8_t offset, uint16_t value)
+{
+ putreg32((uint32_t)value, STM32_PWR_BASE + (uint32_t)offset);
+}
+
+static inline void stm32_pwr_modifyreg(uint8_t offset, uint16_t clearbits, uint16_t setbits)
+{
+ modifyreg32(STM32_PWR_BASE + (uint32_t)offset, (uint32_t)clearbits, (uint32_t)setbits);
+}
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_pwr_enablebkp
+ *
+ * Description:
+ * Enables access to the backup domain (RTC registers, RTC backup data registers
+ * and backup SRAM).
+ *
+ * Input Parameters:
+ * writable - True: enable ability to write to backup domain registers
+ *
+ * Returned Value:
+ * True: The backup domain was previously writable.
+ *
+ ************************************************************************************/
+
+bool stm32_pwr_enablebkp(bool writable)
+{
+ uint16_t regval;
+ bool waswritable;
+
+ /* Get the current state of the STM32 PWR control register */
+
+ regval = stm32_pwr_getreg(STM32_PWR_CR1_OFFSET);
+ waswritable = ((regval & PWR_CR1_DBP) != 0);
+
+ /* Enable or disable the ability to write */
+
+ if (waswritable && !writable)
+ {
+ /* Disable backup domain access */
+
+ regval &= ~PWR_CR1_DBP;
+ stm32_pwr_putreg(STM32_PWR_CR1_OFFSET, regval);
+ }
+ else if (!waswritable && writable)
+ {
+ /* Enable backup domain access */
+
+ regval |= PWR_CR1_DBP;
+ stm32_pwr_putreg(STM32_PWR_CR1_OFFSET, regval);
+
+ /* Enable does not happen right away */
+
+ up_udelay(4);
+ }
+
+ return waswritable;
+}
+
+/************************************************************************************
+ * Name: stm32_pwr_enablebreg
+ *
+ * Description:
+ * Enables the Backup regulator, the Backup regulator (used to maintain backup
+ * SRAM content in Standby and VBAT modes) is enabled. If BRE is reset, the backup
+ * regulator is switched off. The backup SRAM can still be used but its content will
+ * be lost in the Standby and VBAT modes. Once set, the application must wait that
+ * the Backup Regulator Ready flag (BRR) is set to indicate that the data written
+ * into the RAM will be maintained in the Standby and VBAT modes.
+ *
+ * Input Parameters:
+ * regon - state to set it to
+ *
+ * Returned Values:
+ * None
+ *
+ ************************************************************************************/
+
+void stm32_pwr_enablebreg(bool regon)
+{
+ uint16_t regval;
+
+ regval = stm32_pwr_getreg(STM32_PWR_CSR1_OFFSET);
+ regval &= ~PWR_CSR1_BRE;
+ regval |= regon ? PWR_CSR1_BRE : 0;
+ stm32_pwr_putreg(STM32_PWR_CSR1_OFFSET, regval);
+
+ if (regon)
+ {
+ while ((stm32_pwr_getreg(STM32_PWR_CSR1_OFFSET) & PWR_CSR1_BRR) == 0);
+ }
+}
+
+/************************************************************************************
+ * Name: stm32_pwr_setvos
+ *
+ * Description:
+ * Set voltage scaling.
+ *
+ * Input Parameters:
+ * vos - Properly aligned voltage scaling select bits for the PWR_CR register.
+ *
+ * Returned Values:
+ * None
+ *
+ * Assumptions:
+ * At present, this function is called only from initialization logic. If used
+ * for any other purpose that protection to assure that its operation is atomic
+ * will be required.
+ *
+ ************************************************************************************/
+
+void stm32_pwr_setvos(uint16_t vos)
+{
+ uint16_t regval;
+
+ /* The following sequence is required to program the voltage regulator ranges:
+ * 1. Check VDD to identify which ranges are allowed...
+ * 2. Configure the voltage scaling range by setting the VOS bits in the PWR_CR1
+ * register.
+ */
+
+ regval = stm32_pwr_getreg(STM32_PWR_CR1_OFFSET);
+ regval &= ~PWR_CR1_VOS_MASK;
+ regval |= (vos & PWR_CR1_VOS_MASK);
+ stm32_pwr_putreg(STM32_PWR_CR1_OFFSET, regval);
+}
+
+/************************************************************************************
+ * Name: stm32_pwr_setpvd
+ *
+ * Description:
+ * Sets power voltage detector
+ *
+ * Input Parameters:
+ * pls - PVD level
+ *
+ * Returned Values:
+ * None
+ *
+ * Assumptions:
+ * At present, this function is called only from initialization logic. If used
+ * for any other purpose that protection to assure that its operation is atomic
+ * will be required.
+ *
+ ************************************************************************************/
+
+void stm32_pwr_setpvd(uint16_t pls)
+{
+ uint16_t regval;
+
+ /* Set PLS */
+
+ regval = stm32_pwr_getreg(STM32_PWR_CR1_OFFSET);
+ regval &= ~PWR_CR1_PLS_MASK;
+ regval |= (pls & PWR_CR1_PLS_MASK);
+
+ /* Write value to register */
+
+ stm32_pwr_putreg(STM32_PWR_CR1_OFFSET, regval);
+}
+
+/************************************************************************************
+ * Name: stm32_pwr_enablepvd
+ *
+ * Description:
+ * Enable the Programmable Voltage Detector
+ *
+ ************************************************************************************/
+
+void stm32_pwr_enablepvd(void)
+{
+ /* Enable PVD by setting the PVDE bit in PWR_CR register. */
+
+ stm32_pwr_modifyreg(STM32_PWR_CR1_OFFSET, 0, PWR_CR1_PVDE);
+}
+
+/************************************************************************************
+ * Name: stm32_pwr_disablepvd
+ *
+ * Description:
+ * Disable the Programmable Voltage Detector
+ *
+ ************************************************************************************/
+
+void stm32_pwr_disablepvd(void)
+{
+ /* Disable PVD by clearing the PVDE bit in PWR_CR register. */
+
+ stm32_pwr_modifyreg(STM32_PWR_CR1_OFFSET, PWR_CR1_PVDE, 0);
+}
+
+#endif /* CONFIG_STM32_PWR */
diff --git a/arch/arm/src/stm32f7/stm32_pwr.h b/arch/arm/src/stm32f7/stm32_pwr.h
index 3c5a30f96738676775413bc07942eb930ffd28d7..772851d524d657355206a98323ee57249d3f8c6e 100644
--- a/arch/arm/src/stm32f7/stm32_pwr.h
+++ b/arch/arm/src/stm32f7/stm32_pwr.h
@@ -1,8 +1,9 @@
/************************************************************************************
* arch/arm/src/stm32f7/stm32_pwr.h
*
- * Copyright (C) 2015 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt
+ * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/arch/arm/src/stm32f7/stm32_rtc.c b/arch/arm/src/stm32f7/stm32_rtc.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd42b8396a67779936c1ee343f43e92ec244293f
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_rtc.c
@@ -0,0 +1,1503 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_rtc.c
+ *
+ * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ * David Sidrane
+ *
+ * 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
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "up_arch.h"
+
+#include "stm32_rcc.h"
+#include "stm32_pwr.h"
+#include "stm32_exti.h"
+#include "stm32_rtc.h"
+
+#include
+
+#ifdef CONFIG_RTC
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+/* This RTC implementation supports
+ * - date/time RTC hardware
+ * - extended functions Alarm A and B for STM32F4xx and onwards
+ * */
+
+#ifndef CONFIG_RTC_DATETIME
+# error "CONFIG_RTC_DATETIME must be set to use this driver"
+#endif
+
+#ifdef CONFIG_RTC_HIRES
+# error "CONFIG_RTC_HIRES must NOT be set with this driver"
+#endif
+
+#ifndef CONFIG_STM32F7_PWR
+# error "CONFIG_STM32F7_PWR must selected to use this driver"
+#endif
+
+/* Constants ****************************************************************/
+
+#if defined(CONFIG_STM32F7_RTC_HSECLOCK)
+# define RCC_BDCR_RTCSEL RCC_BDCR_RTCSEL_HSE
+#elif defined(CONFIG_STM32F7_RTC_LSICLOCK)
+# define RCC_BDCR_RTCSEL RCC_BDCR_RTCSEL_LSI
+#elif defined(CONFIG_STM32F7_RTC_LSECLOCK)
+# define RCC_BDCR_RTCSEL RCC_BDCR_RTCSEL_LSE
+#else
+# warning "RCC_BDCR_RTCSEL_NOCLK has been selected - RTC will not count"
+#endif
+
+#define SYNCHRO_TIMEOUT (0x00020000)
+#define INITMODE_TIMEOUT (0x00010000)
+
+/* Time conversions */
+
+#define MINUTES_IN_HOUR 60
+#define HOURS_IN_DAY 24
+
+#define hours_add(parm_hrs) \
+ time->tm_hour += parm_hrs;\
+ if ((HOURS_IN_DAY-1) < (time->tm_hour))\
+ {\
+ time->tm_hour = (parm_hrs - HOURS_IN_DAY);\
+ }
+
+#define RTC_ALRMR_DIS_MASK (RTC_ALRMR_MSK4 | RTC_ALRMR_MSK3 | \
+ RTC_ALRMR_MSK2 | RTC_ALRMR_MSK1)
+#define RTC_ALRMR_DIS_DATE_MASK (RTC_ALRMR_MSK4)
+#define RTC_ALRMR_ENABLE (0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+typedef unsigned int rtc_alarmreg_t;
+
+struct alm_cbinfo_s
+{
+ volatile alm_callback_t ac_cb; /* Client callback function */
+ volatile FAR void *ac_arg; /* Argument to pass with the callback function */
+};
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+/* Callback to use when an EXTI is activated */
+
+static struct alm_cbinfo_s g_alarmcb[RTC_ALARM_LAST];
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* g_rtc_enabled is set true after the RTC has successfully initialized */
+
+volatile bool g_rtc_enabled = false;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+static int rtchw_check_alrawf(void);
+static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg);
+#if CONFIG_RTC_NALARMS > 1
+static int rtchw_check_alrbwf(void);
+static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg);
+#endif
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rtc_dumpregs
+ *
+ * Description:
+ * Disable RTC write protection
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_RTC_INFO
+static void rtc_dumpregs(FAR const char *msg)
+{
+ int rtc_state;
+
+ rtcinfo("%s:\n", msg);
+ rtcinfo(" TR: %08x\n", getreg32(STM32_RTC_TR));
+ rtcinfo(" DR: %08x\n", getreg32(STM32_RTC_DR));
+ rtcinfo(" CR: %08x\n", getreg32(STM32_RTC_CR));
+ rtcinfo(" ISR: %08x\n", getreg32(STM32_RTC_ISR));
+ rtcinfo(" PRER: %08x\n", getreg32(STM32_RTC_PRER));
+ rtcinfo(" WUTR: %08x\n", getreg32(STM32_RTC_WUTR));
+ rtcinfo(" ALRMAR: %08x\n", getreg32(STM32_RTC_ALRMAR));
+ rtcinfo(" ALRMBR: %08x\n", getreg32(STM32_RTC_ALRMBR));
+ rtcinfo(" SHIFTR: %08x\n", getreg32(STM32_RTC_SHIFTR));
+ rtcinfo(" TSTR: %08x\n", getreg32(STM32_RTC_TSTR));
+ rtcinfo(" TSDR: %08x\n", getreg32(STM32_RTC_TSDR));
+ rtcinfo(" TSSSR: %08x\n", getreg32(STM32_RTC_TSSSR));
+ rtcinfo(" CALR: %08x\n", getreg32(STM32_RTC_CALR));
+ rtcinfo(" TAFCR: %08x\n", getreg32(STM32_RTC_TAFCR));
+ rtcinfo("ALRMASSR: %08x\n", getreg32(STM32_RTC_ALRMASSR));
+ rtcinfo("ALRMBSSR: %08x\n", getreg32(STM32_RTC_ALRMBSSR));
+ rtcinfo("MAGICREG: %08x\n", getreg32(RTC_MAGIC_REG));
+
+ rtc_state =
+ ((getreg32(STM32_EXTI_RTSR) & EXTI_RTC_ALARM) ? 0x1000 : 0) |
+ ((getreg32(STM32_EXTI_FTSR) & EXTI_RTC_ALARM) ? 0x0100 : 0) |
+ ((getreg32(STM32_EXTI_IMR) & EXTI_RTC_ALARM) ? 0x0010 : 0) |
+ ((getreg32(STM32_EXTI_EMR) & EXTI_RTC_ALARM) ? 0x0001 : 0);
+ rtcinfo("EXTI (RTSR FTSR ISR EVT): %01x\n",rtc_state);
+}
+#else
+# define rtc_dumpregs(msg)
+#endif
+
+/****************************************************************************
+ * Name: rtc_dumptime
+ *
+ * Description:
+ * Disable RTC write protection
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_RTC_INFO
+static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg)
+{
+ rtcinfo("%s:\n", msg);
+ rtcinfo(" tm_sec: %08x\n", tp->tm_sec);
+ rtcinfo(" tm_min: %08x\n", tp->tm_min);
+ rtcinfo(" tm_hour: %08x\n", tp->tm_hour);
+ rtcinfo(" tm_mday: %08x\n", tp->tm_mday);
+ rtcinfo(" tm_mon: %08x\n", tp->tm_mon);
+ rtcinfo(" tm_year: %08x\n", tp->tm_year);
+}
+#else
+# define rtc_dumptime(tp, msg)
+#endif
+
+/****************************************************************************
+ * Name: rtc_wprunlock
+ *
+ * Description:
+ * Disable RTC write protection
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void rtc_wprunlock(void)
+{
+ /* Enable write access to the backup domain (RTC registers, RTC backup data
+ * registers and backup SRAM).
+ */
+
+ (void)stm32_pwr_enablebkp(true);
+
+ /* The following steps are required to unlock the write protection on all the
+ * RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR).
+ *
+ * 1. Write 0xCA into the RTC_WPR register.
+ * 2. Write 0x53 into the RTC_WPR register.
+ *
+ * Writing a wrong key re-activates the write protection.
+ */
+
+ putreg32(0xca, STM32_RTC_WPR);
+ putreg32(0x53, STM32_RTC_WPR);
+}
+
+/****************************************************************************
+ * Name: rtc_wprlock
+ *
+ * Description:
+ * Enable RTC write protection
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void rtc_wprlock(void)
+{
+ /* Writing any wrong key re-activates the write protection. */
+
+ putreg32(0xff, STM32_RTC_WPR);
+
+ /* Disable write access to the backup domain (RTC registers, RTC backup
+ * data registers and backup SRAM).
+ */
+
+ (void)stm32_pwr_enablebkp(false);
+}
+
+/****************************************************************************
+ * Name: rtc_synchwait
+ *
+ * Description:
+ * Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are
+ * synchronized with RTC APB clock.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int rtc_synchwait(void)
+{
+ volatile uint32_t timeout;
+ uint32_t regval;
+ int ret;
+
+ /* Disable the write protection for RTC registers */
+
+ rtc_wprunlock();
+
+ /* Clear Registers synchronization flag (RSF) */
+
+ regval = getreg32(STM32_RTC_ISR);
+ regval &= ~RTC_ISR_RSF;
+ putreg32(regval, STM32_RTC_ISR);
+
+ /* Now wait the registers to become synchronised */
+
+ ret = -ETIMEDOUT;
+ for (timeout = 0; timeout < SYNCHRO_TIMEOUT; timeout++)
+ {
+ regval = getreg32(STM32_RTC_ISR);
+ if ((regval & RTC_ISR_RSF) != 0)
+ {
+ /* Synchronized */
+
+ ret = OK;
+ break;
+ }
+ }
+
+ /* Re-enable the write protection for RTC registers */
+
+ rtc_wprlock();
+ return ret;
+}
+
+/****************************************************************************
+ * Name: rtc_enterinit
+ *
+ * Description:
+ * Enter RTC initialization mode.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int rtc_enterinit(void)
+{
+ volatile uint32_t timeout;
+ uint32_t regval;
+ int ret;
+
+ /* Check if the Initialization mode is already set */
+
+ regval = getreg32(STM32_RTC_ISR);
+
+ ret = OK;
+ if ((regval & RTC_ISR_INITF) == 0)
+ {
+ /* Set the Initialization mode */
+
+ putreg32(RTC_ISR_INIT, STM32_RTC_ISR);
+
+ /* Wait until the RTC is in the INIT state (or a timeout occurs) */
+
+ ret = -ETIMEDOUT;
+ for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++)
+ {
+ regval = getreg32(STM32_RTC_ISR);
+ if ((regval & RTC_ISR_INITF) != 0)
+ {
+ ret = OK;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: rtc_exitinit
+ *
+ * Description:
+ * Exit RTC initialization mode.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static void rtc_exitinit(void)
+{
+ uint32_t regval;
+
+ regval = getreg32(STM32_RTC_ISR);
+ regval &= ~(RTC_ISR_INIT);
+ putreg32(regval, STM32_RTC_ISR);
+}
+
+/****************************************************************************
+ * Name: rtc_bin2bcd
+ *
+ * Description:
+ * Converts a 2 digit binary to BCD format
+ *
+ * Input Parameters:
+ * value - The byte to be converted.
+ *
+ * Returned Value:
+ * The value in BCD representation
+ *
+ ****************************************************************************/
+
+static uint32_t rtc_bin2bcd(int value)
+{
+ uint32_t msbcd = 0;
+
+ while (value >= 10)
+ {
+ msbcd++;
+ value -= 10;
+ }
+
+ return (msbcd << 4) | value;
+}
+
+/****************************************************************************
+ * Name: rtc_bin2bcd
+ *
+ * Description:
+ * Convert from 2 digit BCD to binary.
+ *
+ * Input Parameters:
+ * value - The BCD value to be converted.
+ *
+ * Returned Value:
+ * The value in binary representation
+ *
+ ****************************************************************************/
+
+static int rtc_bcd2bin(uint32_t value)
+{
+ uint32_t tens = (value >> 4) * 10;
+ return (int)(tens + (value & 0x0f));
+}
+
+/****************************************************************************
+ * Name: rtc_setup
+ *
+ * Description:
+ * Performs first time configuration of the RTC. A special value written
+ * into back-up register 0 will prevent this function from being called on
+ * sub-sequent resets or power up.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int rtc_setup(void)
+{
+ uint32_t regval;
+ int ret;
+
+ /* Disable the write protection for RTC registers */
+
+ rtc_wprunlock();
+
+ /* Set Initialization mode */
+
+ ret = rtc_enterinit();
+ if (ret == OK)
+ {
+ /* Set the 24 hour format by clearing the FMT bit in the RTC
+ * control register
+ */
+
+ regval = getreg32(STM32_RTC_CR);
+ regval &= ~RTC_CR_FMT;
+ putreg32(regval, STM32_RTC_CR);
+
+ /* Configure RTC pre-scaler with the required values */
+
+#ifdef CONFIG_STM32F7_RTC_HSECLOCK
+ /* For a 1 MHz clock this yields 0.9999360041 Hz on the second
+ * timer - which is pretty close.
+ */
+
+ putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) |
+ ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
+ STM32_RTC_PRER);
+#else
+ /* Correct values for 32.768 KHz LSE clock and inaccurate LSI clock */
+
+ putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) |
+ ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
+ STM32_RTC_PRER);
+#endif
+
+ /* Exit RTC initialization mode */
+
+ rtc_exitinit();
+ }
+
+ /* Re-enable the write protection for RTC registers */
+
+ rtc_wprlock();
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: rtc_resume
+ *
+ * Description:
+ * Called when the RTC was already initialized on a previous power cycle.
+ * This just brings the RTC back into full operation.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static void rtc_resume(void)
+{
+#ifdef CONFIG_RTC_ALARM
+ uint32_t regval;
+
+ /* Clear the RTC alarm flags */
+
+ regval = getreg32(STM32_RTC_ISR);
+ regval &= ~(RTC_ISR_ALRAF | RTC_ISR_ALRBF);
+ putreg32(regval, STM32_RTC_ISR);
+
+ /* Clear the RTC Alarm Pending bit */
+
+ putreg32(EXTI_RTC_ALARM, STM32_EXTI_PR);
+#endif
+}
+
+/****************************************************************************
+ * Name: stm32_rtc_alarm_handler
+ *
+ * Description:
+ * RTC ALARM interrupt service routine through the EXTI line
+ *
+ * Input Parameters:
+ * irq - The IRQ number that generated the interrupt
+ * context - Architecture specific register save information.
+ *
+ * Returned Value:
+ * Zero (OK) on success; A negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+static int stm32_rtc_alarm_handler(int irq, void *context)
+{
+ FAR struct alm_cbinfo_s *cbinfo;
+ alm_callback_t cb;
+ FAR void *arg;
+ uint32_t isr;
+ uint32_t cr;
+ int ret = OK;
+
+ isr = getreg32(STM32_RTC_ISR);
+
+ /* Check for EXTI from Alarm A or B and handle according */
+
+ if ((isr & RTC_ISR_ALRAF) != 0)
+ {
+ cr = getreg32(STM32_RTC_CR);
+ if ((cr & RTC_CR_ALRAIE) != 0)
+ {
+ cbinfo = &g_alarmcb[RTC_ALARMA];
+ if (cbinfo->ac_cb != NULL)
+ {
+ /* Alarm A callback */
+
+ cb = cbinfo->ac_cb;
+ arg = (FAR void *)cbinfo->ac_arg;
+
+ cbinfo->ac_cb = NULL;
+ cbinfo->ac_arg = NULL;
+
+ cb(arg, RTC_ALARMA);
+ }
+
+ isr = getreg32(STM32_RTC_ISR) & ~RTC_ISR_ALRAF;
+ putreg32(isr, STM32_RTC_CR);
+ }
+ }
+
+#if CONFIG_RTC_NALARMS > 1
+ if ((isr & RTC_ISR_ALRBF) != 0)
+ {
+ cr = getreg32(STM32_RTC_CR);
+ if ((cr & RTC_CR_ALRBIE) != 0)
+ {
+ cbinfo = &g_alarmcb[RTC_ALARMB];
+ if (cbinfo->ac_cb != NULL)
+ {
+ /* Alarm B callback */
+
+ cb = cbinfo->ac_cb;
+ arg = (FAR void *)cbinfo->ac_arg;
+
+ cbinfo->ac_cb = NULL;
+ cbinfo->ac_arg = NULL;
+
+ cb(arg, RTC_ALARMB);
+ }
+
+ isr = getreg32(STM32_RTC_ISR) & ~RTC_ISR_ALRBF;
+ putreg32(isr, STM32_RTC_CR);
+ }
+ }
+#endif
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: rtchw_check_alrXwf X= a or B
+ *
+ * Description:
+ * Check registers
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+static int rtchw_check_alrawf(void)
+{
+ volatile uint32_t timeout;
+ uint32_t regval;
+ int ret = -ETIMEDOUT;
+
+ /* Check RTC_ISR ALRAWF for access to alarm register,
+ * Can take 2 RTCCLK cycles or timeout
+ * CubeMX use GetTick.
+ */
+
+ for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++)
+ {
+ regval = getreg32(STM32_RTC_ISR);
+ if ((regval & RTC_ISR_ALRAWF) != 0)
+ {
+ ret = OK;
+ break;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+#if defined(CONFIG_RTC_ALARM) && CONFIG_RTC_NALARMS > 1
+static int rtchw_check_alrbwf(void)
+{
+ volatile uint32_t timeout;
+ uint32_t regval;
+ int ret = -ETIMEDOUT;
+
+ /* Check RTC_ISR ALRAWF for access to alarm register,
+ * can take 2 RTCCLK cycles or timeout
+ * CubeMX use GetTick.
+ */
+
+ for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++)
+ {
+ regval = getreg32(STM32_RTC_ISR);
+ if ((regval & RTC_ISR_ALRBWF) != 0)
+ {
+ ret = OK;
+ break;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_rtchw_set_alrmXr X is a or b
+ *
+ * Description:
+ * Set the alarm (A or B) hardware registers, using the required hardware
+ * access protocol
+ *
+ * Input Parameters:
+ * alarmreg - the register
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg)
+{
+ int ret = -EBUSY;
+
+ /* Need to follow RTC register wrote protection
+ * Disable the write protection for RTC registers
+ */
+
+ rtc_wprunlock();
+
+ /* Disable RTC alarm & Interrupt */
+
+ modifyreg32(STM32_RTC_CR, (RTC_CR_ALRAE | RTC_CR_ALRAIE), 0);
+
+ ret = rtchw_check_alrawf();
+ if (ret != OK)
+ {
+ goto errout_with_wprunlock;
+ }
+
+ /* Set the RTC Alarm register */
+
+ putreg32(alarmreg, STM32_RTC_ALRMAR);
+ rtcinfo(" TR: %08x ALRMAR: %08x\n",
+ getreg32(STM32_RTC_TR), getreg32(STM32_RTC_ALRMAR));
+
+ /* Enable RTC alarm */
+
+ modifyreg32(STM32_RTC_CR, 0, (RTC_CR_ALRAE | RTC_CR_ALRAIE));
+
+errout_with_wprunlock:
+ rtc_wprlock();
+ return ret;
+}
+#endif
+
+#if defined(CONFIG_RTC_ALARM) && CONFIG_RTC_NALARMS > 1
+static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg)
+{
+ int ret = -EBUSY;
+
+ /* Need to follow RTC register wrote protection
+ * Disable the write protection for RTC registers
+ */
+
+ rtc_wprunlock();
+
+ /* Disable RTC alarm B & Interrupt B */
+
+ modifyreg32(STM32_RTC_CR, (RTC_CR_ALRBE | RTC_CR_ALRBIE), 0);
+
+ ret = rtchw_check_alrbwf();
+ if (ret != OK)
+ {
+ goto rtchw_set_alrmbr_exit;
+ }
+
+ /* Set the RTC Alarm register */
+
+ putreg32(alarmreg, STM32_RTC_ALRMBR);
+ rtcinfo(" TR: %08x ALRMBR: %08x\n",
+ getreg32(STM32_RTC_TR), getreg32(STM32_RTC_ALRMBR));
+
+ /* Enable RTC alarm B */
+
+ modifyreg32(STM32_RTC_CR, 0, (RTC_CR_ALRBE | RTC_CR_ALRBIE));
+
+rtchw_set_alrmbr_exit:
+ rtc_wprlock();
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_rtc_initialize
+ *
+ * Description:
+ * Initialize the hardware RTC per the selected configuration. This
+ * function is called once during the OS initialization sequence
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+int up_rtc_initialize(void)
+{
+ uint32_t regval;
+ uint32_t tr_bkp;
+ uint32_t dr_bkp;
+ int ret;
+ int maxretry = 10;
+ int nretry = 0;
+
+ /* Clocking for the PWR block must be provided. However, this is done
+ * unconditionally in stm32f7xxx_rcc.c on power up. This done
+ * unconditionally because the PWR block is also needed to set the
+ * internal voltage regulator for maximum performance.
+ */
+
+ /* Select the clock source */
+ /* Save the token before losing it when resetting */
+
+ regval = getreg32(RTC_MAGIC_REG);
+
+ (void)stm32_pwr_enablebkp(true);
+
+ if (regval != RTC_MAGIC)
+ {
+ /* Issue the Backup domain Reset Per Section 5.3.20 DocID028270 Rev 2
+ * The LSEON, LSEBYP, RTCSEL and RTCEN bits in the RCC backup domain
+ * control register (RCC_BDCR) are in the Backup domain. As a result,
+ * after Reset, these bits are write-protected and the DBP bit in the
+ * PWR power control register (PWR_CR1) has to be set before these can
+ * be modified. Refer to Section 5.1.1: System reset on page 148 for
+ * further information. These bits are only reset after a Backup
+ * domain Reset (see Section 5.1.3: Backup domain reset).
+ *
+ * This has to be done here so that PWR is already enabled
+ */
+
+ modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_BDRST);
+ modifyreg32(STM32_RCC_BDCR, RCC_BDCR_BDRST, 0);
+
+#if RCC_BDCR_RTCSEL == RCC_BDCR_RTCSEL_LSE
+ /* Because of the Backup domain Reset - we must re enable the LSE */
+
+ stm32_rcc_enablelse();
+#endif
+
+ /* Some boards do not have the external 32khz oscillator installed, for
+ * those boards we must fallback to the crummy internal RC clock or the
+ * external high rate clock
+ */
+
+#ifdef CONFIG_STM32F7_RTC_HSECLOCK
+ /* Use the HSE clock as the input to the RTC block */
+
+ rtc_dumpregs("On reset HSE");
+
+#elif defined(CONFIG_STM32F7_RTC_LSICLOCK)
+ /* Use the LSI clock as the input to the RTC block */
+
+ rtc_dumpregs("On reset LSI");
+
+#elif defined(CONFIG_STM32F7_RTC_LSECLOCK)
+ /* Use the LSE clock as the input to the RTC block */
+
+ rtc_dumpregs("On reset LSE");
+
+#endif
+ modifyreg32(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL);
+
+ /* Enable the RTC Clock by setting the RTCEN bit in the RCC register */
+
+ modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN);
+ }
+ else
+ {
+ uint32_t clksrc = getreg32(STM32_RCC_BDCR);
+
+ rtc_dumpregs("On reset warm");
+
+ /* The RTC is already in use: check if the clock source has changed */
+
+ if ((clksrc & RCC_BDCR_RTCSEL_MASK) != RCC_BDCR_RTCSEL)
+ {
+ tr_bkp = getreg32(STM32_RTC_TR);
+ dr_bkp = getreg32(STM32_RTC_DR);
+ modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_BDRST);
+ modifyreg32(STM32_RCC_BDCR, RCC_BDCR_BDRST, 0);
+
+# if RCC_BDCR_RTCSEL == RCC_BDCR_RTCSEL_LSE
+ /* Because of the Backup domain Reset - we must re enable the LSE
+ * if it is used
+ */
+
+ stm32_rcc_enablelse();
+#endif
+ /* Change to the new clock as the input to the RTC block */
+
+ modifyreg32(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL);
+
+ putreg32(tr_bkp, STM32_RTC_TR);
+ putreg32(dr_bkp, STM32_RTC_DR);
+
+ /* Keep the fact that the RTC is initialized */
+
+ putreg32(RTC_MAGIC, RTC_MAGIC_REG);
+
+ /* Enable the RTC Clock by setting the RTCEN bit in the RCC
+ * register.
+ */
+
+ modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN);
+ }
+ }
+
+ (void)stm32_pwr_enablebkp(false);
+
+ /* Loop, attempting to initialize/resume the RTC. This loop is necessary
+ * because it seems that occasionally it takes longer to initialize the
+ * RTC (the actual failure is in rtc_synchwait()).
+ */
+
+ do
+ {
+ /* Wait for the RTC Time and Date registers to be synchronized with
+ * RTC APB clock.
+ */
+
+ ret = rtc_synchwait();
+
+ /* Check that rtc_syncwait() returned successfully */
+
+ switch (ret)
+ {
+ case OK:
+ {
+ rtcinfo("rtc_syncwait() okay\n");
+ break;
+ }
+
+ default:
+ {
+ rtcerr("ERROR: rtc_syncwait() failed (%d)\n", ret);
+ break;
+ }
+ }
+ }
+ while (ret != OK && ++nretry < maxretry);
+
+ /* Check if the one-time initialization of the RTC has already been
+ * performed. We can determine this by checking if the magic number
+ * has been writing to to back-up date register DR0.
+ */
+
+ if (regval != RTC_MAGIC)
+ {
+ rtcinfo("Do setup\n");
+
+ /* Perform the one-time setup of the LSE clocking to the RTC */
+
+ ret = rtc_setup();
+
+ /* Enable write access to the backup domain (RTC registers, RTC
+ * backup data registers and backup SRAM).
+ */
+
+ (void)stm32_pwr_enablebkp(true);
+
+ /* Remember that the RTC is initialized */
+
+ putreg32(RTC_MAGIC, RTC_MAGIC_REG);
+ }
+ else
+ {
+ rtcinfo("Do resume\n");
+
+ /* RTC already set-up, just resume normal operation */
+
+ rtc_resume();
+ rtc_dumpregs("Did resume");
+ }
+
+ /* Disable write access to the backup domain (RTC registers, RTC backup
+ * data registers and backup SRAM).
+ */
+
+ (void)stm32_pwr_enablebkp(false);
+
+ if (ret != OK && nretry > 0)
+ {
+ rtcinfo("setup/resume ran %d times and failed with %d\n",
+ nretry, ret);
+ return -ETIMEDOUT;
+ }
+
+#ifdef CONFIG_RTC_ALARM
+ /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts
+ * are connected to the EXTI controller. To enable the RTC Alarm
+ * interrupt, the following sequence is required:
+ *
+ * 1. Configure and enable the EXTI Line 17 RTC ALARM in interrupt mode
+ * and select the rising edge sensitivity.
+ * For STM32F4xx
+ * EXTI line 21 RTC Tamper & Timestamp
+ * EXTI line 22 RTC Wakeup
+ * 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC.
+ * 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B).
+ */
+
+ stm32_exti_alarm(true, false, true, stm32_rtc_alarm_handler);
+ rtc_dumpregs("After InitExtiAlarm");
+#else
+ rtc_dumpregs("After Initialization");
+#endif
+
+ g_rtc_enabled = true;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_rtc_getdatetime_with_subseconds
+ *
+ * Description:
+ * Get the current date and time from the date/time RTC. This interface
+ * is only supported by the date/time RTC hardware implementation.
+ * It is used to replace the system timer. It is only used by the RTOS
+ * during initialization to set up the system time when CONFIG_RTC and
+ * CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not).
+ *
+ * NOTE: Some date/time RTC hardware is capability of sub-second accuracy.
+ * That sub-second accuracy is returned through 'nsec'.
+ *
+ * Input Parameters:
+ * tp - The location to return the high resolution time value.
+ * nsec - The location to return the subsecond time value.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS
+int stm32_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec)
+#else
+int up_rtc_getdatetime(FAR struct tm *tp)
+#endif
+{
+#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS
+ uint32_t ssr;
+#endif
+ uint32_t dr;
+ uint32_t tr;
+ uint32_t tmp;
+
+ /* Sample the data time registers. There is a race condition here... If
+ * we sample the time just before midnight on December 31, the date could
+ * be wrong because the day rolled over while were sampling.
+ */
+
+ do
+ {
+ dr = getreg32(STM32_RTC_DR);
+ tr = getreg32(STM32_RTC_TR);
+#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS
+ ssr = getreg32(STM32_RTC_SSR);
+#endif
+ tmp = getreg32(STM32_RTC_DR);
+ }
+ while (tmp != dr);
+
+ rtc_dumpregs("Reading Time");
+
+ /* Convert the RTC time to fields in struct tm format. All of the STM32
+ * All of the ranges of values correspond between struct tm and the time
+ * register.
+ */
+
+ tmp = (tr & (RTC_TR_SU_MASK | RTC_TR_ST_MASK)) >> RTC_TR_SU_SHIFT;
+ tp->tm_sec = rtc_bcd2bin(tmp);
+
+ tmp = (tr & (RTC_TR_MNU_MASK | RTC_TR_MNT_MASK)) >> RTC_TR_MNU_SHIFT;
+ tp->tm_min = rtc_bcd2bin(tmp);
+
+ tmp = (tr & (RTC_TR_HU_MASK | RTC_TR_HT_MASK)) >> RTC_TR_HU_SHIFT;
+ tp->tm_hour = rtc_bcd2bin(tmp);
+
+ /* Now convert the RTC date to fields in struct tm format:
+ * Days: 1-31 match in both cases.
+ * Month: STM32 is 1-12, struct tm is 0-11.
+ * Years: STM32 is 00-99, struct tm is years since 1900.
+ * WeekDay: STM32 is 1 = Mon - 7 = Sun
+ *
+ * Issue: I am not sure what the STM32 years mean. Are these the
+ * years 2000-2099? I'll assume so.
+ */
+
+ tmp = (dr & (RTC_DR_DU_MASK | RTC_DR_DT_MASK)) >> RTC_DR_DU_SHIFT;
+ tp->tm_mday = rtc_bcd2bin(tmp);
+
+ tmp = (dr & (RTC_DR_MU_MASK | RTC_DR_MT)) >> RTC_DR_MU_SHIFT;
+ tp->tm_mon = rtc_bcd2bin(tmp) - 1;
+
+ tmp = (dr & (RTC_DR_YU_MASK | RTC_DR_YT_MASK)) >> RTC_DR_YU_SHIFT;
+ tp->tm_year = rtc_bcd2bin(tmp) + 100;
+
+#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED)
+ tmp = (dr & RTC_DR_WDU_MASK) >> RTC_DR_WDU_SHIFT;
+ tp->tm_wday = tmp % 7;
+ tp->tm_yday = tp->tm_mday +
+ clock_daysbeforemonth(tp->tm_mon, clock_isleapyear(tp->tm_year + 1900));
+ tp->tm_isdst = 0
+#endif
+
+#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS
+ /* Return RTC sub-seconds if no configured and if a non-NULL value
+ * of nsec has been provided to receive the sub-second value.
+ */
+
+ if (nsec)
+ {
+ uint32_t prediv_s;
+ uint32_t usecs;
+
+ prediv_s = getreg32(STM32_RTC_PRER) & RTC_PRER_PREDIV_S_MASK;
+ prediv_s >>= RTC_PRER_PREDIV_S_SHIFT;
+
+ ssr &= RTC_SSR_MASK;
+
+ /* Maximum prediv_s is 0x7fff, thus we can multiply by 100000 and
+ * still fit 32-bit unsigned integer.
+ */
+
+ usecs = (((prediv_s - ssr) * 100000) / (prediv_s + 1)) * 10;
+ *nsec = usecs * 1000;
+ }
+#endif /* CONFIG_STM32_HAVE_RTC_SUBSECONDS */
+
+ rtc_dumptime((FAR const struct tm *)tp, "Returning");
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_rtc_getdatetime
+ *
+ * Description:
+ * Get the current date and time from the date/time RTC. This interface
+ * is only supported by the date/time RTC hardware implementation.
+ * It is used to replace the system timer. It is only used by the RTOS
+ * during initialization to set up the system time when CONFIG_RTC and
+ * CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not).
+ *
+ * NOTE: Some date/time RTC hardware is capability of sub-second accuracy.
+ * That sub-second accuracy is lost in this interface. However, since the
+ * system time is reinitialized on each power-up/reset, there will be no
+ * timing inaccuracy in the long run.
+ *
+ * Input Parameters:
+ * tp - The location to return the high resolution time value.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32_HAVE_RTC_SUBSECONDS
+int up_rtc_getdatetime(FAR struct tm *tp)
+{
+ return stm32_rtc_getdatetime_with_subseconds(tp, NULL);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_rtc_setdatetime
+ *
+ * Description:
+ * Set the RTC to the provided time. RTC implementations which provide
+ * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide
+ * this function.
+ *
+ * Input Parameters:
+ * tp - the time to use
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+int stm32_rtc_setdatetime(FAR const struct tm *tp)
+{
+ uint32_t tr;
+ uint32_t dr;
+ int ret;
+
+ rtc_dumptime(tp, "Setting time");
+
+ /* Then write the broken out values to the RTC */
+
+ /* Convert the struct tm format to RTC time register fields. All of the
+ * STM32 All of the ranges of values correspond between struct tm and the
+ * time register.
+ */
+
+ tr = (rtc_bin2bcd(tp->tm_sec) << RTC_TR_SU_SHIFT) |
+ (rtc_bin2bcd(tp->tm_min) << RTC_TR_MNU_SHIFT) |
+ (rtc_bin2bcd(tp->tm_hour) << RTC_TR_HU_SHIFT);
+
+ /* Now convert the fields in struct tm format to the RTC date register
+ * fields:
+ *
+ * Days: 1-31 match in both cases.
+ * Month: STM32 is 1-12, struct tm is 0-11.
+ * Years: STM32 is 00-99, struct tm is years since 1900.
+ * WeekDay: STM32 is 1 = Mon - 7 = Sun
+ *
+ * Issue: I am not sure what the STM32 years mean. Are these the
+ * years 2000-2099? I'll assume so.
+ */
+
+ dr = (rtc_bin2bcd(tp->tm_mday) << RTC_DR_DU_SHIFT) |
+ ((rtc_bin2bcd(tp->tm_mon + 1)) << RTC_DR_MU_SHIFT) |
+#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED)
+ ((tp->tm_wday == 0 ? 7 : (tp->tm_wday & 7)) << RTC_DR_WDU_SHIFT) |
+#endif
+ ((rtc_bin2bcd(tp->tm_year - 100)) << RTC_DR_YU_SHIFT);
+
+ dr &= ~RTC_DR_RESERVED_BITS;
+
+ /* Disable the write protection for RTC registers */
+
+ rtc_wprunlock();
+
+ /* Set Initialization mode */
+
+ ret = rtc_enterinit();
+ if (ret == OK)
+ {
+ /* Set the RTC TR and DR registers */
+
+ putreg32(tr, STM32_RTC_TR);
+ putreg32(dr, STM32_RTC_DR);
+
+ /* Exit Initialization mode and wait for the RTC Time and Date
+ * registers to be synchronized with RTC APB clock.
+ */
+
+ rtc_exitinit();
+ ret = rtc_synchwait();
+ }
+
+ /* Re-enable the write protection for RTC registers */
+
+ rtc_wprlock();
+ rtc_dumpregs("New time setting");
+ return ret;
+}
+
+/****************************************************************************
+ * Name: up_rtc_settime
+ *
+ * Description:
+ * Set the RTC to the provided time. All RTC implementations must be able
+ * to set their time based on a standard timespec.
+ *
+ * Input Parameters:
+ * tp - the time to use
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+int up_rtc_settime(FAR const struct timespec *tp)
+{
+ FAR struct tm newtime;
+
+ /* Break out the time values (not that the time is set only to units of
+ * seconds)
+ */
+
+ (void)gmtime_r(&tp->tv_sec, &newtime);
+ return stm32_rtc_setdatetime(&newtime);
+}
+
+/****************************************************************************
+ * Name: stm32_rtc_setalarm
+ *
+ * Description:
+ * Set an alarm to an asbolute time using associated hardware.
+ *
+ * Input Parameters:
+ * alminfo - Information about the alarm configuration.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
+{
+ FAR struct alm_cbinfo_s *cbinfo;
+ rtc_alarmreg_t alarmreg;
+ int ret = -EINVAL;
+
+ ASSERT(alminfo != NULL);
+ DEBUGASSERT(RTC_ALARM_LAST > alminfo->as_id);
+
+ /* REVISIT: Should test that the time is in the future */
+
+ rtc_dumptime(&alminfo->as_time, "New alarm time");
+
+ /* Break out the values to the HW alarm register format. The values in
+ * all STM32 fields match the fields of struct tm in this case. Notice
+ * that the alarm is limited to one month.
+ */
+
+ alarmreg = (rtc_bin2bcd(alminfo->as_time.tm_sec) << RTC_ALRMR_SU_SHIFT) |
+ (rtc_bin2bcd(alminfo->as_time.tm_min) << RTC_ALRMR_MNU_SHIFT) |
+ (rtc_bin2bcd(alminfo->as_time.tm_hour) << RTC_ALRMR_HU_SHIFT) |
+ (rtc_bin2bcd(alminfo->as_time.tm_mday) << RTC_ALRMR_DU_SHIFT);
+
+ /* Set the alarm in hardware and enable interrupts */
+
+ switch (alminfo->as_id)
+ {
+ case RTC_ALARMA:
+ {
+ cbinfo = &g_alarmcb[RTC_ALARMA];
+ cbinfo->ac_cb = alminfo->as_cb;
+ cbinfo->ac_arg = alminfo->as_arg;
+
+ ret = rtchw_set_alrmar(alarmreg | RTC_ALRMR_ENABLE);
+ if (ret < 0)
+ {
+ cbinfo->ac_cb = NULL;
+ cbinfo->ac_arg = NULL;
+ }
+
+ rtc_dumpregs("Set AlarmA");
+ }
+ break;
+
+#if CONFIG_RTC_NALARMS > 1
+ case RTC_ALARMB:
+ {
+ cbinfo = &g_alarmcb[RTC_ALARMB];
+ cbinfo->ac_cb = alminfo->as_cb;
+ cbinfo->ac_arg = alminfo->as_arg;
+
+ ret = rtchw_set_alrmbr(alarmreg | RTC_ALRMR_ENABLE);
+ if (ret < 0)
+ {
+ cbinfo->ac_cb = NULL;
+ cbinfo->ac_arg = NULL;
+ }
+
+ rtc_dumpregs("Set AlarmB");
+ }
+ break;
+#endif
+
+ default:
+ rtcerr("ERROR: Invalid ALARM%d\n", alminfo->as_id);
+ break;
+ }
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_rtc_cancelalarm
+ *
+ * Description:
+ * Cancel an alaram.
+ *
+ * Input Parameters:
+ * alarmid - Identifies the alarm to be cancelled
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_ALARM
+int stm32_rtc_cancelalarm(enum alm_id_e alarmid)
+{
+ int ret = -EINVAL;
+
+ DEBUGASSERT(RTC_ALARM_LAST > alarmid);
+
+ /* Cancel the alarm in hardware and disable interrupts */
+
+ switch (alarmid)
+ {
+ case RTC_ALARMA:
+ {
+ /* Cancel the global callback function */
+
+ g_alarmcb[alarmid].ac_cb = NULL;
+ g_alarmcb[alarmid].ac_arg = NULL;
+
+ /* Need to follow RTC register wrote protection.
+ * Disable the write protection for RTC registers
+ */
+
+ rtc_wprunlock();
+
+ /* Disable RTC alarm and interrupt */
+
+ modifyreg32(STM32_RTC_CR, (RTC_CR_ALRAE | RTC_CR_ALRAIE), 0);
+
+ ret = rtchw_check_alrawf();
+ if (ret < 0)
+ {
+ goto errout_with_wprunlock;
+ }
+
+ /* Unset the alarm */
+
+ putreg32(-1, STM32_RTC_ALRMAR);
+ rtc_wprlock();
+ ret = OK;
+ }
+ break;
+
+#if CONFIG_RTC_NALARMS > 1
+ case RTC_ALARMB:
+ {
+ /* Cancel the global callback function */
+
+ g_alarmcb[alarmid].ac_cb = NULL;
+ g_alarmcb[alarmid].ac_arg = NULL;
+
+ /* Need to follow RTC register wrote protection.
+ * Disable the write protection for RTC registers
+ */
+
+ rtc_wprunlock();
+
+ /* Disable RTC alarm and interrupt */
+
+ modifyreg32(STM32_RTC_CR, (RTC_CR_ALRBE | RTC_CR_ALRBIE), 0);
+
+ ret = rtchw_check_alrbwf();
+ if (ret < 0)
+ {
+ goto errout_with_wprunlock;
+ }
+
+ /* Unset the alarm */
+
+ putreg32(-1, STM32_RTC_ALRMBR);
+ rtc_wprlock();
+ ret = OK;
+ }
+ break;
+#endif
+
+ default:
+ rtcerr("ERROR: Invalid ALARM%d\n", alarmid);
+ break;
+ }
+
+ return ret;
+
+errout_with_wprunlock:
+ rtc_wprlock();
+ return ret;
+}
+#endif
+
+#endif /* CONFIG_RTC */
diff --git a/arch/arm/src/stm32f7/stm32_rtc.h b/arch/arm/src/stm32f7/stm32_rtc.h
new file mode 100644
index 0000000000000000000000000000000000000000..f784f8acd310b1dc0cc0dc926812d2f4024e80e9
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_rtc.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_rtc.h
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Copyright (C) 2011-2013, 2015-2016 Gregory Nutt. All rights reserved.
+ * Authors: Uros Platise (Original for the F1)
+ * Gregory Nutt (On-going support and development)
+ * David Sidrane
+ *
+ * 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
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_STM32F7_STM32_RTC_H
+#define __ARCH_ARM_SRC_STM32F7_STM32_RTC_H
+
+#include
+
+#include "chip.h"
+
+/* The STMF7 family use a more traditional Realtime Clock/Calendar (RTCC) with
+ * broken-out data/time in BCD format. The backup registers are integrated into
+ * the RTCC in these families.
+ */
+
+#include "chip/stm32_rtcc.h"
+#include "stm32_alarm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define STM32_RTC_PRESCALER_SECOND 32767 /* Default prescaler to get a second base */
+#define STM32_RTC_PRESCALER_MIN 1 /* Maximum speed of 16384 Hz */
+
+#if !defined(CONFIG_RTC_MAGIC)
+# define CONFIG_RTC_MAGIC (0xfacefeee)
+#endif
+
+#if !defined(CONFIG_RTC_MAGIC_REG)
+# define CONFIG_RTC_MAGIC_REG (0)
+#endif
+
+#define RTC_MAGIC CONFIG_RTC_MAGIC
+#define RTC_MAGIC_REG STM32_RTC_BKR(CONFIG_RTC_MAGIC_REG)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_rtc_getdatetime_with_subseconds
+ *
+ * Description:
+ * Get the current date and time from the date/time RTC. This interface
+ * is only supported by the date/time RTC hardware implementation.
+ * It is used to replace the system timer. It is only used by the RTOS
+ * during initialization to set up the system time when CONFIG_RTC and
+ * CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not).
+ *
+ * NOTE: Some date/time RTC hardware is capability of sub-second accuracy.
+ * Thatsub-second accuracy is returned through 'nsec'.
+ *
+ * Input Parameters:
+ * tp - The location to return the high resolution time value.
+ * nsec - The location to return the subsecond time value.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32F7_HAVE_RTC_SUBSECONDS
+int stm32_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec);
+#endif
+
+/****************************************************************************
+ * Name: stm32_rtc_setdatetime
+ *
+ * Description:
+ * Set the RTC to the provided time. RTC implementations which provide
+ * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide
+ * this function.
+ *
+ * Input Parameters:
+ * tp - the time to use
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_DATETIME
+struct tm;
+int stm32_rtc_setdatetime(FAR const struct tm *tp);
+#endif
+
+/****************************************************************************
+ * Name: stm32_rtc_lowerhalf
+ *
+ * Description:
+ * Instantiate the RTC lower half driver for the STM32. General usage:
+ *
+ * #include
+ * #include "stm32_rtc.h>
+ *
+ * struct rtc_lowerhalf_s *lower;
+ * lower = stm32_rtc_lowerhalf();
+ * rtc_initialize(0, lower);
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, a non-NULL RTC lower interface is returned. NULL is
+ * returned on any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_DRIVER
+struct rtc_lowerhalf_s;
+FAR struct rtc_lowerhalf_s *stm32_rtc_lowerhalf(void);
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32F7_STM32_RTC_H */
diff --git a/arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c b/arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c
new file mode 100644
index 0000000000000000000000000000000000000000..1b20b44edabff9a1bed544e39b712a6544e9b358
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c
@@ -0,0 +1,530 @@
+/****************************************************************************
+ * arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c
+ *
+ * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* REVISIT: This driver is *not* thread-safe! */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include |