From dc4ac48aad19b791247eef851c3d648cb19a5ada Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 14 Mar 2017 11:56:29 -0600 Subject: [PATCH] arch/arm/src/xmc4: Initial, partial support for Infineon XMC4xxx --- arch/arm/Kconfig | 16 + arch/arm/src/xmc4/Kconfig | 328 +++++++ arch/arm/src/xmc4/Make.defs | 141 +++ arch/arm/src/xmc4/chip.h | 77 ++ arch/arm/src/xmc4/xmc4_allocateheap.c | 193 +++++ arch/arm/src/xmc4/xmc4_clockconfig.c | 74 ++ arch/arm/src/xmc4/xmc4_clrpend.c | 102 +++ arch/arm/src/xmc4/xmc4_config.h | 198 +++++ arch/arm/src/xmc4/xmc4_dma.c | 0 arch/arm/src/xmc4/xmc4_dma.h | 218 +++++ arch/arm/src/xmc4/xmc4_gpio.c | 0 arch/arm/src/xmc4/xmc4_gpio.h | 0 arch/arm/src/xmc4/xmc4_i2c.c | 0 arch/arm/src/xmc4/xmc4_i2c.h | 87 ++ arch/arm/src/xmc4/xmc4_idle.c | 105 +++ arch/arm/src/xmc4/xmc4_irq.c | 588 +++++++++++++ arch/arm/src/xmc4/xmc4_lowputc.c | 235 +++++ arch/arm/src/xmc4/xmc4_mpuinit.c | 124 +++ arch/arm/src/xmc4/xmc4_mpuinit.h | 78 ++ arch/arm/src/xmc4/xmc4_pwm.c | 0 arch/arm/src/xmc4/xmc4_pwm.h | 100 +++ arch/arm/src/xmc4/xmc4_serial.c | 1146 +++++++++++++++++++++++++ arch/arm/src/xmc4/xmc4_spi.h | 165 ++++ arch/arm/src/xmc4/xmc4_start.c | 355 ++++++++ arch/arm/src/xmc4/xmc4_timerisr.c | 152 ++++ arch/arm/src/xmc4/xmc4_userspace.c | 107 +++ arch/arm/src/xmc4/xmc4_userspace.h | 64 ++ 27 files changed, 4653 insertions(+) create mode 100644 arch/arm/src/xmc4/Kconfig create mode 100644 arch/arm/src/xmc4/Make.defs create mode 100644 arch/arm/src/xmc4/chip.h create mode 100644 arch/arm/src/xmc4/xmc4_allocateheap.c create mode 100644 arch/arm/src/xmc4/xmc4_clockconfig.c create mode 100644 arch/arm/src/xmc4/xmc4_clrpend.c create mode 100644 arch/arm/src/xmc4/xmc4_config.h create mode 100644 arch/arm/src/xmc4/xmc4_dma.c create mode 100644 arch/arm/src/xmc4/xmc4_dma.h create mode 100644 arch/arm/src/xmc4/xmc4_gpio.c create mode 100644 arch/arm/src/xmc4/xmc4_gpio.h create mode 100644 arch/arm/src/xmc4/xmc4_i2c.c create mode 100644 arch/arm/src/xmc4/xmc4_i2c.h create mode 100644 arch/arm/src/xmc4/xmc4_idle.c create mode 100644 arch/arm/src/xmc4/xmc4_irq.c create mode 100644 arch/arm/src/xmc4/xmc4_lowputc.c create mode 100644 arch/arm/src/xmc4/xmc4_mpuinit.c create mode 100644 arch/arm/src/xmc4/xmc4_mpuinit.h create mode 100644 arch/arm/src/xmc4/xmc4_pwm.c create mode 100644 arch/arm/src/xmc4/xmc4_pwm.h create mode 100644 arch/arm/src/xmc4/xmc4_serial.c create mode 100644 arch/arm/src/xmc4/xmc4_spi.h create mode 100644 arch/arm/src/xmc4/xmc4_start.c create mode 100644 arch/arm/src/xmc4/xmc4_timerisr.c create mode 100644 arch/arm/src/xmc4/xmc4_userspace.c create mode 100644 arch/arm/src/xmc4/xmc4_userspace.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fd44dcff07..21334e7117 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -270,6 +270,19 @@ config ARCH_CHIP_TMS570 ---help--- TI TMS570 family +config ARCH_CHIP_XMC4 + bool "Infineon XMC4xxx" + select ARCH_HAVE_CMNVECTOR + select ARCH_CORTEXM4 + select ARCH_HAVE_MPU + select ARCH_HAVE_RAMFUNCS + select ARCH_HAVE_I2CRESET + select ARM_HAVE_MPU_UNIFIED + select ARMV7M_CMNVECTOR + select ARMV7M_HAVE_STACKCHECK + ---help--- + Infineon XMC4xxx(ARM Cortex-M4) architectures + config ARCH_CHIP_MOXART bool "MoxART" select ARCH_ARM7TDMI @@ -692,6 +705,9 @@ endif if ARCH_CHIP_TMS570 source arch/arm/src/tms570/Kconfig endif +if ARCH_CHIP_XMC4 +source arch/arm/src/xmc4/Kconfig +endif if ARCH_CHIP_MOXART source arch/arm/src/moxart/Kconfig endif diff --git a/arch/arm/src/xmc4/Kconfig b/arch/arm/src/xmc4/Kconfig new file mode 100644 index 0000000000..116d56d14f --- /dev/null +++ b/arch/arm/src/xmc4/Kconfig @@ -0,0 +1,328 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "XMC4xxx Configuration Options" + +choice + prompt "XMC4xxx Chip Selection" + default ARCH_CHIP_XMC4500 + depends on ARCH_CHIP_XMC4 + +config ARCH_CHIP_XMC4500 + bool "XMC4500" + +endchoice + +# These "hidden" settings determine is a peripheral option is available for +# the selection MCU + + +# When there are multiple instances of a device, these "hidden" settings +# will automatically be selected and will represent the 'OR' of the +# instances selected. + +config XMC4_USIC + bool + default n + +config XMC4_USCI_UART + bool + default n + select MCU_SERIAL + +config XMC4_USCI_LIN + bool + default n + +config XMC4_USCI_SPI + bool + default n + +config XMC4_USCI_I2C + bool + default n + +config XMC4_USCI_I2S + bool + default n + +# Chip families + +menu "ARCH_CHIP_XMC4 Peripheral Support" + +config XMC4_USIC0 + bool "USIC0" + default n + select XMC4_USIC + ---help--- + Support USIC0 + +config XMC4_USIC1 + bool "USIC1" + default n + ---help--- + Support USIC1 + +config XMC4_USIC2 + bool "USIC3" + default n + select XMC4_USIC + ---help--- + Support USIC2 + +config XMC4_USIC3 + bool "USIC3" + default n + select XMC4_USIC + ---help--- + Support USIC3 + +config XMC4_USIC4 + bool "USIC4" + default n + select XMC4_USIC + ---help--- + Support USIC4 + +config XMC4_USIC5 + bool "USIC5" + default n + select XMC4_USIC + ---help--- + Support USIC5 + +endmenu + +menu "XMC4xxx USIC Configuration" + depends on XMC4_USIC + +choice + prompt "USIC0 Configuration" + default XMC4_USIC0_ISUART + depends on XMC4_USIC0 + +config XMC4_USIC0_ISUART + bool "UART" + select UART0_SERIALDRIVER + select XMC4_USCI_UART + ---help--- + Configure USIC0 as a UART + +config XMC4_USIC0_ISLIN + bool "LIN" + select XMC4_USCI_LIN + ---help--- + Configure USIC0 as a LIN UART + +config XMC4_USIC0_ISSPI + bool "SPI" + select XMC4_USCI_SPI + ---help--- + Configure USIC0 For SPI communications + +config XMC4_USIC0_ISI2C + bool "I2C" + select XMC4_USCI_I2C + ---help--- + Configure USIC0 For I2C communications + +config XMC4_USIC0_ISI2S + bool "I2S" + select XMC4_USCI_I2S + ---help--- + Configure USIC0 For I2S audio + +endchoice # USIC0 Configuration + +choice + prompt "USIC1 Configuration" + default XMC4_USIC1_ISUART + depends on XMC4_USIC1 + +config XMC4_USIC1_ISUART + bool "UART" + select UART1_SERIALDRIVER + select XMC4_USCI_UART + ---help--- + Configure USIC1 as a UART + +config XMC4_USIC1_ISLIN + bool "LIN" + select XMC4_USCI_LIN + ---help--- + Configure USIC1 as a LIN UART + +config XMC4_USIC1_ISSPI + bool "SPI" + select XMC4_USCI_SPI + ---help--- + Configure USIC1 For SPI communications + +config XMC4_USIC1_ISI2C + bool "I2C" + select XMC4_USCI_I2C + ---help--- + Configure USIC1 For I2C communications + +config XMC4_USIC1_ISI2S + bool "I2S" + select XMC4_USCI_I2S + ---help--- + Configure USIC1 For I2S audio + +endchoice # USIC1 Configuration + +choice + prompt "USIC2 Configuration" + default XMC4_USIC2_ISUART + depends on XMC4_USIC2 + +config XMC4_USIC2_ISUART + bool "UART" + select UART2_SERIALDRIVER + select XMC4_USCI_UART + ---help--- + Configure USIC2 as a UART + +config XMC4_USIC2_ISLIN + bool "LIN" + select XMC4_USCI_LIN + ---help--- + Configure USIC2 as a LIN UART + +config XMC4_USIC2_ISSPI + bool "SPI" + select XMC4_USCI_SPI + ---help--- + Configure USIC2 For SPI communications + +config XMC4_USIC2_ISI2C + bool "I2C" + select XMC4_USCI_I2C + ---help--- + Configure USIC2 For I2C communications + +config XMC4_USIC2_ISI2S + bool "I2S" + select XMC4_USCI_I2S + ---help--- + Configure USIC2 For I2S audio + +endchoice # USIC2 Configuration + +choice + prompt "USIC3 Configuration" + default XMC4_USIC3_ISUART + depends on XMC4_USIC3 + +config XMC4_USIC3_ISUART + bool "UART" + select UART3_SERIALDRIVER + select XMC4_USCI_UART + ---help--- + Configure USIC3 as a UART + +config XMC4_USIC3_ISLIN + bool "LIN" + select XMC4_USCI_LIN + ---help--- + Configure USIC3 as a LIN UART + +config XMC4_USIC3_ISSPI + bool "SPI" + select XMC4_USCI_SPI + ---help--- + Configure USIC3 For SPI communications + +config XMC4_USIC3_ISI2C + bool "I2C" + select XMC4_USCI_I2C + ---help--- + Configure USIC3 For I2C communications + +config XMC4_USIC3_ISI2S + bool "I2S" + select XMC4_USCI_I2S + ---help--- + Configure USIC3 For I2S audio + +endchoice # USIC3 Configuration + +choice + prompt "USIC4 Configuration" + default XMC4_USIC4_ISUART + depends on XMC4_USIC4 + +config XMC4_USIC4_ISUART + bool "UART" + select UART4_SERIALDRIVER + select XMC4_USCI_UART + ---help--- + Configure USIC4 as a UART + +config XMC4_USIC4_ISLIN + bool "LIN" + select XMC4_USCI_LIN + ---help--- + Configure USIC4 as a LIN UART + +config XMC4_USIC4_ISSPI + bool "SPI" + select XMC4_USCI_SPI + ---help--- + Configure USIC4 For SPI communications + +config XMC4_USIC4_ISI2C + bool "I2C" + select XMC4_USCI_I2C + ---help--- + Configure USIC4 For I2C communications + +config XMC4_USIC4_ISI2S + bool "I2S" + select XMC4_USCI_I2S + ---help--- + Configure USIC4 For I2S audio + +endchoice # USIC4 Configuration + +choice + prompt "USIC5 Configuration" + default XMC4_USIC5_ISUART + depends on XMC4_USIC5 + +config XMC4_USIC5_ISUART + bool "UART" + select UART0_SERIALDRIVER + select XMC4_USCI_UART + ---help--- + Configure USIC5 as a UART + +config XMC4_USIC5_ISLIN + bool "LIN" + select XMC4_USCI_LIN + ---help--- + Configure USIC5 as a LIN UART + +config XMC4_USIC5_ISSPI + bool "SPI" + select XMC4_USCI_SPI + ---help--- + Configure USIC5 For SPI communications + +config XMC4_USIC5_ISI2C + bool "I2C" + select XMC4_USCI_I2C + ---help--- + Configure USIC5 For I2C communications + +config XMC4_USIC5_ISI2S + bool "I2S" + select XMC4_USCI_I2S + ---help--- + Configure USIC5 For I2S audio + +endchoice # USIC5 Configuration +endmenu # XMC4xxx USIC Configuration diff --git a/arch/arm/src/xmc4/Make.defs b/arch/arm/src/xmc4/Make.defs new file mode 100644 index 0000000000..79497388a4 --- /dev/null +++ b/arch/arm/src/xmc4/Make.defs @@ -0,0 +1,141 @@ +############################################################################ +# arch/arm/src/kinetis/Make.defs +# +# Copyright (C) 2017 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. +# +############################################################################ + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +HEAD_ASRC = +else +HEAD_ASRC = xmc4_vectors.S +endif + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += up_testset.S vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c +CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_initialize.c up_memfault.c +CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_modifyreg8.c +CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c up_releasepending.c +CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_unblocktask.c up_usestack.c +CMN_CSRCS += up_doirq.c up_hardfault.c up_svcall.c up_vfork.c +CMN_CSRCS += up_systemreset.c + +ifeq ($(CONFIG_ARMV7M_STACKCHECK),y) +CMN_CSRCS += up_stackcheck.c +endif + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# Use of common/up_etherstub.c is deprecated. The preferred mechanism is to +# use CONFIG_NETDEV_LATEINIT=y to suppress the call to up_netinitialize() in +# up_initialize(). Then this stub would not be needed. + +ifeq ($(CONFIG_NET),y) +ifneq ($(CONFIG_XMC4_ENET),y) +CMN_CSRCS += up_etherstub.c +endif +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +ifeq ($(CONFIG_ARMV7M_ITMSYSLOG),y) +CMN_CSRCS += up_itm_syslog.c +endif + +# Required XMC4xxx files + +CHIP_ASRCS = + +CHIP_CSRCS = xmc4_allocateheap.c xmc4_clockconfig.c xmc4_clrpend.c +CHIP_CSRCS += xmc4_idle.c xmc4_irq.c xmc4_lowputc.c xmc4_gpio.c +CHIP_CSRCS += xmc4_serialinit.c xmc4_serial.c xmc4_start.c xmc4_uid.c + +# Configuration-dependent Kinetis files + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += xmc4_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += xmc4_userspace.c xmc4_mpuinit.c +endif + +ifeq ($(CONFIG_DEBUG_GPIO_INFO),y) +CHIP_CSRCS += xmc4_pindump.c +endif + +ifeq ($(CONFIG_XMC4_DMA),y) +CHIP_CSRCS += xmc4_dma.c +endif + +ifeq ($(CONFIG_PWM),y) +CHIP_CSRCS += xmc4_pwm.c +endif + +ifeq ($(CONFIG_I2C),y) +CHIP_CSRCS += xmc4_i2c.c +endif diff --git a/arch/arm/src/xmc4/chip.h b/arch/arm/src/xmc4/chip.h new file mode 100644 index 0000000000..ef746cfcc9 --- /dev/null +++ b/arch/arm/src/xmc4/chip.h @@ -0,0 +1,77 @@ +/************************************************************************************ + * arch/arm/src/xmc4/chip.h + * + * Copyright (C) 2017 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_XMC4_CHIP_H +#define __ARCH_ARM_SRC_XMC4_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Include the memory map and the chip definitions file. Other chip hardware files + * should then include this file for the proper setup. + */ + +#include +#include +#include "chip/xmc4_memorymap.h" + +/* If the common ARMv7-M vector handling logic is used, then it expects the + * following definition in this file that provides the number of supported external + * interrupts which, for this architecture, is provided in the arch/xmc4/chip.h + * header file. + */ + +#define ARMV7M_PERIPHERAL_INTERRUPTS NR_INTERRUPTS + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_XMC4_CHIP_H */ diff --git a/arch/arm/src/xmc4/xmc4_allocateheap.c b/arch/arm/src/xmc4/xmc4_allocateheap.c new file mode 100644 index 0000000000..cdbc8ef2d1 --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_allocateheap.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_allocateheap.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" +#include "xmc4_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Allow user-mode access to the user heap memory */ + + xmc4_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = CONFIG_RAM_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the CONFIG_RAM_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((CONFIG_RAM_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = CONFIG_RAM_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif diff --git a/arch/arm/src/xmc4/xmc4_clockconfig.c b/arch/arm/src/xmc4/xmc4_clockconfig.c new file mode 100644 index 0000000000..67efe53651 --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_clockconfig.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_clock_config.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Authors: 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "up_arch.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xmc4_clock_config + * + * Description: + * Called to initialize the XMC4xxx chip. This does whatever setup is + * needed to put the MCU in a usable state. This includes the + * initialization of clocking using the settings in board.h. + * + ****************************************************************************/ + +void xmc4_clock_config(void) +{ +} diff --git a/arch/arm/src/xmc4/xmc4_clrpend.c b/arch/arm/src/xmc4/xmc4_clrpend.c new file mode 100644 index 0000000000..2eab7d6ffa --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_clrpend.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_clrpend.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "nvic.h" +#include "up_arch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xmc4_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. This does not seem to be required + * for most interrupts. Don't know why... + * + * I keep it in a separate file so that it will not increase the footprint + * on Kinetis platforms that do not need this function. + * + ****************************************************************************/ + +void xmc4_clrpend(int irq) +{ + /* Check for external interrupt */ + + if (irq >= XMC4_IRQ_FIRST) + { + if (irq < (XMC4_IRQ_FIRST+32)) + { + putreg32(1 << (irq - XMC4_IRQ_FIRST), NVIC_IRQ0_31_CLRPEND); + } + else if (irq < (XMC4_IRQ_FIRST+64)) + { + putreg32(1 << (irq - XMC4_IRQ_FIRST - 32), NVIC_IRQ32_63_CLRPEND); + } + else if (irq < (XMC4_IRQ_FIRST+96)) + { + putreg32(1 << (irq - XMC4_IRQ_FIRST - 64), NVIC_IRQ64_95_CLRPEND); + } + else if (irq < NR_IRQS) + { + putreg32(1 << (irq - XMC4_IRQ_FIRST - 96), NVIC_IRQ96_127_CLRPEND); + } + } +} diff --git a/arch/arm/src/xmc4/xmc4_config.h b/arch/arm/src/xmc4/xmc4_config.h new file mode 100644 index 0000000000..e81932569e --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_config.h @@ -0,0 +1,198 @@ +/************************************************************************************ + * arch/arm/src/xmc4/xmc4_config.h + * + * Copyright (C) 2017 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_XMC4_XMC4_CONFIG_H +#define __ARCH_ARM_SRC_XMC4_XMC4_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration *********************************************************************/ +/* Make sure that no unsupported UARTs are enabled */ + +#ifndef CONFIG_XMC4_USIC0 +# undef CONFIG_XMC4_USIC0_ISUART +#endif +#ifndef CONFIG_XMC4_USIC1 +# undef CONFIG_XMC4_USIC1_ISUART +#endif +#ifndef CONFIG_XMC4_USIC2 +# undef CONFIG_XMC4_USIC2_ISUART +#endif +#ifndef CONFIG_XMC4_USIC3 +# undef CONFIG_XMC4_USIC3_ISUART +#endif +#ifndef CONFIG_XMC4_USIC4 +# undef CONFIG_XMC4_USIC4_ISUART +#endif +#ifndef CONFIG_XMC4_USIC5 +# undef CONFIG_XMC4_USIC5_ISUART +#endif + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_XMC4_USIC0_ISUART) || defined(CONFIG_XMC4_USIC1_ISUART) || \ + defined(CONFIG_XMC4_USIC2_ISUART) || defined(CONFIG_XMC4_USIC3_ISUART) || \ + defined(CONFIG_XMC4_USIC3_ISUART) || defined(CONFIG_XMC4_USIC4_ISUART) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2,3,4,5 + */ + +#undef HAVE_UART_CONSOLE + +#if defined(CONFIG_CONSOLE_SYSLOG) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +#else +# if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_XMC4_USIC0_ISUART) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_XMC4_USIC1_ISUART) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_XMC4_USIC2_ISUART) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_XMC4_USIC3_ISUART) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_XMC4_USIC4_ISUART) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_XMC4_USIC5_ISUART) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# define HAVE_UART_CONSOLE 1 +# else +# ifdef CONFIG_DEV_CONSOLE +# warning "No valid CONFIG_[LP]UART[n]_SERIAL_CONSOLE Setting" +# endif +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# endif +#endif + +/* Check UART flow control (Not yet supported) */ + +# undef CONFIG_UART0_FLOWCONTROL +# undef CONFIG_UART1_FLOWCONTROL +# undef CONFIG_UART2_FLOWCONTROL +# undef CONFIG_UART3_FLOWCONTROL +# undef CONFIG_UART4_FLOWCONTROL +# undef CONFIG_UART5_FLOWCONTROL + +/* UART Default Interrupt Priorities */ + +#ifndef CONFIG_XMC4_UART0PRIO +# define CONFIG_XMC4_UART0PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_XMC4_UART1PRIO +# define CONFIG_XMC4_UART1PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_XMC4_UART2PRIO +# define CONFIG_XMC4_UART2PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_XMC4_UART3PRIO +# define CONFIG_XMC4_UART3PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_XMC4_UART4PRIO +# define CONFIG_XMC4_UART4PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif +#ifndef CONFIG_XMC4_UART5PRIO +# define CONFIG_XMC4_UART5PRIO NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_XMC4_XMC4_CONFIG_H */ diff --git a/arch/arm/src/xmc4/xmc4_dma.c b/arch/arm/src/xmc4/xmc4_dma.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arch/arm/src/xmc4/xmc4_dma.h b/arch/arm/src/xmc4/xmc4_dma.h new file mode 100644 index 0000000000..8f2edba432 --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_dma.h @@ -0,0 +1,218 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_dma.h + * + * Copyright (C) 2017 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_XMC4_XMC4_DMA_H +#define __ARCH_ARM_SRC_XMC4_XMC4_DMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip/xmc4_dma.h" + +/**************************************************************************** + * Pre-processor Declarations + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef FAR void *DMA_HANDLE; +typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */ + +#ifdef CONFIG_DEBUG_DMA +struct xmc4_dmaglobalregs_s +{ +#warning "Missing logic" + /* Global Registers */ +}; + +struct xmc4_dmachanregs_s +{ +#warning "Missing logic" + /* Channel Registers */ +}; + +struct xmc4_dmaregs_s +{ + /* Global Registers */ + + struct xmc4_dmaglobalregs_s gbl; + + /* Channel Registers */ + + struct xmc4_dmachanregs_s ch; +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: xmc4_dmainitialize + * + * Description: + * Initialize the GPDMA subsystem. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void xmc4_dmainitilaize(void); + +/**************************************************************************** + * Name: xmc4_dmachannel + * + * Description: + * Allocate a DMA channel. This function sets aside a DMA channel and + * gives the caller exclusive access to the DMA channel. + * + * Returned Value: + * One success, this function returns a non-NULL, void* DMA channel + * handle. NULL is returned on any failure. This function can fail only + * if no DMA channel is available. + * + ****************************************************************************/ + +DMA_HANDLE xmc4_dmachannel(void); + +/**************************************************************************** + * Name: xmc4_dmafree + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until xmc4_dmachannel() is called again to re-gain + * a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void xmc4_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: xmc4_dmasetup + * + * Description: + * Configure DMA for one transfer. + * + ****************************************************************************/ + +int xmc4_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config, + uint32_t srcaddr, uint32_t destaddr, size_t nbytes); + +/**************************************************************************** + * Name: xmc4_dmastart + * + * Description: + * Start the DMA transfer + * + ****************************************************************************/ + +int xmc4_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/**************************************************************************** + * Name: xmc4_dmastop + * + * Description: + * Cancel the DMA. After xmc4_dmastop() is called, the DMA channel is + * reset and xmc4_dmasetup() must be called before xmc4_dmastart() can be + * called again + * + ****************************************************************************/ + +void xmc4_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: xmc4_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void xmc4_dmasample(DMA_HANDLE handle, struct xmc4_dmaregs_s *regs); +#else +# define xmc4_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: xmc4_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void xmc4_dmadump(DMA_HANDLE handle, const struct xmc4_dmaregs_s *regs, + const char *msg); +#else +# define xmc4_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_XMC4_XMC4_DMA_H */ diff --git a/arch/arm/src/xmc4/xmc4_gpio.c b/arch/arm/src/xmc4/xmc4_gpio.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arch/arm/src/xmc4/xmc4_gpio.h b/arch/arm/src/xmc4/xmc4_gpio.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arch/arm/src/xmc4/xmc4_i2c.c b/arch/arm/src/xmc4/xmc4_i2c.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arch/arm/src/xmc4/xmc4_i2c.h b/arch/arm/src/xmc4/xmc4_i2c.h new file mode 100644 index 0000000000..f4a167b713 --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_i2c.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_i2c.h + * + * Copyright (C) 2017 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_XMC4_XMC4_I2C_H +#define __ARCH_ARM_SRC_XMC4_XMC4_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip/xmc4_i2c.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: xmc4_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *xmc4_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: xmc4_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the lpc43_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int xmc4_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_XMC4_XMC4_I2C_H */ diff --git a/arch/arm/src/xmc4/xmc4_idle.c b/arch/arm/src/xmc4/xmc4_idle.c new file mode 100644 index 0000000000..411324311f --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_idle.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_idle.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Sleep until an interrupt occurs to save power */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +} diff --git a/arch/arm/src/xmc4/xmc4_irq.c b/arch/arm/src/xmc4/xmc4_irq.c new file mode 100644 index 0000000000..17725b8c60 --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_irq.c @@ -0,0 +1,588 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_irq.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xmc4_dump_nvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ_INFO) +static void xmc4_dump_nvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + irqinfo("NVIC (%s, irq=%d):\n", msg, irq); + irqinfo(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + irqinfo(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + irqinfo(" IRQ ENABLE: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE), getreg32(NVIC_IRQ96_127_ENABLE)); + irqinfo(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + irqinfo(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY), getreg32(NVIC_IRQ68_71_PRIORITY), + getreg32(NVIC_IRQ72_75_PRIORITY), getreg32(NVIC_IRQ76_79_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ80_83_PRIORITY), getreg32(NVIC_IRQ84_87_PRIORITY), + getreg32(NVIC_IRQ88_91_PRIORITY), getreg32(NVIC_IRQ92_95_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ96_99_PRIORITY), getreg32(NVIC_IRQ100_103_PRIORITY), + getreg32(NVIC_IRQ104_107_PRIORITY), getreg32(NVIC_IRQ108_111_PRIORITY)); +#if NR_VECTORS > 111 + irqinfo(" %08x %08x\n", + getreg32(NVIC_IRQ112_115_PRIORITY), getreg32(NVIC_IRQ116_119_PRIORITY)); +#endif + + leave_critical_section(flags); +} +#else +# define xmc4_dump_nvic(msg, irq) +#endif + +/**************************************************************************** + * Name: xmc4_nmi, xmc4_busfault, xmc4_usagefault, xmc4_pendsv, + * xmc4_dbgmonitor, xmc4_pendsv, xmc4_reserved + * + * Description: + * Handlers for various execptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +static int xmc4_nmi(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int xmc4_busfault(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Bus fault recived\n"); + PANIC(); + return 0; +} + +static int xmc4_usagefault(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Usage fault received\n"); + PANIC(); + return 0; +} + +static int xmc4_pendsv(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int xmc4_dbgmonitor(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int xmc4_reserved(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: xmc4_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void xmc4_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: xmc4_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int xmc4_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= XMC4_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= XMC4_IRQ_FIRST) + { + if (irq < (XMC4_IRQ_FIRST+32)) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - XMC4_IRQ_FIRST); + } + else if (irq < (XMC4_IRQ_FIRST+64)) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - XMC4_IRQ_FIRST - 32); + } + else if (irq < (XMC4_IRQ_FIRST+96)) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (irq - XMC4_IRQ_FIRST - 64); + } + else if (irq < NR_IRQS) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (irq - XMC4_IRQ_FIRST - 96); + } + else + { + return ERROR; /* Invalid irq */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == XMC4_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == XMC4_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == XMC4_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == XMC4_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t regaddr; + int nintlines; + int i; + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports, defined in groups of 32. That is, + * the total number of interrupt lines is up to (32*(INTLINESNUM+1)). + * + * 0 -> 32 interrupt lines, 1 enable register, 8 priority registers + * 1 -> 64 " " " ", 2 enable registers, 16 priority registers + * 2 -> 96 " " " ", 3 enable regsiters, 24 priority registers + * ... + */ + + nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1; + + /* Disable all interrupts. There are nintlines interrupt enable + * registers. + */ + + for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE; + i > 0; + i--, regaddr += 4) + { + putreg32(0, regaddr); + } + + /* 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 + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* Now set all of the interrupt lines to the default priority. There are + * nintlines * 8 priority registers. + */ + + for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY; + i > 0; + i--, regaddr += 4) + { + putreg32(DEFPRIORITY32, regaddr); + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(XMC4_IRQ_SVCALL, up_svcall, NULL); + irq_attach(XMC4_IRQ_HARDFAULT, up_hardfault, NULL); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(XMC4_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + xmc4_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(XMC4_IRQ_MEMFAULT, up_memfault, NULL); + up_enable_irq(XMC4_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG_FEATURES + irq_attach(XMC4_IRQ_NMI, xmc4_nmi, NULL); +#ifndef CONFIG_ARM_MPU + irq_attach(XMC4_IRQ_MEMFAULT, up_memfault, NULL); +#endif + irq_attach(XMC4_IRQ_BUSFAULT, xmc4_busfault, NULL); + irq_attach(XMC4_IRQ_USAGEFAULT, xmc4_usagefault, NULL); + irq_attach(XMC4_IRQ_PENDSV, xmc4_pendsv, NULL); + irq_attach(XMC4_IRQ_DBGMONITOR, xmc4_dbgmonitor, NULL); + irq_attach(XMC4_IRQ_RESERVED, xmc4_reserved, NULL); +#endif + + xmc4_dump_nvic("initial", NR_IRQS); + + /* Initialize logic to support a second level of interrupt decoding for + * configured pin interrupts. + */ + +#ifdef CONFIG_XMC4_GPIOIRQ + xmc4_gpioirq_initialize(); +#endif + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (xmc4_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= XMC4_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } + + xmc4_dump_nvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (xmc4_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= XMC4_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } + + xmc4_dump_nvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ +#if 0 /* Does not appear to be necessary in most cases */ + xmc4_clrpend(irq); +#endif +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= XMC4_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < XMC4_IRQ_FIRST) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= XMC4_IRQ_FIRST; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + xmc4_dump_nvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/xmc4/xmc4_lowputc.c b/arch/arm/src/xmc4/xmc4_lowputc.c new file mode 100644 index 0000000000..8fe2f4094b --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_lowputc.c @@ -0,0 +1,235 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_lowputc.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "xmc4_config.h" +#include "chip/xmc4_uart.h" +#include "chip/xmc4_pinmux.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(HAVE_UART_CONSOLE) +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE XMC4_UART0_BASE +# define CONSOLE_FREQ BOARD_CORECLK_FREQ +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_2STOP CONFIG_UART0_2STOP +# define CONSOLE_PARITY CONFIG_UART0_PARITY +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE XMC4_UART1_BASE +# define CONSOLE_FREQ BOARD_CORECLK_FREQ +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_2STOP CONFIG_UART1_2STOP +# define CONSOLE_PARITY CONFIG_UART1_PARITY +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE XMC4_UART2_BASE +# define CONSOLE_FREQ BOARD_BUS_FREQ +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_2STOP CONFIG_UART2_2STOP +# define CONSOLE_PARITY CONFIG_UART2_PARITY +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_BASE XMC4_UART3_BASE +# define CONSOLE_FREQ BOARD_BUS_FREQ +# define CONSOLE_BAUD CONFIG_UART3_BAUD +# define CONSOLE_BITS CONFIG_UART3_BITS +# define CONSOLE_2STOP CONFIG_UART3_2STOP +# define CONSOLE_PARITY CONFIG_UART3_PARITY +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_BASE XMC4_UART4_BASE +# define CONSOLE_FREQ BOARD_BUS_FREQ +# define CONSOLE_BAUD CONFIG_UART4_BAUD +# define CONSOLE_BITS CONFIG_UART4_BITS +# define CONSOLE_2STOP CONFIG_UART4_2STOP +# define CONSOLE_PARITY CONFIG_UART4_PARITY +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define CONSOLE_BASE XMC4_UART5_BASE +# define CONSOLE_FREQ BOARD_BUS_FREQ +# define CONSOLE_BAUD CONFIG_UART5_BAUD +# define CONSOLE_BITS CONFIG_UART5_BITS +# define CONSOLE_2STOP CONFIG_UART5_2STOP +# define CONSOLE_PARITY CONFIG_UART5_PARITY +# elif defined(HAVE_UART_CONSOLE) +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +# endif +#endif /* HAVE_UART_CONSOLE */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_UART_CONSOLE + /* Wait until the transmit data register is "empty" (TDRE). This state + * depends on the TX watermark setting and may not mean that the transmit + * buffer is truly empty. It just means that we can now add another + * character to the transmit buffer without exceeding the watermark. + * + * NOTE: UART0 has an 8-byte deep FIFO; the other UARTs have no FIFOs + * (1-deep). There appears to be no way to know when the FIFO is not + * full (other than reading the FIFO length and comparing the FIFO count). + * Hence, the FIFOs are not used in this implementation and, as a result + * TDRE indeed mean that the single output buffer is available. + * + * Performance on UART0 could be improved by enabling the FIFO and by + * redesigning all of the FIFO status logic. + */ +#warning Missing logic + + /* Then write the character to the UART data register */ + +#warning Missing logic +} + +/**************************************************************************** + * Name: xmc4_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output available as soon + * as possible. + * + ****************************************************************************/ + +void xmc4_lowsetup(void) +{ + uint32_t regval; + + /* Enable peripheral clocking for all enabled UARTs. */ +#wanring Missing logic + + /* Configure UART pins for the all enabled UARTs */ + + /* Configure the console (only) now. Other UARTs will be configured + * when the serial driver is opened. + */ + + xmc4_uart_configure(CONSOLE_BASE, CONSOLE_BAUD, CONSOLE_FREQ, \ + CONSOLE_PARITY, CONSOLE_BITS, CONSOLE_2STOP); +#endif /* HAVE_UART_DEVICE */ +} + +/**************************************************************************** + * Name: xmc4_uart_reset + * + * Description: + * Reset a UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void xmc4_uart_reset(uintptr_t uart_base) +{ + uint8_t regval; + + /* Just disable the transmitter and receiver */ +#warning Missing logic +} +#endif + +/**************************************************************************** + * Name: xmc4_uart_configure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ****************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void xmc4_uart_configure(uintptr_t uart_base, uint32_t baud, + uint32_t clock, unsigned int parity, + unsigned int nbits, unsigned int stop2) +{ + /* Disable the transmitter and receiver throughout the reconfiguration */ +#warning Missing logic + + /* Configure number of bits, stop bits and parity */ +#warning Missing logic + + /* Check for odd parity */ +#warning Missing logic + + /* Check for even parity */ +#warning Missing logic + + /* Check for 9-bit operation */ +#warning Missing logic + + /* Calculate baud settings (truncating) */ +#warning Missing logic + + /* Configure FIFOs */ +#warning Missing logic + + /* Enable RX and TX FIFOs */ +#warning Missing logic + + /* Now we can (re-)enable the transmitter and receiver */ +#warning Missing logic +} +#endif + diff --git a/arch/arm/src/xmc4/xmc4_mpuinit.c b/arch/arm/src/xmc4/xmc4_mpuinit.c new file mode 100644 index 0000000000..9cd22451be --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_mpuinit.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_mpuinit.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "mpu.h" +#include "xmc4_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xmc4_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3U + * resources. + * + ****************************************************************************/ + +void xmc4_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: xmc4_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void xmc4_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ + diff --git a/arch/arm/src/xmc4/xmc4_mpuinit.h b/arch/arm/src/xmc4/xmc4_mpuinit.h new file mode 100644 index 0000000000..f318424bad --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_mpuinit.h @@ -0,0 +1,78 @@ +/************************************************************************************ + * arch/arm/src/xmc4/xmc4_mpuinit.h + * + * Copyright (C) 2017 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_XMC4_XMC4_MPUINIT_H +#define __ARCH_ARM_SRC_XMC4_XMC4_MPUINIT_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: xmc4_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted MCU + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void xmc4_mpuinitialize(void); +#else +# define xmc4_mpuinitialize() +#endif + +/**************************************************************************** + * Name: xmc4_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void xmc4_mpu_uheap(uintptr_t start, size_t size); +#else +# define xmc4_mpu_uheap(start,size) +#endif + +#endif /* __ARCH_ARM_SRC_XMC4_XMC4_MPUINIT_H */ diff --git a/arch/arm/src/xmc4/xmc4_pwm.c b/arch/arm/src/xmc4/xmc4_pwm.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arch/arm/src/xmc4/xmc4_pwm.h b/arch/arm/src/xmc4/xmc4_pwm.h new file mode 100644 index 0000000000..4de5b5f56a --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_pwm.h @@ -0,0 +1,100 @@ +/************************************************************************************ + * arch/arm/src/xmc4/xmc4_pwm.h + * + * Copyright (C) 2017 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_XMC4_XMC4_PWM_H +#define __ARCH_ARM_SRC_XMC4_XMC4_PWM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Configuration ********************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: xmc4_pwm_initialize + * + * Description: + * Initialize one timer for use with the upper_level PWM driver. + * + * Input Parameters: + * timer - A number identifying the timer use. + * + * Returned Value: + * On success, a pointer to the kinetis lower half PWM driver is returned. + * NULL is returned on any failure. + * + ************************************************************************************/ + +FAR struct pwm_lowerhalf_s *xmc4_pwm_initialize(int timer); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_XMC4_FTMx_PWM */ +#endif /* __ARCH_ARM_SRC_XMC4_XMC4_PWM_H */ diff --git a/arch/arm/src/xmc4/xmc4_serial.c b/arch/arm/src/xmc4/xmc4_serial.c new file mode 100644 index 0000000000..b90f1c19ff --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_serial.c @@ -0,0 +1,1146 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_serial.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "xmc4_config.h" +#include "chip.h" +#include "chip/xmc4_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* Is there at least one UART enabled and configured as a RS-232 device? */ + +#ifndef HAVE_UART_DEVICE +# warning "No UARTs enabled" +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#if defined(HAVE_UART_DEVICE) && defined(USE_SERIALDRIVER) + +/* Which UART with be tty0/console and which tty1-4? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +/* First pick the console and ttys0. This could be any of UART0-5 */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2 is console */ +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart3port /* UART3 is console */ +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart4port /* UART4 is console */ +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart5port /* UART5 is console */ +# define TTYS5_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +#else +# undef CONSOLE_DEV /* No console */ +# if defined(CONFIG_XMC4_USIC0_ISUART) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# define UART0_ASSIGNED 1 +# elif defined(CONFIG_XMC4_USIC1_ISUART) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# define UART1_ASSIGNED 1 +# elif defined(CONFIG_XMC4_USIC2_ISUART) +# define TTYS0_DEV g_uart2port /* UART2 is ttyS0 */ +# define UART2_ASSIGNED 1 +# elif defined(CONFIG_XMC4_USIC3_ISUART) +# define TTYS0_DEV g_uart3port /* UART3 is ttyS0 */ +# define UART3_ASSIGNED 1 +# elif defined(CONFIG_XMC4_USIC4_ISUART) +# define TTYS0_DEV g_uart4port /* UART4 is ttyS0 */ +# define UART4_ASSIGNED 1 +# elif defined(CONFIG_XMC4_USIC5_ISUART) +# define TTYS0_DEV g_uart5port /* UART5 is ttyS0 */ +# define UART5_ASSIGNED 1 +# endif +#endif + +/* Pick ttys1. This could be any of UART0-5 excluding the console UART. */ + +#if defined(CONFIG_XMC4_USIC0_ISUART) && !defined(UART0_ASSIGNED) +# define TTYS1_DEV g_uart0port /* UART0 is ttyS1 */ +# define UART0_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC1_ISUART) && !defined(UART1_ASSIGNED) +# define TTYS1_DEV g_uart1port /* UART1 is ttyS1 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC2_ISUART) && !defined(UART2_ASSIGNED) +# define TTYS1_DEV g_uart2port /* UART2 is ttyS1 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC3_ISUART) && !defined(UART3_ASSIGNED) +# define TTYS1_DEV g_uart3port /* UART3 is ttyS1 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC4_ISUART) && !defined(UART4_ASSIGNED) +# define TTYS1_DEV g_uart4port /* UART4 is ttyS1 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC5_ISUART) && !defined(UART5_ASSIGNED) +# define TTYS1_DEV g_uart5port /* UART5 is ttyS1 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys2. This could be one of UART1-5. It can't be UART0 because that + * was either assigned as ttyS0 or ttys1. One of UART 1-5 could also be the + * console. + */ + +#if defined(CONFIG_XMC4_USIC1_ISUART) && !defined(UART1_ASSIGNED) +# define TTYS2_DEV g_uart1port /* UART1 is ttyS2 */ +# define UART1_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC2_ISUART) && !defined(UART2_ASSIGNED) +# define TTYS2_DEV g_uart2port /* UART2 is ttyS2 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC3_ISUART) && !defined(UART3_ASSIGNED) +# define TTYS2_DEV g_uart3port /* UART3 is ttyS2 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC4_ISUART) && !defined(UART4_ASSIGNED) +# define TTYS2_DEV g_uart4port /* UART4 is ttyS2 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC5_ISUART) && !defined(UART5_ASSIGNED) +# define TTYS2_DEV g_uart5port /* UART5 is ttyS2 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys3. This could be one of UART2-5. It can't be UART0-1 because + * those have already been assigned to ttsyS0, 1, or 2. One of + * UART 2-5 could also be the console. + */ + +#if defined(CONFIG_XMC4_USIC2_ISUART) && !defined(UART2_ASSIGNED) +# define TTYS3_DEV g_uart2port /* UART2 is ttyS3 */ +# define UART2_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC3_ISUART) && !defined(UART3_ASSIGNED) +# define TTYS3_DEV g_uart3port /* UART3 is ttyS3 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC4_ISUART) && !defined(UART4_ASSIGNED) +# define TTYS3_DEV g_uart4port /* UART4 is ttyS3 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC5_ISUART) && !defined(UART5_ASSIGNED) +# define TTYS3_DEV g_uart5port /* UART5 is ttyS3 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys4. This could be one of UART3-5. It can't be UART0-2 because + * those have already been assigned to ttsyS0, 1, 2 or 3. One of + * UART 3-5 could also be the console. + */ + +#if defined(CONFIG_XMC4_USIC3_ISUART) && !defined(UART3_ASSIGNED) +# define TTYS4_DEV g_uart3port /* UART3 is ttyS4 */ +# define UART3_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC4_ISUART) && !defined(UART4_ASSIGNED) +# define TTYS4_DEV g_uart4port /* UART4 is ttyS4 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC5_ISUART) && !defined(UART5_ASSIGNED) +# define TTYS4_DEV g_uart5port /* UART5 is ttyS4 */ +# define UART5_ASSIGNED 1 +#endif + +/* Pick ttys5. This could be one of UART4-5. It can't be UART0-3 because + * those have already been assigned to ttsyS0, 1, 2, 3 or 4. One of + * UART 4-5 could also be the console. + */ + +#if defined(CONFIG_XMC4_USIC4_ISUART) && !defined(UART4_ASSIGNED) +# define TTYS5_DEV g_uart4port /* UART4 is ttyS5 */ +# define UART4_ASSIGNED 1 +#elif defined(CONFIG_XMC4_USIC5_ISUART) && !defined(UART5_ASSIGNED) +# define TTYS5_DEV g_uart5port /* UART5 is ttyS5 */ +# define UART5_ASSIGNED 1 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct xmc4_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint32_t clock; /* Clocking frequency of the UART module */ + uint8_t irqs; /* Status IRQ associated with this UART (for enable) */ + uint8_t ie; /* Interrupts enabled */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (8 or 9) */ + uint8_t stop2; /* Use 2 stop bits */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int xmc4_setup(struct uart_dev_s *dev); +static void xmc4_shutdown(struct uart_dev_s *dev); +static int xmc4_attach(struct uart_dev_s *dev); +static void xmc4_detach(struct uart_dev_s *dev); +static int xmc4_interrupt(int irq, void *context, FAR void *arg); +static int xmc4_ioctl(struct file *filep, int cmd, unsigned long arg); +static int xmc4_receive(struct uart_dev_s *dev, uint32_t *status); +static void xmc4_rxint(struct uart_dev_s *dev, bool enable); +static bool xmc4_rxavailable(struct uart_dev_s *dev); +static void xmc4_send(struct uart_dev_s *dev, int ch); +static void xmc4_txint(struct uart_dev_s *dev, bool enable); +static bool xmc4_txready(struct uart_dev_s *dev); +static bool xmc4_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = xmc4_setup, + .shutdown = xmc4_shutdown, + .attach = xmc4_attach, + .detach = xmc4_detach, + .ioctl = xmc4_ioctl, + .receive = xmc4_receive, + .rxint = xmc4_rxint, + .rxavailable = xmc4_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = xmc4_send, + .txint = xmc4_txint, + .txready = xmc4_txready, + .txempty = xmc4_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_XMC4_USIC0_ISUART +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +#endif +#ifdef CONFIG_XMC4_USIC1_ISUART +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_XMC4_USIC2_ISUART +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif +#ifdef CONFIG_XMC4_USIC3_ISUART +static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE]; +#endif +#ifdef CONFIG_XMC4_USIC4_ISUART +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +#endif +#ifdef CONFIG_XMC4_USIC5_ISUART +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +#endif + +/* This describes the state of the Kinetis UART0 port. */ + +#ifdef CONFIG_XMC4_USIC0_ISUART +static struct xmc4_dev_s g_uart0priv = +{ + .uartbase = XMC4_UART0_BASE, + .clock = BOARD_CORECLK_FREQ, + .baud = CONFIG_UART0_BAUD, + .irqs = XMC4_IRQ_USIC0, + .parity = CONFIG_UART0_PARITY, + .bits = CONFIG_UART0_BITS, + .stop2 = CONFIG_UART0_2STOP, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/* This describes the state of the Kinetis UART1 port. */ + +#ifdef CONFIG_XMC4_USIC1_ISUART +static struct xmc4_dev_s g_uart1priv = +{ + .uartbase = XMC4_UART1_BASE, + .clock = BOARD_CORECLK_FREQ, + .baud = CONFIG_UART1_BAUD, + .irqs = XMC4_IRQ_USIC1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stop2 = CONFIG_UART1_2STOP, +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the Kinetis UART2 port. */ + +#ifdef CONFIG_XMC4_USIC2_ISUART +static struct xmc4_dev_s g_uart2priv = +{ + .uartbase = XMC4_UART2_BASE, + .clock = BOARD_BUS_FREQ, + .baud = CONFIG_UART2_BAUD, + .irqs = XMC4_IRQ_USIC2, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stop2 = CONFIG_UART2_2STOP, +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +/* This describes the state of the Kinetis UART3 port. */ + +#ifdef CONFIG_XMC4_USIC3_ISUART +static struct xmc4_dev_s g_uart3priv = +{ + .uartbase = XMC4_UART3_BASE, + .clock = BOARD_BUS_FREQ, + .baud = CONFIG_UART3_BAUD, + .irqs = XMC4_IRQ_USIC3, + .parity = CONFIG_UART3_PARITY, + .bits = CONFIG_UART3_BITS, + .stop2 = CONFIG_UART3_2STOP, +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/* This describes the state of the Kinetis UART4 port. */ + +#ifdef CONFIG_XMC4_USIC4_ISUART +static struct xmc4_dev_s g_uart4priv = +{ + .uartbase = XMC4_UART4_BASE, + .clock = BOARD_BUS_FREQ, + .baud = CONFIG_UART4_BAUD, + .irqs = XMC4_IRQ_USIC4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stop2 = CONFIG_UART4_2STOP, +}; + +static uart_dev_t g_uart4port = +{ + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart4priv, +}; +#endif + +/* This describes the state of the Kinetis UART5 port. */ + +#ifdef CONFIG_XMC4_USIC5_ISUART +static struct xmc4_dev_s g_uart5priv = +{ + .uartbase = XMC4_UART5_BASE, + .clock = BOARD_BUS_FREQ, + .baud = CONFIG_UART5_BAUD, + .irqs = XMC4_IRQ_USIC5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stop2 = CONFIG_UART5_2STOP, +}; + +static uart_dev_t g_uart5port = +{ + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart5priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint8_t up_serialin(struct xmc4_dev_s *priv, int offset) +{ + return getreg8(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct xmc4_dev_s *priv, int offset, uint8_t value) +{ + putreg8(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_setuartint + ****************************************************************************/ + +static void up_setuartint(struct xmc4_dev_s *priv) +{ + irqstate_t flags; + uint8_t regval; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in ie */ +#warning Missing logic + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct xmc4_dev_s *priv, uint8_t ie) +{ + irqstate_t flags; + + /* Re-enable/re-disable interrupts corresponding to the state of bits in ie */ + + flags = enter_critical_section(); +#warning Missing logic + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct xmc4_dev_s *priv, uint8_t *ie) +{ + irqstate_t flags; + + flags = enter_critical_section(); + if (ie) + { + *ie = priv->ie; + } + + up_restoreuartint(priv, 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: xmc4_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int xmc4_setup(struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + + /* Configure the UART as an RS-232 UART */ + + xmc4_uart_configure(priv->uartbase, priv->baud, priv->clock, + priv->parity, priv->bits, priv->stop2); +#endif + + /* Make sure that all interrupts are disabled */ + + up_restoreuartint(priv, 0); + return OK; +} + +/**************************************************************************** + * Name: xmc4_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void xmc4_shutdown(struct uart_dev_s *dev) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_restoreuartint(priv, 0); + + /* Reset hardware and disable Rx and Tx */ + + xmc4_uart_reset(priv->uartbase); +} + +/**************************************************************************** + * Name: xmc4_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int xmc4_attach(struct uart_dev_s *dev) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ(s). The interrupts are (probably) still + * disabled in the C2 register. + */ + + ret = irq_attach(priv->irqs, xmc4_interrupt, dev); + if (ret == OK) + { + up_enable_irq(priv->irqs); + } + + return ret; +} + +/**************************************************************************** + * Name: xmc4_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void xmc4_detach(struct uart_dev_s *dev) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_restoreuartint(priv, 0); + up_disable_irq(priv->irqs); + + /* Detach from the interrupt(s) */ + + irq_detach(priv->irqs); +} + +/**************************************************************************** + * Name: xmc4_interrupt + * + * Description: + * This is the UART status interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * approprite uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int xmc4_interrupt(int irq, void *context, FAR void *arg) +{ + struct uart_dev_s *dev = (struct uart_dev_s *)arg; + struct xmc4_dev_s *priv; + int passes; + uint8_t s1; + bool handled; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct xmc4_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Read status register 1 */ + + s1 = up_serialin(priv, XMC4_UART_S1_OFFSET); + + /* Handle incoming, receive bytes */ + + /* Check if the receive data register is full (RDRF). NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is full, + * rather, it means that the number of bytes in the RX FIFO has + * exceeded the watermark setting. There may actually be RX data + * available! + * + * The RDRF status indication is cleared when the data is read from + * the RX data register. + */ + +#warning Missing logic + { + /* Process incoming bytes */ + + uart_recvchars(dev); + handled = true; + } + + /* Handle outgoing, transmit bytes */ + + /* Check if the transmit data register is "empty." NOTE: If FIFOS + * are enabled, this does not mean that the FIFO is empty, rather, + * it means that the number of bytes in the TX FIFO is below the + * watermark setting. There could actually be space for additional TX + * data. + * + * The TDRE status indication is cleared when the data is written to + * the TX data register. + */ + +#warning Missing logic + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: xmc4_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int xmc4_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if 0 /* Reserved for future growth */ + struct inode *inode; + struct uart_dev_s *dev; + struct xmc4_dev_s *priv; + int ret = OK; + + DEBUGASSERT(filep, filep->f_inode); + inode = filep->f_inode; + dev = inode->i_private; + + DEBUGASSERT(dev, dev->priv); + priv = (struct xmc4_dev_s *)dev->priv; + + switch (cmd) + { + case xxx: /* Add commands here */ + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: xmc4_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int xmc4_receive(struct uart_dev_s *dev, uint32_t *status) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + uint8_t s1; + + /* Get error status information: + * + * FE: Framing error. To clear FE, read S1 with FE set and then read + * read UART data register (D). + * NF: Noise flag. To clear NF, read S1 and then read the UART data + * register (D). + * PF: Parity error flag. To clear PF, read S1 and then read the UART + * data register (D). + */ + + s1 = up_serialin(priv, XMC4_UART_S1_OFFSET); + + /* Return status information */ + + if (status) + { + *status = (uint32_t)s1; + } + + /* Then return the actual received byte. Reading S1 then D clears all + * RX errors. + */ + + return (int)up_serialin(priv, XMC4_UART_D_OFFSET); +} + +/**************************************************************************** + * Name: xmc4_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void xmc4_rxint(struct uart_dev_s *dev, bool enable) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ie |= UART_C2_RIE; + up_setuartint(priv); +#endif + } + else + { +#ifdef CONFIG_DEBUG_FEATURES +# warning "Revisit: How are errors enabled?" + priv->ie &= ~UART_C2_RIE; +#else + priv->ie &= ~UART_C2_RIE; +#endif + up_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: xmc4_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool xmc4_rxavailable(struct uart_dev_s *dev) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + /* Return true if the receive data register is full (RDRF). NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is full, + * rather, it means that the number of bytes in the RX FIFO has + * exceeded the watermark setting. There may actually be RX data + * available! + */ + + return (up_serialin(priv, XMC4_UART_S1_OFFSET) & UART_S1_RDRF) != 0; +} + +/**************************************************************************** + * Name: xmc4_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void xmc4_send(struct uart_dev_s *dev, int ch) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + up_serialout(priv, XMC4_UART_D_OFFSET, (uint8_t)ch); +} + +/**************************************************************************** + * Name: xmc4_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void xmc4_txint(struct uart_dev_s *dev, bool enable) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ie |= UART_C2_TIE; + up_setuartint(priv); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->ie &= ~UART_C2_TIE; + up_setuartint(priv); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: xmc4_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool xmc4_txready(struct uart_dev_s *dev) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + + /* Return true if the transmit data register is "empty." NOTE: If + * FIFOS are enabled, this does not mean that the FIFO is empty, + * rather, it means that the number of bytes in the TX FIFO is + * below the watermark setting. There may actually be space for + * additional TX data. + */ + + return (up_serialin(priv, XMC4_UART_S1_OFFSET) & UART_S1_TDRE) != 0; +} + +/**************************************************************************** + * Name: xmc4_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool xmc4_txempty(struct uart_dev_s *dev) +{ + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)dev->priv; + + /* Return true if the transmit buffer/fifo is "empty." */ + + return (up_serialin(priv, XMC4_UART_SFIFO_OFFSET) & UART_SFIFO_TXEMPT) != 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xmc4_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock iniialization + * performed in up_clkinitialize(). + * + ****************************************************************************/ + +#if defined(USE_EARLYSERIALINIT) +void xmc4_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * pic32mx_consoleinit() + */ + + up_restoreuartint(TTYS0_DEV.priv, 0); +#ifdef TTYS1_DEV + up_restoreuartint(TTYS1_DEV.priv, 0); +#endif +#ifdef TTYS2_DEV + up_restoreuartint(TTYS2_DEV.priv, 0); +#endif +#ifdef TTYS3_DEV + up_restoreuartint(TTYS3_DEV.priv, 0); +#endif +#ifdef TTYS4_DEV + up_restoreuartint(TTYS4_DEV.priv, 0); +#endif +#ifdef TTYS5_DEV + up_restoreuartint(TTYS5_DEV.priv, 0); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_UART_CONSOLE + CONSOLE_DEV.isconsole = true; + xmc4_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + * Input Parameters: + * None + * + * Returns Value: + * None + * + ****************************************************************************/ + +void up_serialinit(void) +{ + char devname[] = "/dev/ttySx"; + + /* Register the console */ + +#ifdef HAVE_UART_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#ifdef TTYS1_DEV + devname[(sizeof(devname)/sizeof(devname[0]))-2] = '0' + first++; + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + devname[(sizeof(devname)/sizeof(devname[0]))-2] = '0' + first++; + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + devname[(sizeof(devname)/sizeof(devname[0]))-2] = '0' + first++; + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +#ifdef TTYS4_DEV + devname[(sizeof(devname)/sizeof(devname[0]))-2] = '0' + first++; + (void)uart_register("/dev/ttyS4", &TTYS4_DEV); +#endif +#ifdef TTYS5_DEV + devname[(sizeof(devname)/sizeof(devname[0]))-2] = '0' + first++; + (void)uart_register("/dev/ttyS5", &TTYS5_DEV); +#endif + return first; +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +#ifdef HAVE_UART_PUTC +int up_putc(int ch) +{ +#ifdef HAVE_UART_CONSOLE + struct xmc4_dev_s *priv = (struct xmc4_dev_s *)CONSOLE_DEV.priv; + uint8_t ie; + + up_disableuartint(priv, &ie); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreuartint(priv, ie); +#endif + return ch; +} +#endif + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +#ifdef HAVE_UART_PUTC +int up_putc(int ch) +{ +#ifdef HAVE_UART_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} +#endif + +#endif /* HAVE_UART_DEVICE && USE_SERIALDRIVER */ + diff --git a/arch/arm/src/xmc4/xmc4_spi.h b/arch/arm/src/xmc4/xmc4_spi.h new file mode 100644 index 0000000000..0ac514c5ce --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_spi.h @@ -0,0 +1,165 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_spi.h + * + * Copyright (C) 2017 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_XMC4_XMC4_SPI_H +#define __ARCH_ARM_SRC_XMC4_XMC4_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip/xmc4_spi.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +struct spi_dev_s; +enum spi_dev_e; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/************************************************************************************ + * Name: xmc4_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameter: + * bus number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *xmc4_spibus_initialize(int bus); + +/************************************************************************************ + * Name: xmc4_spi[n]select, xmc4_spi[n]status, and xmc4_spi[n]cmddata + * + * Description: + * These external functions must be provided by board-specific logic. They are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * including xmc4_spibus_initialize()) are provided by common Kinetis logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in xmc4_board_initialize() to configure SPI chip select + * pins. + * 2. Provide xmc4_spi[n]select() and xmc4_spi[n]status() functions + * in your board-specific logic. These functions will perform chip selection + * and status operations using GPIOs in the way your board is configured. + * 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide + * xmc4_spi[n]cmddata() functions in your board-specific logic. These + * functions will perform cmd/data selection operations using GPIOs in the way + * your board is configured. + * 3. Add a call to xmc4_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by xmc4_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_XMC4_SPI0 +void xmc4_spi0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t xmc4_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int xmc4_spi0cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif +#ifdef CONFIG_XMC4_SPI1 +void xmc4_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t xmc4_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int xmc4_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif +#ifdef CONFIG_XMC4_SPI2 +void xmc4_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t xmc4_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +#ifdef CONFIG_SPI_CMDDATA +int xmc4_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif +#endif + +/**************************************************************************** + * Name: ssp_flush + * + * Description: + * Flush and discard any words left in the RX fifo. This can be called + * from spi[n]select after a device is deselected (if you worry about such + * things). + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#if defined(CONFIG_XMC4_SPI0) || defined(CONFIG_XMC4_SPI1) || defined(CONFIG_XMC4_SPI2) +struct spi_dev_s; +void spi_flush(FAR struct spi_dev_s *dev); +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_XMC4_XMC4_SPI_H */ diff --git a/arch/arm/src/xmc4/xmc4_start.c b/arch/arm/src/xmc4/xmc4_start.c new file mode 100644 index 0000000000..e71722e4be --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_start.c @@ -0,0 +1,355 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_start.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "xmc4_userspace.h" + +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void xmc4_fpu_config(void); +#endif +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + __attribute__ ((naked, no_instrument_function, noreturn)); +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Memory Map ***************************************************************/ +/* + * 0x0000:0000 - Beginning of the internal FLASH. Address of vectors. + * Mapped as boot memory address 0x0000:0000 at reset. + * 0x07ff:ffff - End of flash region (assuming the max of 2MiB of FLASH). + * 0x1fff:0000 - Start of internal SRAM and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap. NOTE that the ARM uses a decrement before + * store stack so that the correct initial value is the end of + * the stack + 4; + * 0x2002:ffff - End of internal SRAM and end of heap (a + */ + +#define IDLE_STACK ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ +#if defined(CONFIG_ARMV7M_CMNVECTOR) +const uintptr_t g_idle_topstack = HEAP_BASE; +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__ ((no_instrument_function)); +#endif + +/**************************************************************************** + * Name: xmc4_fpu_config + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void xmc4_fpu_config(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void xmc4_fpu_config(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define xmc4_fpu_config() +#endif + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : ); +#endif + + /* Disable the watchdog timer */ + + kinetis_wddisable(); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in SRAM is given by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initialization code + * at _framfuncs + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) + { + *dest++ = *src++; + } +#endif + + /* Perform clock and Kinetis module initialization (This depends on + * RAM functions having been copied to RAM). + */ + + xmc4_clock_config(); + + /* Configure the uart and perform early serial initialization so that we + * can get debug output as soon as possible (This depends on clock + * configuration). + */ + + xmc4_fpu_config(); + xmc4_lowsetup(); +#ifdef USE_EARLYSERIALINIT + xmc4_earlyserialinit(); +#endif + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + xmc4_userspace(); +#endif + + /* Initialize other on-board resources */ + + xmc4_board_initialize(); + + /* Then start NuttX */ + + os_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/xmc4/xmc4_timerisr.c b/arch/arm/src/xmc4/xmc4_timerisr.c new file mode 100644 index 0000000000..ba9e98596c --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_timerisr.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_timerisr.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The Clock Source: The System Tick Timer's clock source is always the core + * clock + */ + +#define SYSTICK_RELOAD ((BOARD_CORECLK_FREQ / CLK_TCK) - 1) + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: xmc4_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +static int xmc4_timerisr(int irq, uint32_t *regs, FAR void *arg) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: arm_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void arm_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Note that is should not be neccesary to set the SYSTICK clock source: + * "The CLKSOURCE bit in SysTick Control and Status register is always set + * to select the core clock." + */ + +#if 0 + regval = getreg32(NVIC_SYSTICK_CTRL); + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; + putreg32(regval, NVIC_SYSTICK_CTRL); +#endif + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(XMC4_IRQ_SYSTICK, (xcpt_t)xmc4_timerisr, NULL); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), + NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(XMC4_IRQ_SYSTICK); +} diff --git a/arch/arm/src/xmc4/xmc4_userspace.c b/arch/arm/src/xmc4/xmc4_userspace.c new file mode 100644 index 0000000000..02dc2d2303 --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_userspace.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/src/xmc4/xmc4_userspace.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "xmc4_mpuinit.h" +#include "xmc4_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xmc4_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void xmc4_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + xmc4_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ + diff --git a/arch/arm/src/xmc4/xmc4_userspace.h b/arch/arm/src/xmc4/xmc4_userspace.h new file mode 100644 index 0000000000..661982c8f9 --- /dev/null +++ b/arch/arm/src/xmc4/xmc4_userspace.h @@ -0,0 +1,64 @@ +/************************************************************************************ + * arch/arm/src/xmc4/xmc4_userspace.h + * + * Copyright (C) 2017 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_XMC4_XMC4_USERSPACE_H +#define __ARCH_ARM_SRC_XMC4_XMC4_USERSPACE_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: xmc4_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void xmc4_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_XMC4_XMC4_USERSPACE_H */