From eba004d4988693c920824691d5b8732b424fcade Mon Sep 17 00:00:00 2001 From: Nobuto Kobayashi Date: Mon, 22 Apr 2019 07:51:22 -0600 Subject: [PATCH] arch/arm/src/cxd56xx and arch/arm/include/cxd56xx: Add initial CXD56xx chip sources. --- arch/arm/Kconfig | 16 + arch/arm/include/cxd56xx/chip.h | 104 ++ arch/arm/include/cxd56xx/irq.h | 272 +++++ arch/arm/src/cxd56xx/Kconfig | 32 + arch/arm/src/cxd56xx/Make.defs | 91 ++ arch/arm/src/cxd56xx/chip.h | 69 ++ arch/arm/src/cxd56xx/chip/cxd5602_memorymap.h | 123 +++ arch/arm/src/cxd56xx/chip/cxd56_uart.h | 134 +++ arch/arm/src/cxd56xx/cxd56_allocateheap.c | 139 +++ arch/arm/src/cxd56xx/cxd56_config.h | 138 +++ arch/arm/src/cxd56xx/cxd56_idle.c | 189 ++++ arch/arm/src/cxd56xx/cxd56_irq.c | 558 ++++++++++ arch/arm/src/cxd56xx/cxd56_irq.h | 84 ++ arch/arm/src/cxd56xx/cxd56_serial.c | 997 ++++++++++++++++++ arch/arm/src/cxd56xx/cxd56_serial.h | 66 ++ arch/arm/src/cxd56xx/cxd56_start.c | 362 +++++++ arch/arm/src/cxd56xx/cxd56_timerisr.c | 152 +++ arch/arm/src/cxd56xx/cxd56_timerisr.h | 89 ++ arch/arm/src/cxd56xx/cxd56_uart.c | 328 ++++++ arch/arm/src/cxd56xx/cxd56_uart.h | 142 +++ 20 files changed, 4085 insertions(+) create mode 100644 arch/arm/include/cxd56xx/chip.h create mode 100644 arch/arm/include/cxd56xx/irq.h create mode 100644 arch/arm/src/cxd56xx/Kconfig create mode 100644 arch/arm/src/cxd56xx/Make.defs create mode 100644 arch/arm/src/cxd56xx/chip.h create mode 100644 arch/arm/src/cxd56xx/chip/cxd5602_memorymap.h create mode 100644 arch/arm/src/cxd56xx/chip/cxd56_uart.h create mode 100644 arch/arm/src/cxd56xx/cxd56_allocateheap.c create mode 100644 arch/arm/src/cxd56xx/cxd56_config.h create mode 100644 arch/arm/src/cxd56xx/cxd56_idle.c create mode 100644 arch/arm/src/cxd56xx/cxd56_irq.c create mode 100644 arch/arm/src/cxd56xx/cxd56_irq.h create mode 100644 arch/arm/src/cxd56xx/cxd56_serial.c create mode 100644 arch/arm/src/cxd56xx/cxd56_serial.h create mode 100644 arch/arm/src/cxd56xx/cxd56_start.c create mode 100644 arch/arm/src/cxd56xx/cxd56_timerisr.c create mode 100644 arch/arm/src/cxd56xx/cxd56_timerisr.h create mode 100644 arch/arm/src/cxd56xx/cxd56_uart.c create mode 100644 arch/arm/src/cxd56xx/cxd56_uart.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 32e6bb88710..0793197508d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -402,6 +402,18 @@ config ARCH_CHIP_XMC4 ---help--- Infineon XMC4xxx(ARM Cortex-M4) architectures +config ARCH_CHIP_CXD56XX + bool "Sony CXD56xx" + select ARCH_CORTEXM4 + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_FPU + select ARCH_HAVE_HEAPCHECK + select ARCH_HAVE_MULTICPU + select ARCH_HAVE_SDIO if MMCSD + ---help--- + Sony CXD56XX (ARM Cortex-M4) architectures + endchoice config ARCH_ARM7TDMI @@ -672,6 +684,7 @@ config ARCH_CHIP default "str71x" if ARCH_CHIP_STR71X default "tms570" if ARCH_CHIP_TMS570 default "xmc4" if ARCH_CHIP_XMC4 + default "cxd56xx" if ARCH_CHIP_CXD56XX config ARCH_HAVE_TRUSTZONE bool @@ -917,5 +930,8 @@ endif if ARCH_CHIP_XMC4 source arch/arm/src/xmc4/Kconfig endif +if ARCH_CHIP_CXD56XX +source arch/arm/src/cxd56xx/Kconfig +endif endif # ARCH_ARM diff --git a/arch/arm/include/cxd56xx/chip.h b/arch/arm/include/cxd56xx/chip.h new file mode 100644 index 00000000000..9a790817d2f --- /dev/null +++ b/arch/arm/include/cxd56xx/chip.h @@ -0,0 +1,104 @@ +/***************************************************************************** + * arch/arm/include/cxd56xx/chip.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012-2013 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_INCLUDE_CXD56XX_CHIP_H +#define __ARCH_ARM_INCLUDE_CXD56XX_CHIP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CXD56M4_SYSH_PRIORITY_MIN 0xe0 /* All bits[7:5] set is minimum priority */ +#define CXD56M4_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define CXD56M4_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define CXD56M4_SYSH_PRIORITY_STEP 0x20 /* Steps between priorities */ + +#define NVIC_SYSH_PRIORITY_MIN CXD56M4_SYSH_PRIORITY_MIN +#define NVIC_SYSH_PRIORITY_DEFAULT CXD56M4_SYSH_PRIORITY_DEFAULT +#define NVIC_SYSH_PRIORITY_MAX CXD56M4_SYSH_PRIORITY_MAX +#define NVIC_SYSH_PRIORITY_STEP CXD56M4_SYSH_PRIORITY_STEP + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the up_irq_save() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +#endif /* __ARCH_ARM_INCLUDE_CXD56XX_CHIP_H */ diff --git a/arch/arm/include/cxd56xx/irq.h b/arch/arm/include/cxd56xx/irq.h new file mode 100644 index 00000000000..7b20667d800 --- /dev/null +++ b/arch/arm/include/cxd56xx/irq.h @@ -0,0 +1,272 @@ +/**************************************************************************** + * arch/arm/include/cxd56xx/irq.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_CXD56XX_IRQ_H +#define __ARCH_ARM_INCLUDE_CXD56XX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define CXD56_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define CXD56_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define CXD56_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define CXD56_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define CXD56_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define CXD56_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ +#define CXD56_IRQ_SIGNVALUE (7) /* Vector 7: Sign value */ +#define CXD56_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define CXD56_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define CXD56_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define CXD56_IRQ_SYSTICK (15) /* Vector 15: System tick */ +#define CXD56_IRQ_EXTINT (16) /* Vector 16: Vector number of the first external interrupt */ + +/* Cortex-M4 External interrupts (vectors >= 16) */ + +#define CXD56_IRQ_PMU (CXD56_IRQ_EXTINT+0) /**< PMU IRQ number */ +#define CXD56_IRQ_CRG (CXD56_IRQ_EXTINT+1) /**< CRG IRQ number */ +#define CXD56_IRQ_HVDD (CXD56_IRQ_EXTINT+2) /**< HVDD IRQ number */ +#define CXD56_IRQ_LP (CXD56_IRQ_EXTINT+3) /**< LP IRQ number */ +#define CXD56_IRQ_RTC0_A0 (CXD56_IRQ_EXTINT+4) /**< RTC0_A0 IRQ number */ +#define CXD56_IRQ_RTC0_A1 (CXD56_IRQ_EXTINT+5) /**< RTC0_A1 IRQ number */ +#define CXD56_IRQ_RTC0_A2 (CXD56_IRQ_EXTINT+6) /**< RTC0_A2 IRQ number */ +#define CXD56_IRQ_RTC1_A0 (CXD56_IRQ_EXTINT+7) /**< RTC1_A0 IRQ number */ +#define CXD56_IRQ_RTC1_A1 (CXD56_IRQ_EXTINT+8) /**< RTC1_A1 IRQ number */ +#define CXD56_IRQ_RTC1_A2 (CXD56_IRQ_EXTINT+9) /**< RTC1_A2 IRQ number */ +#define CXD56_IRQ_RTC_INT (CXD56_IRQ_EXTINT+10) /**< RTC_INT IRQ number */ +#define CXD56_IRQ_UART1 (CXD56_IRQ_EXTINT+11) /**< UART1 IRQ number */ +#define CXD56_IRQ_UART0 (CXD56_IRQ_EXTINT+12) /**< UART0 IRQ number */ +#define CXD56_IRQ_HOSTIF_0 (CXD56_IRQ_EXTINT+13) /**< HOSTIF_0 IRQ number */ +#define CXD56_IRQ_HOSTIF_1 (CXD56_IRQ_EXTINT+14) /**< HOSTIF_1 IRQ number */ +#define CXD56_IRQ_HOSTIF_2 (CXD56_IRQ_EXTINT+15) /**< HOSTIF_2 IRQ number */ +#define CXD56_IRQ_SCU_SPI (CXD56_IRQ_EXTINT+16) /**< SCU_0 SPI IRQ number */ +#define CXD56_IRQ_SCU_I2C0 (CXD56_IRQ_EXTINT+17) /**< SCU_1 I2C1 IRQ number */ +#define CXD56_IRQ_SCU_I2C1 (CXD56_IRQ_EXTINT+18) /**< SCU_2 I2C2 IRQ number */ +#define CXD56_IRQ_SCU_3 (CXD56_IRQ_EXTINT+19) /**< SCU_3 SCU IRQ number */ +#define CXD56_IRQ_EXDEVICE_0 (CXD56_IRQ_EXTINT+20) /**< EXDEVICE_0 IRQ number */ +#define CXD56_IRQ_EXDEVICE_1 (CXD56_IRQ_EXTINT+21) /**< EXDEVICE_1 IRQ number */ +#define CXD56_IRQ_EXDEVICE_2 (CXD56_IRQ_EXTINT+22) /**< EXDEVICE_2 IRQ number */ +#define CXD56_IRQ_EXDEVICE_3 (CXD56_IRQ_EXTINT+23) /**< EXDEVICE_3 IRQ number */ +#define CXD56_IRQ_EXDEVICE_4 (CXD56_IRQ_EXTINT+24) /**< EXDEVICE_4 IRQ number */ +#define CXD56_IRQ_EXDEVICE_5 (CXD56_IRQ_EXTINT+25) /**< EXDEVICE_5 IRQ number */ +#define CXD56_IRQ_EXDEVICE_6 (CXD56_IRQ_EXTINT+26) /**< EXDEVICE_6 IRQ number */ +#define CXD56_IRQ_EXDEVICE_7 (CXD56_IRQ_EXTINT+27) /**< EXDEVICE_7 IRQ number */ +#define CXD56_IRQ_EXDEVICE_8 (CXD56_IRQ_EXTINT+28) /**< EXDEVICE_8 IRQ number */ +#define CXD56_IRQ_EXDEVICE_9 (CXD56_IRQ_EXTINT+29) /**< EXDEVICE_9 IRQ number */ +#define CXD56_IRQ_EXDEVICE_10 (CXD56_IRQ_EXTINT+30) /**< EXDEVICE_10 IRQ number */ +#define CXD56_IRQ_EXDEVICE_11 (CXD56_IRQ_EXTINT+31) /**< EXDEVICE_11 IRQ number */ +#define CXD56_IRQ_DMA_A_0 (CXD56_IRQ_EXTINT+32) /**< DMA_A_0 IRQ number */ +#define CXD56_IRQ_DMA_A_1 (CXD56_IRQ_EXTINT+33) /**< DMA_A_1 IRQ number */ +#define CXD56_IRQ_DMA_A_2 (CXD56_IRQ_EXTINT+34) /**< DMA_A_2 IRQ number */ +#define CXD56_IRQ_DMA_A_3 (CXD56_IRQ_EXTINT+35) /**< DMA_A_3 IRQ number */ +#define CXD56_IRQ_DMA_A_4 (CXD56_IRQ_EXTINT+36) /**< DMA_A_4 IRQ number */ +#define CXD56_IRQ_DMA_A_5 (CXD56_IRQ_EXTINT+37) /**< DMA_A_5 IRQ number */ +#define CXD56_IRQ_DMA_A_6 (CXD56_IRQ_EXTINT+38) /**< DMA_A_6 IRQ number */ +#define CXD56_IRQ_DMA_A_7 (CXD56_IRQ_EXTINT+39) /**< DMA_A_7 IRQ number */ +#define CXD56_IRQ_DMA_A_8 (CXD56_IRQ_EXTINT+40) /**< DMA_A_8 IRQ number */ +#define CXD56_IRQ_DMA_A_9 (CXD56_IRQ_EXTINT+41) /**< DMA_A_9 IRQ number */ +#define CXD56_IRQ_DMA_A_10 (CXD56_IRQ_EXTINT+42) /**< DMA_A_10 IRQ number */ +#define CXD56_IRQ_DMA_A_11 (CXD56_IRQ_EXTINT+43) /**< DMA_A_11 IRQ number */ +#define CXD56_IRQ_DMA_A_12 (CXD56_IRQ_EXTINT+44) /**< DMA_A_12 IRQ number */ +#define CXD56_IRQ_DMA_A_13 (CXD56_IRQ_EXTINT+45) /**< DMA_A_13 IRQ number */ +#define CXD56_IRQ_DMA_A_14 (CXD56_IRQ_EXTINT+46) /**< DMA_A_14 IRQ number */ +#define CXD56_IRQ_DMA_A_15 (CXD56_IRQ_EXTINT+47) /**< DMA_A_15 IRQ number */ +#define CXD56_IRQ_DMA_A_16 (CXD56_IRQ_EXTINT+48) /**< DMA_A_16 IRQ number */ +#define CXD56_IRQ_DMA_A_17 (CXD56_IRQ_EXTINT+49) /**< DMA_A_17 IRQ number */ +#define CXD56_IRQ_DMA_A_18 (CXD56_IRQ_EXTINT+50) /**< DMA_A_18 IRQ number */ +#define CXD56_IRQ_DMA_A_19 (CXD56_IRQ_EXTINT+51) /**< DMA_A_19 IRQ number */ +#define CXD56_IRQ_DMA_A_20 (CXD56_IRQ_EXTINT+52) /**< DMA_A_20 IRQ number */ +#define CXD56_IRQ_DMA_A_21 (CXD56_IRQ_EXTINT+53) /**< DMA_A_21 IRQ number */ +#define CXD56_IRQ_DMA_A_22 (CXD56_IRQ_EXTINT+54) /**< DMA_A_22 IRQ number */ +#define CXD56_IRQ_DMA_A_23 (CXD56_IRQ_EXTINT+55) /**< DMA_A_23 IRQ number */ +#define CXD56_IRQ_DMA_A_24 (CXD56_IRQ_EXTINT+56) /**< DMA_A_24 IRQ number */ +#define CXD56_IRQ_DMA_A_25 (CXD56_IRQ_EXTINT+57) /**< DMA_A_25 IRQ number */ +#define CXD56_IRQ_DMA_A_26 (CXD56_IRQ_EXTINT+58) /**< DMA_A_26 IRQ number */ +#define CXD56_IRQ_DMA_A_27 (CXD56_IRQ_EXTINT+59) /**< DMA_A_27 IRQ number */ +#define CXD56_IRQ_DMA_A_28 (CXD56_IRQ_EXTINT+60) /**< DMA_A_28 IRQ number */ +#define CXD56_IRQ_DMA_A_29 (CXD56_IRQ_EXTINT+61) /**< DMA_A_29 IRQ number */ +#define CXD56_IRQ_DMA_A_30 (CXD56_IRQ_EXTINT+62) /**< DMA_A_30 IRQ number */ +#define CXD56_IRQ_DMA_A_31 (CXD56_IRQ_EXTINT+63) /**< DMA_A_31 IRQ number */ +#define CXD56_IRQ_DMA_B_0 (CXD56_IRQ_EXTINT+64) /**< DMA_B_0 IRQ number */ +#define CXD56_IRQ_DMA_B_1 (CXD56_IRQ_EXTINT+65) /**< DMA_B_1 IRQ number */ +#define CXD56_IRQ_DMA_C_0 (CXD56_IRQ_EXTINT+66) /**< DMA_C_0 IRQ number */ +#define CXD56_IRQ_DMA_C_1 (CXD56_IRQ_EXTINT+67) /**< DMA_C_1 IRQ number */ +#define CXD56_IRQ_DMA_D_0 (CXD56_IRQ_EXTINT+68) /**< DMA_D_0 IRQ number */ +#define CXD56_IRQ_DMA_D_1 (CXD56_IRQ_EXTINT+69) /**< DMA_D_1 IRQ number */ +#define CXD56_IRQ_SAKE_NSEC (CXD56_IRQ_EXTINT+70) /**< SAKE_NSEC IRQ number */ +#define CXD56_IRQ_SAKE_SEC (CXD56_IRQ_EXTINT+71) /**< SAKE_SEC IRQ number */ +#define CXD56_IRQ_USB_VBUS (CXD56_IRQ_EXTINT+72) /**< USB_VBUS IRQ number */ +#define CXD56_IRQ_USB_VBUSN (CXD56_IRQ_EXTINT+73) /**< USB_VBUSN IRQ number */ +#define CXD56_IRQ_SPIM (CXD56_IRQ_EXTINT+74) /**< SPI0 IRQ number */ +#define CXD56_IRQ_I2CM (CXD56_IRQ_EXTINT+75) /**< I2C0 IRQ number */ +#define CXD56_IRQ_DEBUG0 (CXD56_IRQ_EXTINT+76) /**< DEBUG0 IRQ number */ +#define CXD56_IRQ_DEBUG1 (CXD56_IRQ_EXTINT+77) /**< DEBUG1 IRQ number */ +#define CXD56_IRQ_FIFO_TO (CXD56_IRQ_EXTINT+78) /**< FIFO_TO IRQ number */ +#define CXD56_IRQ_FIFO_FROM (CXD56_IRQ_EXTINT+79) /**< FIFO_FROM IRQ number */ +#define CXD56_IRQ_SPH0 (CXD56_IRQ_EXTINT+80) /**< SPH0 IRQ number */ +#define CXD56_IRQ_SPH1 (CXD56_IRQ_EXTINT+81) /**< SPH1 IRQ number */ +#define CXD56_IRQ_SPH2 (CXD56_IRQ_EXTINT+82) /**< SPH2 IRQ number */ +#define CXD56_IRQ_SPH3 (CXD56_IRQ_EXTINT+83) /**< SPH3 IRQ number */ +#define CXD56_IRQ_SPH4 (CXD56_IRQ_EXTINT+84) /**< SPH4 IRQ number */ +#define CXD56_IRQ_SPH5 (CXD56_IRQ_EXTINT+85) /**< SPH5 IRQ number */ +#define CXD56_IRQ_SPH6 (CXD56_IRQ_EXTINT+86) /**< SPH6 IRQ number */ +#define CXD56_IRQ_SPH7 (CXD56_IRQ_EXTINT+87) /**< SPH7 IRQ number */ +#define CXD56_IRQ_SPH8 (CXD56_IRQ_EXTINT+88) /**< SPH8 IRQ number */ +#define CXD56_IRQ_SPH9 (CXD56_IRQ_EXTINT+89) /**< SPH9 IRQ number */ +#define CXD56_IRQ_SPH10 (CXD56_IRQ_EXTINT+90) /**< SPH10 IRQ number */ +#define CXD56_IRQ_SPH11 (CXD56_IRQ_EXTINT+91) /**< SPH11 IRQ number */ +#define CXD56_IRQ_SPH12 (CXD56_IRQ_EXTINT+92) /**< SPH12 IRQ number */ +#define CXD56_IRQ_SPH13 (CXD56_IRQ_EXTINT+93) /**< SPH13 IRQ number */ +#define CXD56_IRQ_SPH14 (CXD56_IRQ_EXTINT+94) /**< SPH14 IRQ number */ +#define CXD56_IRQ_SPH15 (CXD56_IRQ_EXTINT+95) /**< SPH15 IRQ number */ +#define CXD56_IRQ_SW_INT (CXD56_IRQ_EXTINT+96) /**< SW_INT IRQ number */ +#define CXD56_IRQ_TIMER0 (CXD56_IRQ_EXTINT+97) /**< TIMER0 IRQ number */ +#define CXD56_IRQ_TIMER1 (CXD56_IRQ_EXTINT+98) /**< TIMER1 IRQ number */ +#define CXD56_IRQ_TIMER2 (CXD56_IRQ_EXTINT+99) /**< TIMER2 IRQ number */ +#define CXD56_IRQ_WDT_INT (CXD56_IRQ_EXTINT+100) /**< WDT_INT IRQ number */ +#define CXD56_IRQ_WDT_RES (CXD56_IRQ_EXTINT+101) /**< WDT_RES IRQ number */ +#define CXD56_IRQ_AUDIO_0 (CXD56_IRQ_EXTINT+102) /**< AUDIO_0(MIC) IRQ number */ +#define CXD56_IRQ_AUDIO_1 (CXD56_IRQ_EXTINT+103) /**< AUDIO_1(I2S1) IRQ number */ +#define CXD56_IRQ_AUDIO_2 (CXD56_IRQ_EXTINT+104) /**< AUDIO_2(I2S2) IRQ number */ +#define CXD56_IRQ_AUDIO_3 (CXD56_IRQ_EXTINT+105) /**< AUDIO_3(CODEC) IRQ number */ +#define CXD56_IRQ_GE2D (CXD56_IRQ_EXTINT+106) /**< APP_IMG 2D Graphics Engine IRQ number */ +#define CXD56_IRQ_ROT (CXD56_IRQ_EXTINT+107) /**< APP_IMG_ROTation IRQ number */ +#define CXD56_IRQ_CISIF (CXD56_IRQ_EXTINT+108) /**< APP_IMG CISIF IRQ number */ +#define CXD56_IRQ_IMG_WSPI (CXD56_IRQ_EXTINT+109) /**< APP_IMG WSSP IRQ number */ +#define CXD56_IRQ_IDMAC (CXD56_IRQ_EXTINT+110) /**< APP_IMG DMAC IRQ number */ +#define CXD56_IRQ_APP_UART (CXD56_IRQ_EXTINT+111) /**< APP_IMG UART IRQ number */ +#define CXD56_IRQ_VSYNC (CXD56_IRQ_EXTINT+112) /**< APP_IMG VSYNC IRQ number */ +#define CXD56_IRQ_IMG_SPI (CXD56_IRQ_EXTINT+113) /**< APP_IMG SSP IRQ number */ +#define CXD56_IRQ_EMMC (CXD56_IRQ_EXTINT+114) /**< APP_PER EMMC IRQ number */ +#define CXD56_IRQ_SDIO (CXD56_IRQ_EXTINT+115) /**< APP_PER SDIO IRQ number */ +#define CXD56_IRQ_USB_INT (CXD56_IRQ_EXTINT+116) /**< APP_PER USB_INT IRQ number */ +#define CXD56_IRQ_USB_SYS (CXD56_IRQ_EXTINT+117) /**< APP_PER USB_SYS IRQ number */ +#define CXD56_IRQ_APP_DMAC0 (CXD56_IRQ_EXTINT+118) /**< APP_DMAC0 IRQ number */ +#define CXD56_IRQ_APP_DMAC1 (CXD56_IRQ_EXTINT+119) /**< APP_DMAC1 IRQ number */ +#define CXD56_IRQ_APP_SAKE_NSEC (CXD56_IRQ_EXTINT+120) /**< APP_SAKE_NSEC IRQ number */ +#define CXD56_IRQ_APP_SAKE_SEC (CXD56_IRQ_EXTINT+121) /**< APP_SAKE_SEC IRQ number */ +#define CXD56_IRQ_SKDMAC_0 (CXD56_IRQ_EXTINT+122) /**< APP_SAKE_DMAC_0 IRQ number */ +#define CXD56_IRQ_SKDMAC_1 (CXD56_IRQ_EXTINT+123) /**< APP_SAKE_DMAC_1 IRQ number */ +#define CXD56_IRQ_APP_PPB (CXD56_IRQ_EXTINT+124) /**< reserved */ +#define CXD56_IRQ_GPS_OR (CXD56_IRQ_EXTINT+125) /**< GNSS_OR IRQ number */ +#define CXD56_IRQ_SFC (CXD56_IRQ_EXTINT+126) /**< SFC IRQ number */ +#define CXD56_IRQ_PMIC (CXD56_IRQ_EXTINT+127) /**< PMIC IRQ number */ + +#define CXD56_IRQ_NEXTINT (128) +#define CXD56_IRQ_NIRQS (CXD56_IRQ_EXTINT+CXD56_IRQ_NEXTINT) + +/* Total number of IRQ numbers (This will need to be revisited if/when the + * Cortex-M0 is supported) + */ + +#define NR_VECTORS CXD56_IRQ_NIRQS +#define NR_IRQS CXD56_IRQ_NIRQS + +/* Cortex-M0 External interrupts (vectors >= 16) */ + +#if 0 +# define CXD56M0_IRQ_NIRQS (CXD56_IRQ_EXTINT + CXD56M0_IRQ_NEXTINT) +#endif + +/* Total number of IRQ numbers (This will need to be revisited if/when the + * Cortex-M0 is supported) + */ + +#if 0 +# define NR_VECTORS CXD56M0_IRQ_NIRQS +# define NR_IRQS CXD56M0_IRQ_NIRQS +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*vic_vector_t)(uint32_t *regs); +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_CXD56XX_IRQ_H */ + diff --git a/arch/arm/src/cxd56xx/Kconfig b/arch/arm/src/cxd56xx/Kconfig new file mode 100644 index 00000000000..4d7a99a8666 --- /dev/null +++ b/arch/arm/src/cxd56xx/Kconfig @@ -0,0 +1,32 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "CXD56xx Configuration Options" + +config CXD56_ARCH_OPTS + bool + default y + select ARCH_DMA + select SDIO_DMA if MMCSD + +menu "CXD56xx Peripheral Support" + +config CXD56_UART1 + bool "UART1" + default y + select UART1_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + ---help--- + UART interface in the communication subsystem. This doesn't have any + hardware flow control, and is mainly used for debug console. + +config CXD56_UART2 + bool "UART2" + default n + select UART2_SERIALDRIVER + ---help--- + UART interface with hardware flow control in the application subsystem. + +endmenu diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs new file mode 100644 index 00000000000..910a23842b0 --- /dev/null +++ b/arch/arm/src/cxd56xx/Make.defs @@ -0,0 +1,91 @@ +############################################################################ +# arch/arm/src/cxd56xx/Make.defs +# +# Copyright 2018 Sony Semiconductor Solutions Corporation +# +# Copyright (C) 2012-2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +HEAD_ASRC = + +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 +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c +CMN_CSRCS += up_svcall.c up_vfork.c + +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +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 + +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 + +CHIP_CSRCS = cxd56_allocateheap.c cxd56_idle.c +CHIP_CSRCS += cxd56_serial.c cxd56_uart.c cxd56_irq.c +CHIP_CSRCS += cxd56_start.c +CHIP_CSRCS += cxd56_timerisr.c diff --git a/arch/arm/src/cxd56xx/chip.h b/arch/arm/src/cxd56xx/chip.h new file mode 100644 index 00000000000..622319818ee --- /dev/null +++ b/arch/arm/src/cxd56xx/chip.h @@ -0,0 +1,69 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/chip.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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 of Sony Semiconductor Solutions Corporation 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_CXD56XX_CHIP_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Include the chip capabilities file */ + +#include + +#define ARMV7M_PERIPHERAL_INTERRUPTS 128 + +#include "chip/cxd5602_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_H */ diff --git a/arch/arm/src/cxd56xx/chip/cxd5602_memorymap.h b/arch/arm/src/cxd56xx/chip/cxd5602_memorymap.h new file mode 100644 index 00000000000..e2d2f3b56da --- /dev/null +++ b/arch/arm/src/cxd56xx/chip/cxd5602_memorymap.h @@ -0,0 +1,123 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/chip/cxd5602_memorymap.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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 of Sony Semiconductor Solutions Corporation 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_CXD56XX_CHIP_CXD5602_MEMORYMAP_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_CXD5602_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CXD56_ADSP_BASE 0x4c000000 +#define CXD56_SYS_MIRROR 0x04000000 + +#define CXD56_SYS_RAM_BASE 0x05000000 +#define CXD56_GDSP_RAM_BASE 0x09000000 +#define CXD56_ADSP_RAM_BASE 0x0d000000 +#define CXD56_RAM_BASE 0x0d000000 +#define CXD56_RAM_SIZE 0x00180000 +#define CXD56_ARM_BASE 0xe0000000 +#define CXD56_TIMER_BASE 0xe0043000 +#define CXD56_WDOG_BASE 0xe0044000 +#define CXD56_INTC_BASE 0xe0045000 + +#define CXD56_SWINT_BASE 0x4600c000 +#define CXD56_CPUFIFO_BASE 0x4600c400 +#define CXD56_SPH_BASE 0x4600c800 + +/* Peripheral and system configuration */ + +#define CXD56_ROM_BASE (CXD56_SYS_MIRROR + 0x00000000) +#define CXD56_TOPREG_BASE (CXD56_SYS_MIRROR + 0x00100000) +#define CXD56_TOPREG_SUB_BASE (CXD56_SYS_MIRROR + 0x00103000) +#define CXD56_PMU_SUB_BASE (CXD56_SYS_MIRROR + 0x00106000) +#define CXD56_FREQDISC_BASE (CXD56_SYS_MIRROR + 0x00107000) +#define CXD56_RTC0_BASE (CXD56_SYS_MIRROR + 0x00108000) +#define CXD56_RTC1_BASE (CXD56_SYS_MIRROR + 0x00109000) +#define CXD56_TDC_BASE (CXD56_SYS_MIRROR + 0x0010B000) + +/* reserved 0x0010c000 - 0x00110fff */ + +#define CXD56_SPIFLASH_BASE (CXD56_SYS_MIRROR + 0x00110000) + +/* reserved 0x00111000 - 0x0011ffff */ + +#define CXD56_DMAC0_BASE (CXD56_SYS_MIRROR + 0x00120000) /* SDMAC */ +#define CXD56_DMAC1_BASE (CXD56_SYS_MIRROR + 0x00121000) /* HDMAC */ +#define CXD56_DMAC2_BASE (CXD56_SYS_MIRROR + 0x00122000) /* SYDMAC */ +#define CXD56_DMAC3_BASE (CXD56_SYS_MIRROR + 0x00123000) /* SYSUB */ + +/* reserved 0x00124000 - 0x0017ffff */ + +#define CXD56_SCU_FIFO_REG_BASE (CXD56_SYS_MIRROR + 0x00180000) +#define CXD56_SCU_FIFO_4K_BASE (CXD56_SYS_MIRROR + 0x00182000) +#define CXD56_SCU_FIFO_8K_BASE (CXD56_SYS_MIRROR + 0x00183000) +#define CXD56_SCU_FIFO_32K_BASE (CXD56_SYS_MIRROR + 0x00185000) +#define CXD56_SCU_SPI_BASE (CXD56_SYS_MIRROR + 0x0018d000) +#define CXD56_SCU_I2C0_BASE (CXD56_SYS_MIRROR + 0x0018d400) +#define CXD56_SCU_I2C1_BASE (CXD56_SYS_MIRROR + 0x0018d800) +#define CXD56_SCU_ADCIF_BASE (CXD56_SYS_MIRROR + 0x0018dc00) +#define CXD56_SCU_SEQ_IRAM_BASE (CXD56_SYS_MIRROR + 0x00190000) +#define CXD56_SCU_SEQ_IRAM_MIRROR (CXD56_SYS_MIRROR + 0x00192000) +#define CXD56_SCU_SEQ_DRAM_BASE (CXD56_SYS_MIRROR + 0x00194000) +#define CXD56_SCU_SEQ_DRAM_MIRROR (CXD56_SYS_MIRROR + 0x00194800) +#define CXD56_SCU_BASE (CXD56_SYS_MIRROR + 0x00195000) +#define CXD56_UART0_BASE (CXD56_SYS_MIRROR + 0x001a9000) + +#define CXD56_I2CM_BASE (CXD56_SYS_MIRROR + 0x001aa000) +#define CXD56_SPIM_BASE (CXD56_SYS_MIRROR + 0x001ab000) +#define CXD56_UART1_BASE (CXD56_SYS_MIRROR + 0x001ac000) + +#define CXD56_CPU_BASE (CXD56_ADSP_BASE + 0x02002000) +#define CXD56_CRG_BASE (CXD56_ADSP_BASE + 0x02011000) +#define CXD56_ADR_CONV_BASE (CXD56_ADSP_BASE + 0x02012000) +#define CXD56_EXCCONF_BASE (CXD56_ADSP_BASE + 0x02013000) +#define CXD56_CISIF_BASE (CXD56_ADSP_BASE + 0x02100000) +#define CXD56_GE2D_BASE (CXD56_ADSP_BASE + 0x02101000) +#define CXD56_ROT_BASE (CXD56_ADSP_BASE + 0x02101400) +#define CXD56_UART2_BASE (CXD56_ADSP_BASE + 0x02103000) +#define CXD56_IMG_SPI_BASE (CXD56_ADSP_BASE + 0x02103400) /* IMG_SSP (Display) */ +#define CXD56_IMG_WSPI_BASE (CXD56_ADSP_BASE + 0x02103c00) /* IMG_SSP (WiFi) */ +#define CXD56_USBDEV_BASE (CXD56_ADSP_BASE + 0x02200000) +#define CXD56_EMMC_BASE (CXD56_ADSP_BASE + 0x02201000) +#define CXD56_SDIO_BASE (CXD56_ADSP_BASE + 0x02202000) + +#endif diff --git a/arch/arm/src/cxd56xx/chip/cxd56_uart.h b/arch/arm/src/cxd56xx/chip/cxd56_uart.h new file mode 100644 index 00000000000..907a77bff43 --- /dev/null +++ b/arch/arm/src/cxd56xx/chip/cxd56_uart.h @@ -0,0 +1,134 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/chip/cxd56_uart.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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 of Sony Semiconductor Solutions Corporation 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_CXD56XX_CHIP_CXD56_UART_H +#define __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +/* Common Register Offsets */ + +#define CXD56_UART_DR 0x000 /* Data register */ +#define CXD56_UART_RSR_ECR 0x004 /* Recieve status/error clear register */ +#define CXD56_UART_FR 0x018 /* Flag register */ +#define CXD56_UART_ILPR 0x020 /* IrDA low-power counter register */ +#define CXD56_UART_IBRD 0x024 /* Integer baud rate register */ +#define CXD56_UART_FBRD 0x028 /* Fractional baud rate register */ +#define CXD56_UART_LCR_H 0x02c /* Line control register */ +#define CXD56_UART_CR 0x030 /* Control register */ +#define CXD56_UART_IFLS 0x034 /* Interrupt FIFO level select register */ +#define CXD56_UART_IMSC 0x038 /* Interrupt mask set/clear register */ +#define CXD56_UART_RIS 0x03c /* Raw Interrupt status register */ +#define CXD56_UART_MIS 0x040 /* Masked interrupt status register */ +#define CXD56_UART_ICR 0x044 /* Interrupt clear register */ +#define CXD56_UART_DMACR 0x048 /* DMA control register */ + +#define UART_FR_RI (0x1 << 8) +#define UART_FR_TXFE (0x1 << 7) +#define UART_FR_RXFF (0x1 << 6) +#define UART_FR_TXFF (0x1 << 5) +#define UART_FR_RXFE (0x1 << 4) +#define UART_FR_BUSY (0x1 << 3) +#define UART_FR_DCD (0x1 << 2) +#define UART_FR_DSR (0x1 << 1) +#define UART_FR_CTS (0x1 << 0) + +#define UART_LCR_SPS (1u << 7) +#define UART_LCR_WLEN(x) ((((x)-5)&3)<<5) +#define UART_LCR_FEN (1u << 4) +#define UART_LCR_STP2 (1u << 3) +#define UART_LCR_EPS (1u << 2) +#define UART_LCR_PEN (1u << 1) +#define UART_LCR_BRK (1u << 0) + +#define UART_CR_CTSEN (1u << 15) +#define UART_CR_RTSEN (1u << 14) +#define UART_CR_OUT2 (1u << 13) +#define UART_CR_OUT1 (1u << 12) +#define UART_CR_RTS (1u << 11) +#define UART_CR_DTR (1u << 10) +#define UART_CR_RXE (1u << 9) +#define UART_CR_TXE (1u << 8) +#define UART_CR_LBE (1u << 7) +#define UART_CR_SIRLP (1u << 2) +#define UART_CR_SIREN (1u << 1) +#define UART_CR_EN (1u << 0) + +#define UART_INTR_RI (1u << 0) /* nUARTRI modem interrupt */ +#define UART_INTR_CTS (1u << 1) /* nUARTCTS modem interrupt */ +#define UART_INTR_DCD (1u << 2) /* nUARTDCD modem interrupt */ +#define UART_INTR_DSR (1u << 3) /* nUARTDSR modem interrupt */ +#define UART_INTR_RX (1u << 4) /* Receive interrupt */ +#define UART_INTR_TX (1u << 5) /* Transmit interrupt */ +#define UART_INTR_RT (1u << 6) /* Receive timeout interrupt */ +#define UART_INTR_FE (1u << 7) /* Framing error interrupt */ +#define UART_INTR_PE (1u << 8) /* Parity error interrupt */ +#define UART_INTR_BE (1u << 9) /* Break error interrupt */ +#define UART_INTR_OE (1u << 10) /* Overrun error interrupt */ +#define UART_INTR_ALL (0x7ff) /* All of interrupts */ + +#define UART_FLAG_RI (1u << 8) /* Ring indicator */ +#define UART_FLAG_TXFE (1u << 7) /* Transmit FIFO empty */ +#define UART_FLAG_RXFF (1u << 6) /* Receive FIFO full */ +#define UART_FLAG_TXFF (1u << 5) /* Transmit FIFO full */ +#define UART_FLAG_RXFE (1u << 4) /* Receive FIFO empty */ +#define UART_FLAG_BUSY (1u << 3) /* UART busy */ +#define UART_FLAG_DCD (1u << 2) /* Data carrier detect */ +#define UART_FLAG_DSR (1u << 1) /* Data set ready */ +#define UART_FLAG_CTS (1u << 0) /* Cleart to send */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_CXD56_UART_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_allocateheap.c b/arch/arm/src/cxd56xx/cxd56_allocateheap.c new file mode 100644 index 00000000000..606e2139bc7 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_allocateheap.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_allocateheap.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012-2013, 2015-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 "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* _sbss is the start of the BSS region (see the linker script) _ebss is the + * end of the BSS regsion (see the linker script). 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 configured end of memory. + * g_idle_topstack is the beginning of this heap region (not necessarily + * aligned). + */ + +const uint32_t g_idle_topstack = (uint32_t)&_ebss + + CONFIG_IDLETHREAD_STACKSIZE; + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/* Sanity check */ + +#if (CONFIG_RAM_START < CXD56_RAM_BASE) || \ + (CONFIG_RAM_START + CONFIG_RAM_SIZE > CXD56_RAM_BASE + CXD56_RAM_SIZE) +# error Invalid memory configuration +#endif + +#define MM_RAM_END CONFIG_RAM_END + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_heap_color + * + * Description: + * Set heap memory to a known, non-zero state to checking heap usage. + * + ****************************************************************************/ + +#ifdef CONFIG_HEAP_COLORATION +static inline void up_heap_color(FAR void *start, size_t size) +{ + memset(start, HEAP_COLOR, size); +} +#else +# define up_heap_color(start,size) +#endif + +/**************************************************************************** + * 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(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + /* Start with the first SRAM region */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = MM_RAM_END - g_idle_topstack; + + /* Colorize the heap for debug */ + + up_heap_color(*heap_start, *heap_size); +} diff --git a/arch/arm/src/cxd56xx/cxd56_config.h b/arch/arm/src/cxd56xx/cxd56_config.h new file mode 100644 index 00000000000..1a47f401cbb --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_config.h @@ -0,0 +1,138 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_config.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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 of Sony Semiconductor Solutions Corporation 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_CXD56XX_CXD56XX_CONFIG_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56XX_CONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Required configuration settings */ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_CXD56_UART0) || defined(CONFIG_CXD56_UART1) || \ + defined(CONFIG_CXD56_UART2) +# define HAVE_UART 1 +#endif + +/* Make sure all features are disabled for diabled U[S]ARTs. This simplifies + * checking later. + */ + +#ifndef CONFIG_CXD56_UART0 +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART0_RS485MODE +# undef CONFIG_UART0_RS485_DTRDIR +#endif + +#ifndef CONFIG_CXD56_UART1 +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART1_RS485MODE +# undef CONFIG_UART1_RS485_DTRDIR +#endif + +#ifndef CONFIG_CXD56_UART2 +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART2_RS485MODE +# undef CONFIG_UART2_RS485_DTRDIR +#endif + +/* Is there a serial console? There should be at most one defined. It could + * be on any UARTn, n=0,1,2,3 - OR - there might not be any serial console at + * all. + */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_UART0_SERIAL_CONSOLE +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef CONFIG_UART3_SERIAL_CONSOLE +# undef HAVE_CONSOLE +#endif + +/* Check UART flow control (Only supported by UART1) */ + +# undef CONFIG_UART0_FLOWCONTROL +# undef CONFIG_UART2_FLOWCONTROL +# undef CONFIG_UART3_FLOWCONTROL +#ifndef CONFIG_CXD56_UART1 +# undef CONFIG_UART1_FLOWCONTROL +#endif + +/* Get Firmware version */ + +#define GET_SBL_VERSION() (BKUP->sbl_version) +#define GET_SYSFW_VERSION() (BKUP->sysfw_version) +#define GET_SYSFW_VERSION_MAJOR() ((GET_SYSFW_VERSION() >> 28) & 0xf) +#define GET_SYSFW_VERSION_MINOR() ((GET_SYSFW_VERSION() >> 20) & 0xff) +#define GET_SYSFW_VERSION_BUILD() (GET_SYSFW_VERSION() & 0xfffff) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56XX_CONFIG_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_idle.c b/arch/arm/src/cxd56xx/cxd56_idle.c new file mode 100644 index 00000000000..b0655d025a2 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_idle.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/arm/src/cxd56/cxd56_idle.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#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 + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = enter_critical_section(); + + /* Perform board-specific, state-dependent logic here */ + + _info("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + cxd56_pmstandby(true); + break; + + case PM_SLEEP: + (void)cxd56_pmsleep(); + break; + + default: + break; + } + + leave_critical_section(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * 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. + */ + + nxsched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +} diff --git a/arch/arm/src/cxd56xx/cxd56_irq.c b/arch/arm/src/cxd56xx/cxd56_irq.c new file mode 100644 index 00000000000..1734e25493c --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_irq.c @@ -0,0 +1,558 @@ +/**************************************************************************** + * arch/arm/src/cxd56/cxd56_irq.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "cxd56_irq.h" + +#ifdef CONFIG_SMP +# include "init/init.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (CXD56M4_SYSH_PRIORITY_DEFAULT << 24 | CXD56M4_SYSH_PRIORITY_DEFAULT << 16 | \ + CXD56M4_SYSH_PRIORITY_DEFAULT << 8 | CXD56M4_SYSH_PRIORITY_DEFAULT) + +#define INTC_EN(n) (CXD56_INTC_BASE + 0x10 + (((n) >> 5) << 2)) + +/**************************************************************************** + * 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. + */ + +#ifdef CONFIG_SMP +/* For the case of configurations with multiple CPUs, then there must be one + * such value for each processor that can receive an interrupt. + */ + +volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; +#else +volatile uint32_t *g_current_regs[1]; +#endif + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cxd56_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ_INFO) +static void cxd56_dumpnvic(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\n", getreg32(NVIC_IRQ0_31_ENABLE), + getreg32(NVIC_IRQ32_63_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\n", + getreg32(NVIC_IRQ48_51_PRIORITY), + getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY)); + leave_critical_section(flags); +} +#else +# define cxd56_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: cxd56_nmi, cxd56_busfault, cxd56_usagefault, cxd56_pendsv, + * cxd56_dbgmonitor, cxd56_pendsv, cxd56_reserved + * + * Description: + * Handlers for various exceptions. 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 cxd56_nmi(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int cxd56_busfault(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Bus fault recived\n"); + PANIC(); + return 0; +} + +static int cxd56_usagefault(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Usage fault received\n"); + PANIC(); + return 0; +} + +static int cxd56_pendsv(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int cxd56_dbgmonitor(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int cxd56_reserved(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: cxd56_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 cxd56_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 + +static int excinfo(int irq, uint32_t *regaddr, uint32_t *bit) +{ + *regaddr = NVIC_SYSHCON; + switch (irq) + { + case CXD56_IRQ_MEMFAULT: + *bit = NVIC_SYSHCON_MEMFAULTENA; + break; + + case CXD56_IRQ_BUSFAULT: + *bit = NVIC_SYSHCON_BUSFAULTENA; + break; + + case CXD56_IRQ_USAGEFAULT: + *bit = NVIC_SYSHCON_USGFAULTENA; + break; + + case CXD56_IRQ_SYSTICK: + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + break; + + default: + return ERROR; /* Invalid or unsupported exception */ + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * Complete initialization of the interrupt system and enable normal, + * interrupt processing. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int num_priority_registers; + + /* Disable all interrupts */ + + putreg32(0, NVIC_IRQ0_31_ENABLE); + putreg32(0, NVIC_IRQ32_63_ENABLE); + putreg32(0, NVIC_IRQ64_95_ENABLE); + putreg32(0, NVIC_IRQ96_127_ENABLE); + + /* 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); + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports: + * + * 0 -> 32 interrupt lines, 8 priority registers + * 1 -> 64 " " " ", 16 priority registers + * 2 -> 96 " " " ", 32 priority registers + * ... + */ + + num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8; + + /* Now set all of the interrupt lines to the default priority */ + + regaddr = NVIC_IRQ0_3_PRIORITY; + while (num_priority_registers--) + { + putreg32(DEFPRIORITY32, regaddr); + regaddr += 4; + } + + /* 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(CXD56_IRQ_SVCALL, up_svcall, NULL); + irq_attach(CXD56_IRQ_HARDFAULT, up_hardfault, NULL); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(CXD56_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + cxd56_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(CXD56_IRQ_MEMFAULT, up_memfault, NULL); + up_enable_irq(CXD56_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG_FEATURES + irq_attach(CXD56_IRQ_NMI, cxd56_nmi, NULL); +# ifndef CONFIG_ARM_MPU + irq_attach(CXD56_IRQ_MEMFAULT, up_memfault, NULL); +# endif + irq_attach(CXD56_IRQ_BUSFAULT, cxd56_busfault, NULL); + irq_attach(CXD56_IRQ_USAGEFAULT, cxd56_usagefault, NULL); + irq_attach(CXD56_IRQ_PENDSV, cxd56_pendsv, NULL); + irq_attach(CXD56_IRQ_DBGMONITOR, cxd56_dbgmonitor, NULL); + irq_attach(CXD56_IRQ_RESERVED, cxd56_reserved, NULL); +#endif + + cxd56_dumpnvic("initial", CXD56_IRQ_NIRQS); + + /* If a debugger is connected, try to prevent it from catching hardfaults. + * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal + * operation. + */ + +#if defined(CONFIG_DEBUG_FEATURES) && !defined(CONFIG_ARMV7M_USEBASEPRI) + { + uint32_t regval; + + regval = getreg32(NVIC_DEMCR); + regval &= ~NVIC_DEMCR_VCHARDERR; + putreg32(regval, NVIC_DEMCR); + } +#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 (irq >= CXD56_IRQ_EXTINT) + { + irqstate_t flags = enter_critical_section(); + irq -= CXD56_IRQ_EXTINT; + bit = 1 << (irq & 0x1f); + + regval = getreg32(INTC_EN(irq)); + regval &= ~bit; + putreg32(regval, INTC_EN(irq)); + leave_critical_section(flags); + putreg32(bit, NVIC_IRQ_CLEAR(irq)); + } + else + { + if (excinfo(irq, ®addr, &bit) == OK) + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } + + cxd56_dumpnvic("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 (irq >= CXD56_IRQ_EXTINT) + { + irqstate_t flags = enter_critical_section(); + irq -= CXD56_IRQ_EXTINT; + bit = 1 << (irq & 0x1f); + + regval = getreg32(INTC_EN(irq)); + regval |= bit; + putreg32(regval, INTC_EN(irq)); + leave_critical_section(flags); + putreg32(bit, NVIC_IRQ_ENABLE(irq)); + } + else + { + if (excinfo(irq, ®addr, &bit) == OK) + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } + + cxd56_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_ack_irq(int irq) +{ + /* Check for external interrupt */ + + if (irq >= CXD56_IRQ_EXTINT) + { + irq -= CXD56_IRQ_EXTINT; + putreg32(1 << (irq & 0x1f), NVIC_IRQ_CLRPEND(irq)); + } +} + +/**************************************************************************** + * 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 >= CXD56_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < CXD56_IRQ_EXTINT) + { + /* 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 -= CXD56_IRQ_EXTINT; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + cxd56_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/cxd56xx/cxd56_irq.h b/arch/arm/src/cxd56xx/cxd56_irq.h new file mode 100644 index 00000000000..568e5d1963e --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_irq.h @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_irq.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_IRQ_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_IRQ_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_serial.c b/arch/arm/src/cxd56xx/cxd56_serial.c new file mode 100644 index 00000000000..8c3811c3f98 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_serial.c @@ -0,0 +1,997 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_serial.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "cxd56_config.h" +#include "cxd56_serial.h" + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#if defined(USE_SERIALDRIVER) && defined(HAVE_UART) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t basefreq; /* Base frequency of input clock */ + uint32_t baud; /* Configured baud */ + uint32_t ier; /* Saved IER value */ + uint8_t id; /* ID=0,1,2,3 */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ +#ifdef HAVE_RS485 + bool dtrdir; /* DTR pin is the direction bit */ +#endif + void *pmhandle; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_setup(FAR struct uart_dev_s *dev); +static void up_shutdown(FAR struct uart_dev_s *dev); +static int up_attach(FAR struct uart_dev_s *dev); +static void up_detach(FAR struct uart_dev_s *dev); +static int up_interrupt(int irq, FAR void *context, FAR void *arg); +static int up_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +#ifdef CONFIG_UART2_IFLOWCONTROL +static bool up_rxflowcontrol(FAR struct uart_dev_s *dev, + unsigned int nbuffered, bool upper); +#endif +static int up_receive(FAR struct uart_dev_s *dev, FAR uint32_t *status); +static void up_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(FAR struct uart_dev_s *dev); +static void up_send(FAR struct uart_dev_s *dev, int ch); +static void up_txint(FAR struct uart_dev_s *dev, bool enable); +static bool up_txready(FAR struct uart_dev_s *dev); +static bool up_txempty(FAR struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +#ifdef CONFIG_CXD56_UART2 +static const struct uart_ops_s g_uart2_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_UART2_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; +#endif + +/* I/O buffers */ + +#ifdef CONFIG_CXD56_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif +#ifdef CONFIG_CXD56_UART2 +static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE]; +#endif + +/* This describes the state of the CXD56xx uart1 port. */ + +#ifdef CONFIG_CXD56_UART1 +static struct up_dev_s g_uart1priv = +{ + .uartbase = CXD56_UART1_BASE, + .basefreq = BOARD_UART1_BASEFREQ, + .baud = CONFIG_UART1_BAUD, + .id = 1, + .irq = CXD56_IRQ_UART1, + .parity = CONFIG_UART1_PARITY, + .bits = CONFIG_UART1_BITS, + .stopbits2 = 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, +}; +# define TTYS0_DEV g_uart1port /* UART1=ttyS0 */ +#endif + +/* This describes the state of the CXD56xx uart1 port. */ + +#ifdef CONFIG_CXD56_UART2 +static struct up_dev_s g_uart2priv = +{ + .uartbase = CXD56_UART2_BASE, + .basefreq = BOARD_UART2_BASEFREQ, + .baud = CONFIG_UART2_BAUD, + .id = 2, + .irq = CXD56_IRQ_APP_UART, + .parity = CONFIG_UART2_PARITY, + .bits = CONFIG_UART2_BITS, + .stopbits2 = 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_uart2_ops, + .priv = &g_uart2priv, +}; + +# define TTYS2_DEV g_uart2port /* UART2=ttyS2 */ +#endif + +/* Which UART with be tty0/console and which tty1? tty2? tty3? */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1=console */ +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart2port /* UART2=console */ +# endif +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(FAR struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(FAR struct up_dev_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static inline void up_disableuartint(FAR struct up_dev_s *priv, + FAR uint32_t *ier) +{ + irqstate_t flags; + + flags = enter_critical_section(); + if (ier) + { + *ier = priv->ier & UART_INTR_ALL; + } + + priv->ier &= ~UART_INTR_ALL; + up_serialout(priv, CXD56_UART_IMSC, priv->ier); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static inline void up_restoreuartint(FAR struct up_dev_s *priv, uint32_t ier) +{ + irqstate_t flags; + + flags = enter_critical_section(); + priv->ier |= ier & UART_INTR_ALL; + up_serialout(priv, CXD56_UART_IMSC, priv->ier); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_enablebreaks + ****************************************************************************/ + +static inline void up_enablebreaks(FAR struct up_dev_s *priv, bool enable) +{ + uint32_t lcr = up_serialin(priv, CXD56_UART_LCR_H); + if (enable) + { + lcr |= UART_LCR_BRK; + } + else + { + lcr &= ~UART_LCR_BRK; + } + + up_serialout(priv, CXD56_UART_LCR_H, lcr); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This method is + * called the first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(FAR struct uart_dev_s *dev) +{ +#ifndef CONFIG_SUPPRESS_UART_CONFIG + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + uint32_t lcr; + uint32_t cr; + + cxd56_uart_setup(priv->id); + + /* Init HW */ + + up_serialout(priv, CXD56_UART_CR, 0); + up_serialout(priv, CXD56_UART_LCR_H, 0); + up_serialout(priv, CXD56_UART_DMACR, 0); + up_serialout(priv, CXD56_UART_RSR_ECR, 0xf); + + /* Set up the IER */ + + priv->ier = up_serialin(priv, CXD56_UART_IMSC); + + /* Set the BAUD divisor */ + + cxd56_setbaud(priv->uartbase, priv->basefreq, priv->baud); + + /* Set up the LCR */ + + lcr = 0; + if (priv->bits == 7) + { + lcr |= UART_LCR_WLEN(7); + } + else + { + lcr |= UART_LCR_WLEN(8); + } + + if (priv->stopbits2) + { + lcr |= UART_LCR_STP2; + } + + if (priv->parity == 1) + { + lcr |= (UART_LCR_PEN); + } + else if (priv->parity == 2) + { + lcr |= (UART_LCR_PEN | UART_LCR_EPS); + } + + /* Save the LCR */ + + up_serialout(priv, CXD56_UART_LCR_H, lcr); + + up_serialout(priv, CXD56_UART_IFLS, 0); + up_serialout(priv, CXD56_UART_ICR, 0x7ff); + + cr = UART_CR_RXE | UART_CR_TXE; + + /* Enable Auto-RTS and Auto-CS Flow Control in the Modem Control Register */ + +# ifdef CONFIG_UART1_FLOWCONTROL + if (priv->uartbase == CXD56_UART1_BASE) + { + cr |= UART_CR_CTSEN | UART_CR_RTSEN; + } +# endif + + /* Enable Auto-RTS and Auto-CS Flow Control in UART2 */ + +# ifdef CONFIG_UART2_IFLOWCONTROL + if (priv->uartbase == CXD56_UART2_BASE) + { + cr |= UART_CR_RTSEN; + } +# endif +# ifdef CONFIG_UART2_OFLOWCONTROL + if (priv->uartbase == CXD56_UART2_BASE) + { + cr |= UART_CR_CTSEN; + } +# endif + up_serialout(priv, CXD56_UART_CR, cr); + + /* Enable FIFO and UART in the last */ + + lcr |= UART_LCR_FEN; + up_serialout(priv, CXD56_UART_LCR_H, lcr); + cr |= UART_CR_EN; + up_serialout(priv, CXD56_UART_CR, cr); +#endif + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial port is closed + * + ****************************************************************************/ + +static void up_shutdown(FAR struct uart_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + + /* Disable further interrupts from the UART */ + + up_disableuartint(priv, NULL); + + /* Put the UART hardware back its reset state */ + + switch (priv->id) + { + case 0: + case 1: + case 2: + cxd56_uart_reset(priv->id); + break; + + default: + break; + } +} + +/**************************************************************************** + * Name: up_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 up_attach(FAR struct uart_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, up_interrupt, dev); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_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 up_detach(FAR struct uart_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_rxflowcontrol + * + * Description: + * Called when Rx buffer is full (or exceeds configured watermark levels + * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). + * Return true if UART activated RX flow control to block more incoming + * data + * + * Input parameters: + * dev - UART device instance + * nbuffered - the number of characters currently buffered + * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is + * not defined the value will be 0 for an empty buffer or the + * defined buffer size for a full buffer) + * upper - true indicates the upper watermark was crossed where + * false indicates the lower watermark has been crossed + * + * Returned Value: + * true if RX flow control activated. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(FAR struct uart_dev_s *dev, + unsigned int nbuffered, bool upper) +{ + (void)nbuffered; + + up_rxint(dev, !upper); + + return true; +} +#endif /* CONFIG_SERIAL_IFLOWCONTROL */ + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART 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 + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, FAR void *context, FAR void *arg) +{ + FAR struct uart_dev_s *dev = (FAR struct uart_dev_s *)arg; + FAR struct up_dev_s *priv; + uint32_t status; + int passes; + + priv = (FAR struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = up_serialin(priv, CXD56_UART_MIS); + if (status == 0) + { + return OK; + } + + up_serialout(priv, CXD56_UART_ICR, status); + if (status & UART_INTR_RI) + { + } + + if (status & UART_INTR_CTS) + { + } + + if (status & UART_INTR_DCD) + { + } + + if (status & UART_INTR_DSR) + { + } + + if (status & (UART_INTR_RX | UART_INTR_RT)) + { + uart_recvchars(dev); + } + + if (status & UART_INTR_TX) + { + uart_xmitchars(dev); + } + + if (status & UART_INTR_FE) + { + } + + if (status & UART_INTR_PE) + { + } + + if (status & UART_INTR_BE) + { + } + + if (status & UART_INTR_OE) + { + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct uart_dev_s *dev = inode->i_private; + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + FAR struct up_dev_s *user = (FAR struct up_dev_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + FAR struct termios *termiosp = (FAR struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Other termios fields are not yet returned. + * Note that only cfsetospeed is not necessary because we have + * knowledge that only one speed is supported. + */ + + cfsetispeed(termiosp, priv->baud); + } + break; + + case TCSETS: + { + FAR struct termios *termiosp = (FAR struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Handle other termios settings. + * Note that only cfgetispeed is used besued we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + cxd56_setbaud(priv->uartbase, priv->basefreq, priv->baud); + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + up_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + up_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + + case TCFLSH: /* Flush TX fifo etc. */ + { + while (!up_txempty(dev)); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_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 up_receive(FAR struct uart_dev_s *dev, FAR uint32_t *status) +{ + FAR struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rbr; + + rbr = up_serialin(priv, CXD56_UART_DR); + *status = rbr & 0xf00; + return rbr & 0xff; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(FAR struct uart_dev_s *dev, bool enable) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= (UART_INTR_RX | UART_INTR_RT); +#endif + } + else + { + priv->ier &= ~(UART_INTR_RX | UART_INTR_RT); + } + + up_serialout(priv, CXD56_UART_IMSC, priv->ier); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(FAR struct uart_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + return ((up_serialin(priv, CXD56_UART_FR) & UART_FLAG_RXFE) == 0); +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void up_send(FAR struct uart_dev_s *dev, int ch) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + up_serialout(priv, CXD56_UART_DR, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(FAR struct uart_dev_s *dev, bool enable) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->ier |= UART_INTR_TX; + up_serialout(priv, CXD56_UART_IMSC, priv->ier); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + priv->ier &= ~UART_INTR_TX; + up_serialout(priv, CXD56_UART_IMSC, priv->ier); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool up_txready(FAR struct uart_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + return ((up_serialin(priv, CXD56_UART_FR) & UART_FLAG_TXFF) == 0); +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool up_txempty(FAR struct uart_dev_s *dev) +{ + FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->priv; + uint32_t rbr = 0; + rbr = up_serialin(priv, CXD56_UART_FR); + return (((rbr & UART_FLAG_TXFE) != 0) && ((rbr & UART_FLAG_BUSY) == 0)); +} + +/**************************************************************************** + * Public Funtions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialinit + * + * 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: Configuration of the CONSOLE UART was performed by up_lowsetup() + * very early in the boot sequence. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ + /* Configuration whichever one is the console */ + +# ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +# endif +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t ier; + up_disableuartint(priv, &ier); +#endif + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#ifdef HAVE_CONSOLE + up_restoreuartint(priv, ier); +#endif + + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_UART + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/cxd56xx/cxd56_serial.h b/arch/arm/src/cxd56xx/cxd56_serial.h new file mode 100644 index 00000000000..58368cdfd8e --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_serial.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_serial.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * 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 of Sony Semiconductor Solutions Corporation 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_CXD56XX_CXD56_SERIAL_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_SERIAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "cxd56_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_SERIAL_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_start.c b/arch/arm/src/cxd56xx/cxd56_start.c new file mode 100644 index 00000000000..c786536492b --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_start.c @@ -0,0 +1,362 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_start.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Power-Up Reset Overview + * ----------------------- + * + * The ARM core starts executing code on reset with the program counter set + * to 0x0000:0000. The CXD56xx contains a shadow pointer register that + * allows areas of memory to be mapped to address 0x0000:0000. The default, + * reset value of the shadow pointer is 0x1040:0000 so that on reset code in + * the boot ROM is always executed first. + * + * The boot starts after reset is released. The IRC is selected as CPU clock + * and the Cortex-M4 starts the boot loader. By default the JTAG access to the + * chip is disabled at reset. The boot ROM determines the boot mode based on + * the OTP BOOT_SRC value or reset state pins. For flash-based parts, the part + * boots from internal flash by default. Otherwse, the boot ROM copies the + * image to internal SRAM at location 0x1000:0000, sets the ARM's shadow + * pointer to 0x1000:0000, and jumps to that location. + * + * However, using JTAG the executable image can be also loaded directly into + * and executed from SRAM. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "up_arch.h" +#include "up_internal.h" +#include "nvic.h" +#include "sched/sched.h" +#include "init/init.h" + +#include "cxd56_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CXD56_BOOT_ENTRY_POINT (0x04100000 + 0x1400) + +/* XXX */ + +void weak_function up_cpuctxload(void); + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_nx_start(void *pv, unsigned int nbytes) + __attribute__((naked, no_instrument_function, noreturn)); +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +#define DEFPRIORITY32 \ + (CXD56M4_SYSH_PRIORITY_DEFAULT << 24 | CXD56M4_SYSH_PRIORITY_DEFAULT << 16 | \ + CXD56M4_SYSH_PRIORITY_DEFAULT << 8 | CXD56M4_SYSH_PRIORITY_DEFAULT) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fpuconfig + * + * 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 +# ifndef CONFIG_ARMV7M_LAZYFPU + +static inline void fpuconfig(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 fpuconfig(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 fpuconfig() +#endif + +/**************************************************************************** + * Name: go_nx_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_nx_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * nx_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 nx_start\n" /* Branch to nx_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + uint32_t *dest; + + /* Set MSP/PSP to IDLE stack */ + + __asm__ __volatile__("\tmsr msp, %0\n" : + : "r" ((uint32_t)&_ebss + + CONFIG_IDLETHREAD_STACKSIZE - 4)); + __asm__ __volatile__("\tmsr psp, %0\n" : + : "r" ((uint32_t)&_ebss + + CONFIG_IDLETHREAD_STACKSIZE - 4)); + + up_irq_disable(); + + if (*((uint32_t *)CXD56_BOOT_ENTRY_POINT)) + { +#ifdef CONFIG_HAVE_WEAKFUNCTIONS + if (up_cpuctxload) +#endif + { + up_cpuctxload(); + } + } + + /* Enable bus snoop */ + + putreg32(0, CXD56_EXCCONF_BASE + 0); + + cxd56_lowsetup(); + showprogress('A'); + + /* 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; + } + + /* Initialize the FPU (if configured) */ + + fpuconfig(); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_earlyserialinit(); +#endif + showprogress('E'); + + /* 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 + showprogress('F'); +#endif + + /* Initialize onboard resources */ + + cxd56_boardinitialize(); + showprogress('G'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into nx_start() */ + + go_nx_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Call nx_start() */ + + nx_start(); + + /* Shouldn't get here */ + + for (; ; ); +#endif +} diff --git a/arch/arm/src/cxd56xx/cxd56_timerisr.c b/arch/arm/src/cxd56xx/cxd56_timerisr.c new file mode 100644 index 00000000000..f7f66ab08e9 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_timerisr.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_timerisr.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012 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: Either the internal CCLK or external STCLK (P3.26) clock + * as the source in the STCTRL register. This file alwyays configures the + * timer to use CCLK as its source. + */ + +static uint32_t g_systrvr; + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int cxd56_timerisr(int irq, uint32_t *regs, FAR void *arg); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: cxd56_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +static int cxd56_timerisr(int irq, uint32_t *regs, FAR void *arg) +{ + /* Process timer interrupt */ + + nxsched_process_timer(); + return 0; +} + +/**************************************************************************** + * 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 |= (CXD56M4_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Make sure that the SYSTICK clock source is set to use the CXD56xx CCLK */ + + regval = getreg32(NVIC_SYSTICK_CTRL); + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; + putreg32(regval, NVIC_SYSTICK_CTRL); + + /* Configure SysTick to interrupt at the requested rate */ + + g_systrvr = (CXD56_CCLK / CLK_TCK) - 1; + putreg32(g_systrvr, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(CXD56_IRQ_SYSTICK, (xcpt_t)cxd56_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(CXD56_IRQ_SYSTICK); +} diff --git a/arch/arm/src/cxd56xx/cxd56_timerisr.h b/arch/arm/src/cxd56xx/cxd56_timerisr.h new file mode 100644 index 00000000000..67531f57680 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_timerisr.h @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_timerisr.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012 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_CXD56XX_CXD56_TIMERISR_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_TIMERISR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * 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: cxd56_timerisr_initialize + * + * Description: + * initialize timerisr + * + * + ****************************************************************************/ + +int cxd56_timerisr_initialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_TIMERISR_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_uart.c b/arch/arm/src/cxd56xx/cxd56_uart.c new file mode 100644 index 00000000000..7b596c28d83 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_uart.c @@ -0,0 +1,328 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_uart.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012 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 "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "cxd56_config.h" +#include "cxd56_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE CXD56_UART0_BASE +# define CONSOLE_BASEFREQ BOARD_UART0_BASEFREQ +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +# define CONSOLE_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE CXD56_UART1_BASE +# define CONSOLE_BASEFREQ BOARD_UART1_BASEFREQ +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +# define CONSOLE_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE CXD56_UART2_BASE +# define CONSOLE_BASEFREQ BOARD_UART2_BASEFREQ +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_PARITY CONFIG_UART2_PARITY +# define CONSOLE_2STOP CONFIG_UART2_2STOP +#elif defined(HAVE_CONSOLE) +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Get word length setting for the console */ + +#if CONSOLE_BITS >= 5 && CONSOLE_BITS <= 8 +# define CONSOLE_LCR_WLS UART_LCR_WLEN(CONSOLE_BITS) +#elif defined(HAVE_CONSOLE) +# error "Invalid CONFIG_UARTn_BITS setting for console " +#endif + +/* Get parity setting for the console */ + +#if CONSOLE_PARITY == 0 +# define CONSOLE_LCR_PAR 0 +#elif CONSOLE_PARITY == 1 +# define CONSOLE_LCR_PAR (UART_LCR_PEN) +#elif CONSOLE_PARITY == 2 +# define CONSOLE_LCR_PAR (UART_LCR_PEN | UART_LCR_EPS) +#elif CONSOLE_PARITY == 3 +# define CONSOLE_LCR_PAR (UART_LCR_PEN | UART_LCR_SPS) +#elif CONSOLE_PARITY == 4 +# define CONSOLE_LCR_PAR (UART_LCR_PEN | UART_LCR_EPS | UART_LCR_SPS) +#elif defined(HAVE_CONSOLE) +# error "Invalid CONFIG_UARTn_PARITY setting for CONSOLE" +#endif + +/* Get stop-bit setting for the console and UART0/1/2 */ + +#if CONSOLE_2STOP != 0 +# define CONSOLE_LCR_STOP UART_LCR_STP2 +#else +# define CONSOLE_LCR_STOP 0 +#endif + +/* LCR and FCR values for the console */ + +#define CONSOLE_LCR_VALUE (CONSOLE_LCR_WLS | CONSOLE_LCR_PAR | CONSOLE_LCR_STOP) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct uartdev +{ + uintptr_t uartbase; /* Base address of UART registers */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct uartdev g_uartdevs[] = +{ + { + CXD56_UART0_BASE + }, + { + CXD56_UART1_BASE + }, + { + CXD56_UART2_BASE + } +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#if defined HAVE_UART && defined HAVE_CONSOLE + /* Wait for the transmitter to be available */ + + while ((getreg32(CONSOLE_BASE + CXD56_UART_FR) & UART_FLAG_TXFF)); + + /* Send the character */ + + putreg32((uint32_t)ch, CONSOLE_BASE + CXD56_UART_DR); +#endif +} + +/**************************************************************************** + * Name: cxd56_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + * The USART0/2/3 and UART1 peripherals are configured using the following + * registers: + * 1. Baud rate: In the LCR register, set bit DLAB = 1. This enables access + * to registers DLL and DLM for setting the baud rate. Also, if needed, + * set the fractional baud rate in the fractional divider + * 2. UART FIFO: Use bit FIFO enable (bit 0) in FCR register to + * enable FIFO. + * 3. Pins: Select UART pins through the PINSEL registers and pin modes + * through the PINMODE registers. UART receive pins should not have + * pull-down resistors enabled. + * 4. Interrupts: To enable UART interrupts set bit DLAB = 0 in the LCRF + * register. This enables access to IER. Interrupts are enabled + * in the NVIC using the appropriate Interrupt Set Enable register. + * 5. DMA: UART transmit and receive functions can operate with the + * GPDMA controller. + * + ****************************************************************************/ + +void cxd56_lowsetup(void) +{ +#ifdef HAVE_UART + /* Enable clocking and for all console UART and disable power for + * other UARTs + */ + +# if defined(CONFIG_UART0_SERIAL_CONSOLE) + cxd56_uart_setup(0); +# elif defined(CONFIG_UART1_SERIAL_CONSOLE) + cxd56_uart_setup(1); +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) + cxd56_uart_setup(2); +# endif + + /* Configure the console (only) */ + +# if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + { + uint32_t val; + + val = getreg32(CONSOLE_BASE + CXD56_UART_CR); + if (val & UART_CR_EN) + { + return; + } + } + + putreg32(CONSOLE_LCR_VALUE, CONSOLE_BASE + CXD56_UART_LCR_H); + cxd56_setbaud(CONSOLE_BASE, CONSOLE_BASEFREQ, CONSOLE_BAUD); + putreg32(0, CONSOLE_BASE + CXD56_UART_IFLS); + putreg32(UART_INTR_ALL, CONSOLE_BASE + CXD56_UART_ICR); + +# endif +#endif /* HAVE_UART */ +} + +/**************************************************************************** + * Name: cxd56_uart_reset + * + * Description: + * Reset a UART. These functions are used by the serial driver when a + * UART is closed. + * + ****************************************************************************/ + +void cxd56_uart_reset(int ch) +{ +} + +void cxd56_uart_setup(int ch) +{ + uint32_t cr; + uint32_t lcr; + + /* TODO: clock configuration */ + +#ifdef CONFIG_CXD56_UART2 + if (ch == 2) + { + /* Not supported yet. */ + + return; + } +#endif /* CONFIG_CXD56_UART2 */ + + cr = getreg32(g_uartdevs[ch].uartbase + CXD56_UART_CR); + putreg32(cr & ~(1 << 0), g_uartdevs[ch].uartbase + CXD56_UART_CR); + + lcr = getreg32(g_uartdevs[ch].uartbase + CXD56_UART_LCR_H); + putreg32(lcr & ~(1 << 4), g_uartdevs[ch].uartbase + CXD56_UART_LCR_H); + + putreg32(cr, g_uartdevs[ch].uartbase + CXD56_UART_CR); +} + +/**************************************************************************** + * Name: cxd56_setbaud + * + ****************************************************************************/ + +void cxd56_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud) +{ + uint32_t ibrd; + uint32_t fbrd; + uint32_t div; + uint32_t lcr_h; + irqstate_t flags = enter_critical_section(); + + div = basefreq / (16 * baud / 100); + ibrd = div / 100; + + /* fbrd will be up to 63. + * ((99 * 64 + 50) / 100 = 6386 / 100 = 63) + */ + + fbrd = (((div % 100) * 64) + 50) / 100; + + /* Check invalid baud rate divider setting combination. */ + + if (ibrd == 0 || (ibrd == 65535 && fbrd != 0)) + { + goto finish; + } + + putreg32(ibrd, uartbase + CXD56_UART_IBRD); + putreg32(fbrd, uartbase + CXD56_UART_FBRD); + + /* Baud rate is updated by writing to LCR_H. */ + + lcr_h = getreg32(uartbase + CXD56_UART_LCR_H); + putreg32(lcr_h, uartbase + CXD56_UART_LCR_H); + +finish: + leave_critical_section(flags); +} diff --git a/arch/arm/src/cxd56xx/cxd56_uart.h b/arch/arm/src/cxd56xx/cxd56_uart.h new file mode 100644 index 00000000000..a03c664fab3 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_uart.h @@ -0,0 +1,142 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_uart.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_UART_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include "chip/cxd56_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * 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: cxd56_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization of the serial console. + * + ****************************************************************************/ + +void cxd56_lowsetup(void); + +/**************************************************************************** + * Name: cxd56_uart_reset + * + * Description: + * Reset a U[S]ART. These functions are used by the serial driver when a + * U[S]ART is closed. + * + ****************************************************************************/ + +void cxd56_uart_reset(int ch); + +/**************************************************************************** + * Name: cxd56_uart_setup + * + * Description: + * Configure the UART. This involves: + * + * 1. Connecting the input clock to the UART as specified in the + * board.h file, + * 2. Configuring the UART pins + * + ****************************************************************************/ + +void cxd56_uart_setup(int); + +/**************************************************************************** + * Name: cxd56_setbaud + * + * Description: + * Configure the U[S]ART divisors to accomplish the desired BAUD given the + * U[S]ART base frequency. + * + * This computationally intensive algorithm is based on the same logic + * used in the NXP sample code. + * + ****************************************************************************/ + +void cxd56_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud); + +/**************************************************************************** + * Name: cxd56_uart_initialize + * + * Description: + * Various initial registration + * + ****************************************************************************/ + +int cxd56_uart_initialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_UART_H */