summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-24 17:27:38 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-24 17:27:38 +0000
commit87e2cdcd00d8cdaab89a154cfb7112a54252c1c2 (patch)
treec2aa0d0293e55d558763d9c11ddc7781c1af4699 /nuttx/arch/arm/src
parentd941bab5f47e370884546575d1aa0e3001bb6028 (diff)
downloadpx4-nuttx-87e2cdcd00d8cdaab89a154cfb7112a54252c1c2.tar.gz
px4-nuttx-87e2cdcd00d8cdaab89a154cfb7112a54252c1c2.tar.bz2
px4-nuttx-87e2cdcd00d8cdaab89a154cfb7112a54252c1c2.zip
Add support for compal e99 and e88 phones
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4512 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src')
-rw-r--r--nuttx/arch/arm/src/calypso/Make.defs53
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_armio.c103
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_head.S23
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_heap.c84
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_irq.c312
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_lowputc.S133
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_serial.c964
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_timer.c206
-rw-r--r--nuttx/arch/arm/src/calypso/chip.h211
-rw-r--r--nuttx/arch/arm/src/calypso/clock.c218
10 files changed, 2307 insertions, 0 deletions
diff --git a/nuttx/arch/arm/src/calypso/Make.defs b/nuttx/arch/arm/src/calypso/Make.defs
new file mode 100644
index 000000000..cebf503b7
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/Make.defs
@@ -0,0 +1,53 @@
+############################################################################
+# calypso/Make.defs
+#
+# Copyright (C) 2007 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+#
+# Copyright (C) 2011 Stefan Richter. All rights reserved.
+# Author: Stefan Richter <ichgeh@l--putt.de>
+#
+# 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 Gregory Nutt 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 = calypso_head.S
+
+CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_vectors.S \
+ up_nommuhead.S
+CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
+ up_createstack.c up_dataabort.c up_mdelay.c up_udelay.c up_doirq.c \
+ up_exit.c up_idle.c up_initialstate.c up_initialize.c \
+ up_interruptcontext.c up_prefetchabort.c up_releasepending.c \
+ up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c \
+ up_sigdeliver.c up_syscall.c up_unblocktask.c \
+ up_undefinedinsn.c up_usestack.c
+
+CHIP_ASRCS = calypso_lowputc.S
+CHIP_CSRCS = calypso_irq.c calypso_timer.c calypso_heap.c \
+ calypso_serial.c clock.c
diff --git a/nuttx/arch/arm/src/calypso/calypso_armio.c b/nuttx/arch/arm/src/calypso/calypso_armio.c
new file mode 100644
index 000000000..59c5a79e7
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_armio.c
@@ -0,0 +1,103 @@
+/****************************************************************************
+ * Driver for shared features of ARMIO modules
+ *
+ * Copyright (C) 2011 Stefan Richter. All rights reserved.
+ * Author: Stefan Richter <ichgeh@l--putt.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include <arch/calypso/memory.h>
+#include <arch/calypso/armio.h>
+
+
+/****************************************************************************
+ * HW access
+ ****************************************************************************/
+
+#define BASE_ADDR_ARMIO 0xfffe4800
+#define ARMIO_REG(x) ((void *)BASE_ADDR_ARMIO + (x))
+
+enum armio_reg {
+ LATCH_IN = 0x00,
+ LATCH_OUT = 0x02,
+ IO_CNTL = 0x04,
+ CNTL_REG = 0x06,
+ LOAD_TIM = 0x08,
+ KBR_LATCH_REG = 0x0a,
+ KBC_REG = 0x0c,
+ BUZZ_LIGHT_REG = 0x0e,
+ LIGHT_LEVEL = 0x10,
+ BUZZER_LEVEL = 0x12,
+ GPIO_EVENT_MODE = 0x14,
+ KBD_GPIO_INT = 0x16,
+ KBD_GPIO_MASKIT = 0x18,
+ GPIO_DEBOUNCING = 0x1a,
+ GPIO_LATCH = 0x1c,
+};
+
+#define KBD_INT (1<<0)
+#define GPIO_INT (1<<1)
+
+
+/****************************************************************************
+ * ARMIO interrupt handler
+ * forward keypad events
+ * forward GPIO events
+ ****************************************************************************/
+
+static int kbd_gpio_irq(int irq, uint32_t *regs)
+{
+ calypso_kbd_irq();
+
+ return 0;
+}
+
+
+/****************************************************************************
+ * Initialize ARMIO
+ ****************************************************************************/
+
+void calypso_armio(void)
+{
+ /* Enable ARMIO clock */
+ writew(1<<5, ARMIO_REG(CNTL_REG));
+
+ /* Mask GPIO interrupt and keypad interrupt */
+ writew(KBD_INT|GPIO_INT, ARMIO_REG(KBD_GPIO_MASKIT));
+
+ /* Attach and enable the interrupt */
+ irq_attach(IRQ_KEYPAD_GPIO, (xcpt_t)kbd_gpio_irq);
+ up_enable_irq(IRQ_KEYPAD_GPIO);
+}
diff --git a/nuttx/arch/arm/src/calypso/calypso_head.S b/nuttx/arch/arm/src/calypso/calypso_head.S
new file mode 100644
index 000000000..eb83b6851
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_head.S
@@ -0,0 +1,23 @@
+/* Place a branch to the real head at the entry point */
+.section .text.start
+ b __start
+
+
+/* Exception Vectors like they are needed for the exception vector
+ indirection of the internal boot ROM. The following section must
+ be liked to appear at 0x80001c */
+.section .text.exceptions
+_undef_instr:
+ b up_vectorundefinsn
+_sw_interr:
+ b up_vectorswi
+_prefetch_abort:
+ b up_vectorprefetch
+_data_abort:
+ b up_vectordata
+_reserved:
+ b _reserved
+_irq:
+ b up_vectorirq
+_fiq:
+ b up_vectorfiq
diff --git a/nuttx/arch/arm/src/calypso/calypso_heap.c b/nuttx/arch/arm/src/calypso/calypso_heap.c
new file mode 100644
index 000000000..70c44da01
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_heap.c
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * calypso_heap.c
+ * Initialize memory interfaces of Calypso MCU
+ *
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2011 Stefan Richter <ichgeh@l--putt.de>
+ *
+ * This source code is derivated from Osmocom-BB project and was
+ * relicensed as BSD with permission from original authors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include <arch/calypso/clock.h>
+#include <arch/calypso/timer.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Name: up_addregion
+ *
+ * Description:
+ * This function is called right after basics are initialized and right
+ * before IRQ system setup.
+ *
+ ****************************************************************************/
+
+void up_addregion(void)
+{
+#ifdef CONFIG_ARCH_BOARD_COMPALE99
+ /* Disable watchdog in first non-common function */
+ wdog_enable(0);
+#endif
+ // XXX: change to initialization of extern memory with save defaults
+ /* Configure memory interface */
+ calypso_mem_cfg(CALYPSO_nCS0, 3, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS1, 3, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS2, 5, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS3, 5, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_CS4, 0, CALYPSO_MEM_8bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS6, 0, CALYPSO_MEM_32bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS7, 0, CALYPSO_MEM_32bit, 0);
+
+ /* Set VTCXO_DIV2 = 1, configure PLL for 104 MHz and give ARM half of that */
+ calypso_clock_set(2, CALYPSO_PLL13_104_MHZ, ARM_MCLK_DIV_2);
+
+ /* Configure the RHEA bridge with some sane default values */
+ calypso_rhea_cfg(0, 0, 0xff, 0, 1, 0, 0);
+}
diff --git a/nuttx/arch/arm/src/calypso/calypso_irq.c b/nuttx/arch/arm/src/calypso/calypso_irq.c
new file mode 100644
index 000000000..a37fc6f38
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_irq.c
@@ -0,0 +1,312 @@
+/****************************************************************************
+ * arch/arm/src/calypso/calypso_irq.c
+ * Driver for Calypso IRQ controller
+ *
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2011 by Stefan Richter <ichgeh@l--putt.de>
+ *
+ * This source code is derivated from Osmocom-BB project and was
+ * relicensed as BSD with permission from original authors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/calypso/memory.h>
+
+#include "arm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BASE_ADDR_IRQ 0xfffffa00
+#define BASE_ADDR_IBOOT_EXC 0x0080001C
+
+enum irq_reg {
+ IT_REG1 = 0x00,
+ IT_REG2 = 0x02,
+ MASK_IT_REG1 = 0x08,
+ MASK_IT_REG2 = 0x0a,
+ IRQ_NUM = 0x10,
+ FIQ_NUM = 0x12,
+ IRQ_CTRL = 0x14,
+};
+
+#define ILR_IRQ(x) (0x20 + (x*2))
+#define IRQ_REG(x) ((void *)BASE_ADDR_IRQ + (x))
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+extern uint32_t _exceptions;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static uint8_t default_irq_prio[] = {
+ [IRQ_WATCHDOG] = 0xff,
+ [IRQ_TIMER1] = 0xff,
+ [IRQ_TIMER2] = 0xff,
+ [IRQ_TSP_RX] = 0,
+ [IRQ_TPU_FRAME] = 3,
+ [IRQ_TPU_PAGE] = 0xff,
+ [IRQ_SIMCARD] = 0xff,
+ [IRQ_UART_MODEM] = 8,
+ [IRQ_KEYPAD_GPIO] = 4,
+ [IRQ_RTC_TIMER] = 9,
+ [IRQ_RTC_ALARM_I2C] = 10,
+ [IRQ_ULPD_GAUGING] = 2,
+ [IRQ_EXTERNAL] = 12,
+ [IRQ_SPI] = 0xff,
+ [IRQ_DMA] = 0xff,
+ [IRQ_API] = 0xff,
+ [IRQ_SIM_DETECT] = 0,
+ [IRQ_EXTERNAL_FIQ] = 7,
+ [IRQ_UART_IRDA] = 2,
+ [IRQ_ULPD_GSM_TIMER] = 1,
+ [IRQ_GEA] = 0xff,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void _irq_enable(enum irq_nr nr, int enable)
+{
+ uint16_t *reg = IRQ_REG(MASK_IT_REG1);
+ uint16_t val;
+
+ if (nr > 15) {
+ reg = IRQ_REG(MASK_IT_REG2);
+ nr -= 16;
+ }
+
+ val = readw(reg);
+ if (enable)
+ val &= ~(1 << nr);
+ else
+ val |= (1 << nr);
+ writew(val, reg);
+}
+
+static void set_default_priorities(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(default_irq_prio); i++) {
+ uint16_t val;
+ uint8_t prio = default_irq_prio[i];
+ if (prio > 31)
+ prio = 31;
+
+ val = readw(IRQ_REG(ILR_IRQ(i)));
+ val &= ~(0x1f << 2);
+ val |= prio << 2;
+
+ /* Make edge mode default. Hopefully causes less trouble */
+ val |= 0x02;
+
+ writew(val, IRQ_REG(ILR_IRQ(i)));
+ }
+}
+
+/* Install the exception handlers to where the ROM loader jumps */
+static void calypso_exceptions_install(void)
+{
+ uint32_t *exceptions_dst = (uint32_t *) BASE_ADDR_IBOOT_EXC;
+ uint32_t *exceptions_src = &_exceptions;
+ int i;
+
+ for (i = 0; i < 7; i++)
+ *exceptions_dst++ = *exceptions_src++;
+
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_irqinitialize
+ *
+ * Description:
+ * Setup the IRQ and FIQ controllers
+ *
+ ****************************************************************************/
+
+void up_irqinitialize(void)
+{
+ /* Prepare hardware */
+ calypso_exceptions_install();
+ current_regs = NULL;
+
+ /* Switch to internal ROM */
+ calypso_bootrom(1);
+
+ /* set default priorities */
+ set_default_priorities();
+
+ /* mask all interrupts off */
+ writew(0xffff, IRQ_REG(MASK_IT_REG1));
+ writew(0xffff, IRQ_REG(MASK_IT_REG2));
+
+ /* clear all pending interrupts */
+ writew(0, IRQ_REG(IT_REG1));
+ writew(0, IRQ_REG(IT_REG2));
+
+ /* enable interrupts globally to the ARM core */
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+ irqrestore(SVC_MODE | PSR_F_BIT);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ if((unsigned)irq < NR_IRQS)
+ _irq_enable(irq, 0);
+}
+
+/****************************************************************************
+ * Name: up_enable_irq
+ *
+ * Description:
+ * Enable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_enable_irq(int irq)
+{
+ if((unsigned)irq < NR_IRQS)
+ _irq_enable(irq, 1);
+}
+
+/****************************************************************************
+ * Name: up_prioritize_irq
+ *
+ * Description:
+ * Set the priority of an IRQ.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_IRQPRIO
+int up_prioritize_irq(int nr, int prio)
+{
+ uint16_t val;
+
+ if (prio == -1)
+ prio = default_irq_prio[nr];
+
+ if (prio > 31)
+ prio = 31;
+
+ val = prio << 2;
+ writew(val, IRQ_REG(ILR_IRQ(nr)));
+
+ return 0; // XXX: what's the return???
+}
+#endif
+
+/****************************************************************************
+ * Entry point for interrupts
+ ****************************************************************************/
+
+void up_decodeirq(uint32_t *regs)
+{
+ uint8_t num, tmp;
+ uint32_t *saved_regs;
+
+ /* XXX: What is this???
+ * Passed to but ignored in IRQ handlers
+ * Only valid meaning is apparently non-NULL == IRQ context */
+ saved_regs = (uint32_t *)current_regs;
+ current_regs = regs;
+
+ /* Detect & deliver the IRQ */
+ num = readb(IRQ_REG(IRQ_NUM)) & 0x1f;
+ irq_dispatch(num, regs);
+
+ /* Start new IRQ agreement */
+ tmp = readb(IRQ_REG(IRQ_CTRL));
+ tmp |= 0x01;
+ writeb(tmp, IRQ_REG(IRQ_CTRL));
+
+ current_regs = saved_regs;
+}
+
+/****************************************************************************
+ * Entry point for FIQs
+ ****************************************************************************/
+
+void calypso_fiq(void)
+{
+ uint8_t num, tmp;
+ uint32_t *regs;
+
+ /* XXX: What is this???
+ * Passed to but ignored in IRQ handlers
+ * Only valid meaning is apparently non-NULL == IRQ context */
+ regs = (uint32_t *)current_regs;
+ current_regs = (uint32_t *)&num;
+
+ /* Detect & deliver like an IRQ but we are in FIQ context */
+ num = readb(IRQ_REG(FIQ_NUM)) & 0x1f;
+ irq_dispatch(num, regs);
+
+ /* Start new FIQ agreement */
+ tmp = readb(IRQ_REG(IRQ_CTRL));
+ tmp |= 0x02;
+ writeb(tmp, IRQ_REG(IRQ_CTRL));
+
+ current_regs = regs;
+}
diff --git a/nuttx/arch/arm/src/calypso/calypso_lowputc.S b/nuttx/arch/arm/src/calypso/calypso_lowputc.S
new file mode 100644
index 000000000..951ea03d5
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_lowputc.S
@@ -0,0 +1,133 @@
+/**************************************************************************
+ * calypso/calypso_lowputc.S
+ *
+ * Copyright (C) 2011 Stefan Richter. All rights reserved.
+ * Author: Stefan Richter <ichgeh@l--putt.de>
+ *
+ * based on: c5471/c5471_lowputc.S
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/**************************************************************************
+ * Included Files
+ **************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Functions
+ **************************************************************************/
+
+/**************************************************************************
+ * Public Functions
+ **************************************************************************/
+
+/**************************************************************************
+ * Name: up_lowputc
+ **************************************************************************/
+
+/* This assembly language version has the advantage that it can does not
+ * require a C stack and uses only r0-r1. Hence it can be used during
+ * early boot phases.
+ */
+
+ .text
+ .global up_lowputc
+ .type up_lowputc, function
+up_lowputc:
+ /* On entry, r0 holds the character to be printed */
+
+#ifdef CONFIG_SERIAL_IRDA_CONSOLE
+ ldr r2, =UART_IRDA_BASE /* r2=IRDA UART base */
+#else
+ ldr r2, =UART_MODEM_BASE /* r2=Modem UART base */
+#endif
+
+ /* Poll bit 0 of the UART_SSR register. When the bit
+ * is clear, the TX FIFO is no longer full
+ */
+
+1: ldrb r1, [r2, #UART_SSR_OFFS]
+ tst r1, #UART_SSR_TXFULL
+ bne 1b
+
+ /* Send the character by writing it into the UART_THR
+ * register.
+ */
+
+ strb r0, [r2, #UART_THR_OFFS]
+
+ /* Wait for the tranmsit holding regiser (THR) to be
+ * emptied. This is detemined when bit 6 of the LSR
+ * is set.
+ */
+
+2: ldrb r1, [r2, #UART_LSR_OFFS]
+ tst r1, #0x00000020
+ beq 2b
+
+ /* If the character that we just sent was a linefeed,
+ * then send a carriage return as well.
+ */
+
+ teq r0, #'\n'
+ moveq r0, #'\r'
+ beq 1b
+
+ /* And return */
+
+ mov pc, lr
+
diff --git a/nuttx/arch/arm/src/calypso/calypso_serial.c b/nuttx/arch/arm/src/calypso/calypso_serial.c
new file mode 100644
index 000000000..e64743ae1
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_serial.c
@@ -0,0 +1,964 @@
+/****************************************************************************
+ * calypso/calypso_serial.c
+ *
+ * Copyright (C) 2011 Stefan Richter. All rights reserved.
+ * Author: Stefan Richter <ichgeh@l--putt.de>
+ *
+ * based on c5471/c5471_serial.c
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <arch/serial.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BASE_BAUD 115200
+
+#if defined(CONFIG_UART_IRDA_HWFLOWCONTROL) || defined(CONFIG_UART_MODEM_HWFLOWCONTROL)
+# define CONFIG_UART_HWFLOWCONTROL
+#endif
+
+#if UART_FCR_OFFS == UART_EFR_OFFS
+# define UART_MULTIPLEX_REGS
+// HW flow control not supported yet
+# undef CONFIG_UART_HWFLOWCONTROL
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct uart_regs_s
+{
+ uint32_t ier;
+ uint32_t lcr;
+ uint32_t fcr;
+#ifdef CONFIG_UART_HWFLOWCONTROL
+ uint32_t efr;
+ uint32_t tcr;
+#endif
+};
+
+struct up_dev_s
+{
+ unsigned int uartbase; /* Base address of UART registers */
+ unsigned int baud_base; /* Base baud for conversions */
+ unsigned int baud; /* Configured baud */
+ uint8_t xmit_fifo_size; /* Size of transmit FIFO */
+ 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) */
+#ifdef CONFIG_UART_HWFLOWCONTROL
+ bool flowcontrol; /* true: Hardware flow control
+ * is enabled. */
+#endif
+ bool stopbits2; /* true: Configure with 2
+ * stop bits instead of 1 */
+ struct uart_regs_s regs; /* Shadow copy of readonly regs */
+
+#ifdef CONFIG_SERCOMM_CONSOLE
+ bool sercomm; /* Call sercomm in interrupt if true */
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int up_setup(struct uart_dev_s *dev);
+static void up_shutdown(struct uart_dev_s *dev);
+static int up_attach(struct uart_dev_s *dev);
+static void up_detach(struct uart_dev_s *dev);
+static int up_interrupt(int irq, void *context);
+static int up_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int up_receive(struct uart_dev_s *dev, unsigned int *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+static void up_send(struct uart_dev_s *dev, int ch);
+static void up_txint(struct uart_dev_s *dev, bool enable);
+static bool up_txready(struct uart_dev_s *dev);
+static bool up_txempty(struct uart_dev_s *dev);
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+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,
+ .send = up_send,
+ .txint = up_txint,
+ .txready = up_txready,
+ .txempty = up_txempty,
+};
+
+/* I/O buffers */
+
+static char g_irdarxbuffer[CONFIG_UART_IRDA_RXBUFSIZE];
+static char g_irdatxbuffer[CONFIG_UART_IRDA_TXBUFSIZE];
+static char g_modemrxbuffer[CONFIG_UART_MODEM_RXBUFSIZE];
+static char g_modemtxbuffer[CONFIG_UART_MODEM_TXBUFSIZE];
+
+/* This describes the state of the C5471 serial IRDA port. */
+
+static struct up_dev_s g_irdapriv =
+{
+ .xmit_fifo_size = UART_IRDA_XMIT_FIFO_SIZE,
+ .baud_base = BASE_BAUD,
+ .uartbase = UART_IRDA_BASE,
+ .baud = CONFIG_UART_IRDA_BAUD,
+ .irq = UART_IRQ_IRDA,
+ .parity = CONFIG_UART_IRDA_PARITY,
+ .bits = CONFIG_UART_IRDA_BITS,
+#ifdef CONFIG_UART_IRDA_HWFLOWCONTROL
+ .flowcontrol = true,
+#endif
+ .stopbits2 = CONFIG_UART_IRDA_2STOP,
+
+#ifdef CONFIG_SERCOMM_CONSOLE
+ .sercomm = false,
+#endif
+};
+
+static uart_dev_t g_irdaport =
+{
+ .recv =
+ {
+ .size = CONFIG_UART_IRDA_RXBUFSIZE,
+ .buffer = g_irdarxbuffer,
+ },
+ .xmit =
+ {
+ .size = CONFIG_UART_IRDA_TXBUFSIZE,
+ .buffer = g_irdatxbuffer,
+ },
+ .ops = &g_uart_ops,
+ .priv = &g_irdapriv,
+};
+
+/* This describes the state of the C5471 serial Modem port. */
+
+static struct up_dev_s g_modempriv =
+{
+ .xmit_fifo_size = UART_XMIT_FIFO_SIZE,
+ .baud_base = BASE_BAUD,
+ .uartbase = UART_MODEM_BASE,
+ .baud = CONFIG_UART_MODEM_BAUD,
+ .irq = UART_IRQ_MODEM,
+ .parity = CONFIG_UART_MODEM_PARITY,
+ .bits = CONFIG_UART_MODEM_BITS,
+#ifdef CONFIG_UART_MODEM_HWFLOWCONTROL
+ .flowcontrol = true,
+#endif
+ .stopbits2 = CONFIG_UART_MODEM_2STOP,
+
+#ifdef CONFIG_SERCOMM_CONSOLE
+ .sercomm = false,
+#endif
+};
+
+static uart_dev_t g_modemport =
+{
+ .recv =
+ {
+ .size = CONFIG_UART_MODEM_RXBUFSIZE,
+ .buffer = g_modemrxbuffer,
+ },
+ .xmit =
+ {
+ .size = CONFIG_UART_MODEM_TXBUFSIZE,
+ .buffer = g_modemtxbuffer,
+ },
+ .ops = &g_uart_ops,
+ .priv = &g_modempriv,
+};
+
+/* Now, which one with be tty0/console and which tty1? */
+
+#ifdef CONFIG_SERIAL_IRDA_CONSOLE
+# define CONSOLE_DEV g_irdaport
+# define TTYS0_DEV g_irdaport
+# define TTYS1_DEV g_modemport
+#else
+# define CONSOLE_DEV g_modemport
+# define TTYS0_DEV g_modemport
+# define TTYS1_DEV g_irdaport
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_inserial
+ ****************************************************************************/
+
+static inline uint32_t up_inserial(struct up_dev_s *priv, uint32_t offset)
+{
+#if UART_REGISTER_BITS == 8
+ return getreg8(priv->uartbase + offset);
+#elif UART_REGISTER_BITS == 32
+ return getreg32(priv->uartbase + offset);
+#else
+#error Unsupported number of bits set in UART_REGISTER_BITS
+#endif
+}
+
+/****************************************************************************
+ * Name: up_serialout
+ ****************************************************************************/
+
+static inline void up_serialout(struct up_dev_s *priv, uint32_t offset, uint32_t value)
+{
+#if UART_REGISTER_BITS == 8
+ putreg8(value & 0xff, priv->uartbase + offset);
+#elif UART_REGISTER_BITS == 32
+ putreg32(value, priv->uartbase + offset);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static inline void up_disableuartint(struct up_dev_s *priv, uint16_t *ier)
+{
+ if (ier)
+ {
+ *ier = priv->regs.ier & UART_IER_INTMASK;
+ }
+ priv->regs.ier &= ~UART_IER_INTMASK;
+ up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
+}
+
+/****************************************************************************
+ * Name: up_restoreuartint
+ ****************************************************************************/
+
+static inline void up_restoreuartint(struct up_dev_s *priv, uint16_t ier)
+{
+ priv->regs.ier |= ier & (UART_IER_RECVINT|UART_IER_XMITINT);
+ up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
+}
+
+/****************************************************************************
+ * Name: up_waittxready
+ ****************************************************************************/
+
+static inline void up_waittxready(struct up_dev_s *priv)
+{
+ int tmp;
+
+ for (tmp = 1000 ; tmp > 0 ; tmp--)
+ {
+ if ((up_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0)
+ {
+ break;
+ }
+ }
+}
+/****************************************************************************
+ * Name: up_disablebreaks
+ ****************************************************************************/
+
+static inline void up_disablebreaks(struct up_dev_s *priv)
+{
+ priv->regs.lcr &= ~UART_LCR_BOC;
+ up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr);
+}
+
+/****************************************************************************
+ * Name: up_enablebreaks
+ ****************************************************************************/
+
+static inline void up_enablebreaks(struct up_dev_s *priv)
+{
+ priv->regs.lcr |= UART_LCR_BOC;
+ up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr);
+}
+
+/****************************************************************************
+ * Name: up_setrate
+ ****************************************************************************/
+
+static inline void up_setrate(struct up_dev_s *priv, unsigned int rate)
+{
+ uint32_t div_bit_rate;
+
+ switch (rate)
+ {
+ case 115200:
+ div_bit_rate = BAUD_115200;
+ break;
+ case 57600:
+ div_bit_rate = BAUD_57600;
+ break;
+ case 38400:
+ div_bit_rate = BAUD_38400;
+ break;
+ case 19200:
+ div_bit_rate = BAUD_19200;
+ break;
+ case 4800:
+ div_bit_rate = BAUD_4800;
+ break;
+ case 2400:
+ div_bit_rate = BAUD_2400;
+ break;
+ case 1200:
+ div_bit_rate = BAUD_1200;
+ break;
+ case 9600:
+ default:
+ div_bit_rate = BAUD_9600;
+ break;
+ }
+
+#if UART_DIV_BIT_RATE_OFFS
+ up_serialout(priv, UART_DIV_BIT_RATE_OFFS, div_bit_rate);
+#else
+ up_serialout(priv, UART_DIV_LOW_OFFS, div_bit_rate);
+ up_serialout(priv, UART_DIV_HIGH_OFFS, div_bit_rate >> 8);
+#endif
+}
+
+/****************************************************************************
+ * 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.
+ *
+ ****************************************************************************/
+#include <stdio.h>
+static int up_setup(struct uart_dev_s *dev)
+{
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+ struct up_dev_s *priv = dev->priv;
+ unsigned int cval;
+
+ if (priv->bits == 7)
+ {
+ cval = UART_LCR_7BITS;
+ }
+ else
+ {
+ cval = UART_LCR_8BITS;
+ }
+
+ if (priv->stopbits2)
+ {
+ cval |= UART_LCR_2STOP;
+ }
+
+ if (priv->parity == 1) /* Odd parity */
+ {
+ cval |= (UART_LCR_PAREN|UART_LCR_PARODD);
+ }
+ else if (priv->parity == 2) /* Even parity */
+ {
+ cval |= (UART_LCR_PAREN|UART_LCR_PAREVEN);
+ }
+
+ /* Both the IrDA and MODEM UARTs support RESET and UART mode. */
+
+ up_serialout(priv, UART_MDR_OFFS, MDR_RESET_MODE);
+ up_serialout(priv, UART_LCR_OFFS, 0xbf);
+ up_serialout(priv, UART_XON1_OFFS, 0x00);
+ up_serialout(priv, UART_XON2_OFFS, 0x00);
+ up_serialout(priv, UART_XOFF1_OFFS, 0x00);
+ up_serialout(priv, UART_XOFF2_OFFS, 0x00);
+ up_serialout(priv, UART_EFR_OFFS, 0x00);
+ up_serialout(priv, UART_LCR_OFFS, 0x00);
+ up_mdelay(5);
+
+ up_serialout(priv, UART_MDR_OFFS, MDR_UART_MODE);
+ up_mdelay(5);
+
+ priv->regs.ier = up_inserial(priv, UART_IER_OFFS);
+ priv->regs.lcr = up_inserial(priv, UART_LCR_OFFS);
+#ifdef CONFIG_UART_HWFLOWCONTROL
+ if (priv->flowcontrol)
+ {
+ priv->regs.efr = up_inserial(priv, UART_EFR_OFFS);
+ priv->regs.tcr = up_inserial(priv, UART_TCR_OFFS);
+ }
+#endif
+
+ up_disableuartint(priv, NULL);
+
+#ifdef UART_MULTIPLEX_REGS
+ up_serialout(priv, UART_LCR_OFFS, 0x00bf);
+#endif
+
+ up_serialout(priv, UART_EFR_OFFS, 0x0010); /* Unprotect enhanced control */
+
+#ifdef UART_MULTIPLEX_REGS
+ priv->regs.lcr = 0x80;
+ up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr);
+ //up_serialout(priv, UART_MCR_OFFS, 1<<4); /* loopback */
+#endif
+
+ up_serialout(priv, UART_TFCR_OFFS, 0); /* Reset to 0 */
+ up_serialout(priv, UART_RFCR_OFFS, UART_FCR_RX_CLR); /* Clear RX fifo */
+ up_serialout(priv, UART_TFCR_OFFS, UART_FCR_TX_CLR); /* Clear TX fifo */
+ priv->regs.fcr = UART_FCR_FIFO_EN;
+ up_serialout(priv, UART_TFCR_OFFS, priv->regs.fcr); /* Enable RX/TX fifos */
+
+ up_disablebreaks(priv);
+
+ /* Set the RX and TX trigger levels to the minimum */
+
+ priv->regs.fcr = (priv->regs.fcr & 0xffffff0f) | UART_FCR_FTL;
+ up_serialout(priv, UART_RFCR_OFFS, priv->regs.fcr);
+
+ up_setrate(priv, priv->baud);
+
+#ifdef UART_MULTIPLEX_REGS
+ up_serialout(priv, UART_SCR_OFFS, 1); /* Disable DMA */
+ priv->regs.lcr = (uint32_t)cval; /* Configure mode, return to THR/RHR */
+#else
+ priv->regs.lcr &= 0xffffffe0; /* clear original field, and... */
+ priv->regs.lcr |= (uint32_t)cval; /* Set new bits in that field. */
+#endif
+ up_serialout(priv, UART_LCR_OFFS, priv->regs.lcr);
+
+#ifdef CONFIG_UART_HWFLOWCONTROL
+ if (priv->flowcontrol)
+ {
+ /* Set the FIFO level triggers for flow control
+ * Halt = 48 bytes, resume = 12 bytes
+ */
+
+ priv->regs.tcr = (priv->regs.tcr & 0xffffff00) | 0x0000003c;
+ up_serialout(priv, UART_TCR_OFFS, priv->regs.tcr);
+
+ /* Enable RTS/CTS flow control */
+
+ priv->regs.efr |= 0x000000c0;
+ up_serialout(priv, UART_EFR_OFFS, priv->regs.efr);
+ }
+ else
+ {
+ /* Disable RTS/CTS flow control */
+
+ priv->regs.efr &= 0xffffff3f;
+ up_serialout(priv, UART_EFR_OFFS, priv->regs.efr);
+ }
+#endif
+#endif
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_shutdown
+ *
+ * Description:
+ * Disable the UART. This method is called when the serial port is closed
+ *
+ ****************************************************************************/
+
+static void up_shutdown(struct uart_dev_s *dev)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv;
+ up_disableuartint(priv, NULL);
+}
+
+/****************************************************************************
+ * 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(struct uart_dev_s *dev)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ int ret;
+
+ /* Attach and enable the IRQ */
+
+ ret = irq_attach(priv->irq, up_interrupt);
+ 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(struct uart_dev_s *dev)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ up_disable_irq(priv->irq);
+ irq_detach(priv->irq);
+}
+
+/****************************************************************************
+ * 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 approprite
+ * uart_dev_s structure in order to call these functions.
+ *
+ ****************************************************************************/
+
+static int up_interrupt(int irq, void *context)
+{
+ struct uart_dev_s *dev = NULL;
+ struct up_dev_s *priv;
+ volatile uint32_t cause;
+
+ if (g_irdapriv.irq == irq)
+ {
+ dev = &g_irdaport;
+ }
+ else if (g_modempriv.irq == irq)
+ {
+ dev = &g_modemport;
+ }
+ else
+ {
+ PANIC(OSERR_INTERNAL);
+ }
+ priv = (struct up_dev_s*)dev->priv;
+
+ cause = up_inserial(priv, UART_ISR_OFFS) & 0x0000003f;
+
+ if ((cause & 0x0000000c) == 0x0000000c)
+ {
+ uint32_t ier_val = 0;
+
+ /* Is this an interrupt from the IrDA UART? */
+
+ if (irq == UART_IRQ_IRDA)
+ {
+ /* Save the currently enabled IrDA UART interrupts
+ * so that we can restore the IrDA interrupt state
+ * below.
+ */
+
+ ier_val = up_inserial(priv, UART_IER_OFFS);
+
+ /* Then disable all IrDA UART interrupts */
+
+ up_serialout(priv, UART_IER_OFFS, 0);
+ }
+
+ /* Receive characters from the RX fifo */
+
+#ifdef CONFIG_SERCOMM_CONSOLE
+ if (priv->sercomm)
+ {
+ sercomm_recvchars(dev);
+ }
+ else
+#endif
+ {
+ uart_recvchars(dev);
+ }
+
+ /* read UART_RHR to clear int condition
+ * toss = up_inserialchar(priv,&status);
+ */
+
+ /* Is this an interrupt from the IrDA UART? */
+
+ if (irq == UART_IRQ_IRDA)
+ {
+ /* Restore the IrDA UART interrupt enables */
+
+ up_serialout(priv, UART_IER_OFFS, ier_val);
+ }
+ }
+ else if ((cause & 0x0000000c) == 0x00000004)
+ {
+#ifdef CONFIG_SERCOMM_CONSOLE
+ if (priv->sercomm)
+ {
+ sercomm_recvchars(dev);
+ }
+ else
+#endif
+ {
+ uart_recvchars(dev);
+ }
+ }
+
+ if ((cause & 0x00000002) != 0)
+ {
+#ifdef CONFIG_SERCOMM_CONSOLE
+ if (priv->sercomm)
+ {
+ sercomm_xmitchars(dev);
+ }
+ else
+#endif
+ {
+ uart_xmitchars(dev);
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_ioctl
+ *
+ * Description:
+ * All ioctl calls will be routed through this method
+ *
+ ****************************************************************************/
+
+static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+ struct inode *inode = filep->f_inode;
+ struct uart_dev_s *dev = inode->i_private;
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ int ret = OK;
+
+ switch (cmd)
+ {
+ case TIOCSERGSTRUCT:
+ {
+ struct up_dev_s *user = (struct up_dev_s*)arg;
+ if (!user)
+ {
+ *get_errno_ptr() = EINVAL;
+ ret = ERROR;
+ }
+ else
+ {
+ memcpy(user, dev, sizeof(struct up_dev_s));
+ }
+ }
+ break;
+
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ {
+ irqstate_t flags = irqsave();
+ up_enablebreaks(priv);
+ irqrestore(flags);
+ }
+ break;
+
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ {
+ irqstate_t flags;
+ flags = irqsave();
+ up_disablebreaks(priv);
+ irqrestore(flags);
+ }
+ break;
+
+ default:
+ *get_errno_ptr() = ENOTTY;
+ ret = ERROR;
+ 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
+ * the return 'status'.
+ *
+ ****************************************************************************/
+
+static int up_receive(struct uart_dev_s *dev, unsigned int *status)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ uint32_t rhr;
+ uint32_t lsr;
+
+ /* Construct a 16bit status word that uses the high byte to
+ * hold the status bits associated with framing,parity,break
+ * and a low byte that holds error bits of LSR for
+ * conditions such as overflow, etc.
+ */
+
+ rhr = up_inserial(priv, UART_RHR_OFFS);
+ lsr = up_inserial(priv, UART_LSR_OFFS);
+
+ *status = (unsigned int)((rhr & 0x0000ff00) | (lsr & 0x000000ff));
+
+ return rhr & 0x000000ff;
+}
+
+/****************************************************************************
+ * Name: up_rxint
+ *
+ * Description:
+ * Call to enable or disable RX interrupts
+ *
+ ****************************************************************************/
+
+static void up_rxint(struct uart_dev_s *dev, bool enable)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ if (enable)
+ {
+#ifndef CONFIG_SUPPRESS_SERIAL_INTS
+ priv->regs.ier |= UART_IER_RECVINT;
+ up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
+#endif
+ }
+ else
+ {
+ priv->regs.ier &= ~UART_IER_RECVINT;
+ up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
+ }
+}
+
+/****************************************************************************
+ * Name: up_rxavailable
+ *
+ * Description:
+ * Return true if the receive fifo is not empty
+ *
+ ****************************************************************************/
+
+static bool up_rxavailable(struct uart_dev_s *dev)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ return up_inserial(priv, UART_LSR_OFFS) & UART_RX_FIFO_NOEMPTY;
+}
+
+/****************************************************************************
+ * Name: up_send
+ *
+ * Description:
+ * This method will send one byte on the UART
+ *
+ ****************************************************************************/
+
+static void up_send(struct uart_dev_s *dev, int ch)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ up_serialout(priv, UART_THR_OFFS, (uint8_t)ch);
+}
+
+/****************************************************************************
+ * Name: up_txint
+ *
+ * Description:
+ * Call to enable or disable TX interrupts
+ *
+ ****************************************************************************/
+
+static void up_txint(struct uart_dev_s *dev, bool enable)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ if (enable)
+ {
+#ifndef CONFIG_SUPPRESS_SERIAL_INTS
+ priv->regs.ier |= UART_IER_XMITINT;
+ up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
+#endif
+ }
+ else
+ {
+ priv->regs.ier &= ~UART_IER_XMITINT;
+ up_serialout(priv, UART_IER_OFFS, priv->regs.ier);
+ }
+}
+
+/****************************************************************************
+ * Name: up_txready
+ *
+ * Description:
+ * Return true if the tranmsit fifo is not full
+ *
+ ****************************************************************************/
+
+static bool up_txready(struct uart_dev_s *dev)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ return (up_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0;
+}
+
+/****************************************************************************
+ * Name: up_txempty
+ *
+ * Description:
+ * Return true if the transmit fifo is empty
+ *
+ ****************************************************************************/
+
+static bool up_txempty(struct uart_dev_s *dev)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ return (up_inserial(priv, UART_LSR_OFFS) & UART_LSR_TREF) != 0;
+}
+
+/****************************************************************************
+ * Public Funtions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_earlyserialinit
+ *
+ * Description:
+ * Performs the low level UART initialization early in
+ * debug so that the serial console will be available
+ * during bootup. This must be called before up_serialinit.
+ *
+ ****************************************************************************/
+
+void up_earlyserialinit(void)
+{
+ up_disableuartint(TTYS0_DEV.priv, NULL);
+ up_disableuartint(TTYS1_DEV.priv, NULL);
+
+ CONSOLE_DEV.isconsole = true;
+ up_setup(&CONSOLE_DEV);
+}
+
+/****************************************************************************
+ * Name: up_serialinit
+ *
+ * Description:
+ * Register serial console and serial ports. This assumes
+ * that up_earlyserialinit was called previously.
+ *
+ ****************************************************************************/
+
+void up_serialinit(void)
+{
+#ifdef CONFIG_SERCOMM_CONSOLE
+ ((struct up_dev_s*)TTYS0_DEV.priv)->sercomm = true;
+ (void)sercomm_register("/dev/console", &TTYS0_DEV);
+ (void)uart_register("/dev/ttyS0", &TTYS1_DEV);
+#else
+ (void)uart_register("/dev/console", &CONSOLE_DEV);
+ (void)uart_register("/dev/ttyS0", &TTYS0_DEV);
+ (void)uart_register("/dev/ttyS1", &TTYS1_DEV);
+#endif
+}
+
+/****************************************************************************
+ * Name: up_putc
+ *
+ * Description:
+ * Provide priority, low-level access to support OS debug
+ * writes
+ *
+ ****************************************************************************/
+
+int up_putc(int ch)
+{
+ struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv;
+ uint16_t ier;
+
+ up_disableuartint(priv, &ier);
+ up_waittxready(priv);
+ up_serialout(priv, UART_THR_OFFS, (uint8_t)ch);
+
+ /* Check for LF */
+
+ if (ch == '\n')
+ {
+ /* Add CR */
+
+ up_waittxready(priv);
+ up_serialout(priv, UART_THR_OFFS, '\r');
+ }
+
+ up_waittxready(priv);
+ up_restoreuartint(priv, ier);
+ return ch;
+}
+
diff --git a/nuttx/arch/arm/src/calypso/calypso_timer.c b/nuttx/arch/arm/src/calypso/calypso_timer.c
new file mode 100644
index 000000000..e42b95d14
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/calypso_timer.c
@@ -0,0 +1,206 @@
+/****************************************************************************
+ * arch/arm/src/calypso/calypso_timer.c
+ * Calypso DBB internal Timer Driver
+ *
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2011 by Stefan Richter <ichgeh@l--putt.de>
+ *
+ * This source code is derivated from Osmocom-BB project and was
+ * relicensed as BSD with permission from original authors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <nuttx/arch.h>
+
+#include <arch/calypso/defines.h>
+#include <arch/calypso/memory.h>
+#include <arch/calypso/timer.h>
+
+
+#define BASE_ADDR_TIMER 0xfffe3800
+#define TIMER2_OFFSET 0x3000
+
+#define TIMER_REG(n, m) (((n)-1) ? (BASE_ADDR_TIMER + TIMER2_OFFSET + (m)) : (BASE_ADDR_TIMER + (m)))
+
+enum timer_reg {
+ CNTL_TIMER = 0x00,
+ LOAD_TIMER = 0x02,
+ READ_TIMER = 0x04,
+};
+
+enum timer_ctl {
+ CNTL_START = (1 << 0),
+ CNTL_AUTO_RELOAD = (1 << 1),
+ CNTL_CLOCK_ENABLE = (1 << 5),
+};
+
+/* Regular Timers (1 and 2) */
+
+void hwtimer_enable(int num, int on)
+{
+ uint8_t ctl;
+
+ if (num < 1 || num > 2) {
+ printf("Unknown timer %u\n", num);
+ return;
+ }
+
+ ctl = readb(TIMER_REG(num, CNTL_TIMER));
+ if (on)
+ ctl |= CNTL_START|CNTL_CLOCK_ENABLE;
+ else
+ ctl &= ~CNTL_START;
+ writeb(ctl, TIMER_REG(num, CNTL_TIMER));
+}
+
+void hwtimer_config(int num, uint8_t pre_scale, int auto_reload)
+{
+ uint8_t ctl;
+
+ ctl = (pre_scale & 0x7) << 2;
+ if (auto_reload)
+ ctl |= CNTL_AUTO_RELOAD;
+
+ writeb(ctl, TIMER_REG(num, CNTL_TIMER));
+}
+
+void hwtimer_load(int num, uint16_t val)
+{
+ writew(val, TIMER_REG(num, LOAD_TIMER));
+}
+
+uint16_t hwtimer_read(int num)
+{
+ uint8_t ctl = readb(TIMER_REG(num, CNTL_TIMER));
+
+ /* somehow a read results in an abort */
+ if ((ctl & (CNTL_START|CNTL_CLOCK_ENABLE)) != (CNTL_START|CNTL_CLOCK_ENABLE))
+ return 0xFFFF;
+ return readw(TIMER_REG(num, READ_TIMER));
+}
+
+/************************************************************
+ * Watchdog Timer
+ ************************************************************/
+
+#define BASE_ADDR_WDOG 0xfffff800
+#define WDOG_REG(m) (BASE_ADDR_WDOG + m)
+
+enum wdog_reg {
+ WD_CNTL_TIMER = CNTL_TIMER,
+ WD_LOAD_TIMER = LOAD_TIMER,
+ WD_READ_TIMER = 0x02,
+ WD_MODE = 0x04,
+};
+
+enum wdog_ctl {
+ WD_CTL_START = (1 << 7),
+ WD_CTL_AUTO_RELOAD = (1 << 8)
+};
+
+enum wdog_mode {
+ WD_MODE_DIS_ARM = 0xF5,
+ WD_MODE_DIS_CONFIRM = 0xA0,
+ WD_MODE_ENABLE = (1 << 15)
+};
+
+#define WD_CTL_PRESCALE(value) (((value)&0x07) << 9)
+
+static void wdog_irq(__unused enum irq_nr nr)
+{
+ puts("=> WATCHDOG\n");
+}
+
+void wdog_enable(int on)
+{
+ if (!on) {
+ writew(WD_MODE_DIS_ARM, WDOG_REG(WD_MODE));
+ writew(WD_MODE_DIS_CONFIRM, WDOG_REG(WD_MODE));
+ }
+}
+
+void wdog_reset(void)
+{
+ // enable watchdog
+ writew(WD_MODE_ENABLE, WDOG_REG(WD_MODE));
+ // force expiration
+ writew(0x0000, WDOG_REG(WD_LOAD_TIMER));
+ writew(0x0000, WDOG_REG(WD_LOAD_TIMER));
+}
+
+/************************************************************
+ * Global Functions
+ ************************************************************/
+
+/************************************************************
+ * Function: up_timerisr
+ *
+ * Description:
+ * The timer ISR will perform a variety of services for
+ * various portions of the systems.
+ *
+ ************************************************************/
+
+int up_timerisr(int irq, uint32_t *regs)
+{
+ /* Process timer interrupt */
+
+ sched_process_timer();
+ return 0;
+}
+
+/************************************************************
+ * Function: up_timerinit
+ *
+ * Description:
+ * Setup Calypso HW timer 2 to cause system ticks.
+ *
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ************************************************************/
+
+void up_timerinit(void)
+{
+ up_disable_irq(IRQ_SYSTIMER);
+
+ /* The timer runs at 13MHz / 32, i.e. 406.25kHz */
+ /* 4062 ticks until expiry yields 100Hz interrupt */
+ hwtimer_load(2, 4062);
+ hwtimer_config(2, 0, 1);
+ hwtimer_enable(2, 1);
+
+ /* Attach and enable the timer interrupt */
+ irq_attach(IRQ_SYSTIMER, (xcpt_t)up_timerisr);
+ up_enable_irq(IRQ_SYSTIMER);
+}
+
diff --git a/nuttx/arch/arm/src/calypso/chip.h b/nuttx/arch/arm/src/calypso/chip.h
new file mode 100644
index 000000000..d190dbc22
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/chip.h
@@ -0,0 +1,211 @@
+/****************************************************************************
+ * calypso/chip.h
+ *
+ * Copyright (C) 2011 Stefan Richter. All rights reserved.
+ * Author: Stefan Richter <ichgeh@l--putt.de>
+ *
+ * based on: c5471/chip.h
+ * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 Gregory Nutt 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 __CALYPSO_CHIP_H
+#define __CALYPSO_CHIP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* UARTs ********************************************************************/
+
+#define UART_IRDA_BASE 0xffff5000
+#define UART_MODEM_BASE 0xffff5800
+#define UART_UIR 0xffff6000
+#define UARTn_IO_RANGE 0x00000800
+
+/* Common UART Registers. Expressed as offsets from the BASE address */
+
+#define UART_RHR_OFFS 0x00000000 /* Rcv Holding Register */
+#define UART_THR_OFFS 0x00000000 /* Xmit Holding Register */
+#define UART_FCR_OFFS 0x00000002 /* FIFO Control Register */
+#define UART_RFCR_OFFS 0x00000002 /* Rcv FIFO Control Register */
+#define UART_TFCR_OFFS 0x00000002 /* Xmit FIFO Control Register */
+#define UART_SCR_OFFS 0x00000010 /* Status Control Register */
+#define UART_LCR_OFFS 0x00000003 /* Line Control Register */
+#define UART_LSR_OFFS 0x00000005 /* Line Status Register */
+#define UART_SSR_OFFS 0x00000011 /* Supplementary Status Register */
+#define UART_MCR_OFFS 0x00000004 /* Modem Control Register */
+#define UART_MSR_OFFS 0x00000006 /* Modem Status Register */
+#define UART_IER_OFFS 0x00000001 /* Interrupt Enable Register */
+#define UART_ISR_OFFS 0x00000002 /* Interrupt Status Register */
+#define UART_EFR_OFFS 0x00000002 /* Enhanced Feature Register */
+#define UART_XON1_OFFS 0x00000004 /* XON1 Character Register */
+#define UART_XON2_OFFS 0x00000005 /* XON2 Character Register */
+#define UART_XOFF1_OFFS 0x00000006 /* XOFF1 Character Register */
+#define UART_XOFF2_OFFS 0x00000007 /* XOFF2 Character Register */
+#define UART_SPR_OFFS 0x00000007 /* Scratch-pad Register */
+#define UART_DIV_LOW_OFFS 0x00000000 /* Divisor for baud generation */
+#define UART_DIV_HIGH_OFFS 0x00000001
+#define UART_TCR_OFFS 0x00000006 /* Transmission Control Register */
+#define UART_TLR_OFFS 0x00000007 /* Trigger Level Register */
+#define UART_MDR_OFFS 0x00000008 /* Mode Definition Register */
+
+/* UART Settings ************************************************************/
+
+/* Miscellaneous UART settings. */
+
+#define UART_REGISTER_BITS 8
+#define UART_IRQ_MODEM IRQ_UART_MODEM
+#define UART_IRQ_IRDA IRQ_UART_IRDA
+
+#define UART_RX_FIFO_NOEMPTY 0x00000001
+#define UART_SSR_TXFULL 0x00000001
+#define UART_LSR_TREF 0x00000020
+
+#define UART_XMIT_FIFO_SIZE 64
+#define UART_IRDA_XMIT_FIFO_SIZE 64
+
+/* UART_LCR Register */
+ /* Bits 31-7: Reserved */
+#define UART_LCR_BOC 0x00000040 /* Bit 6: Break Control */
+ /* Bit 5: Parity Type 2 */
+#define UART_LCR_PAREVEN 0x00000010 /* Bit 4: Parity Type 1 */
+#define UART_LCR_PARODD 0x00000000
+#define UART_LCR_PARMARK 0x00000010
+#define UART_LCR_PARSPACE 0x00000011
+#define UART_LCR_PAREN 0x00000008 /* Bit 3: Paity Enable */
+#define UART_LCR_PARDIS 0x00000000
+#define UART_LCR_2STOP 0x00000004 /* Bit 2: Number of stop bits */
+#define UART_LCR_1STOP 0x00000000
+#define UART_LCR_5BITS 0x00000000 /* Bits 0-1: Word-length */
+#define UART_LCR_6BITS 0x00000001
+#define UART_LCR_7BITS 0x00000002
+#define UART_LCR_8BITS 0x00000003
+
+#define UART_FCR_FTL 0x000000f0
+#define UART_FCR_FIFO_EN 0x00000001
+#define UART_FCR_TX_CLR 0x00000002
+#define UART_FCR_RX_CLR 0x00000004
+
+#define UART_IER_RECVINT 0x00000001
+#define UART_IER_XMITINT 0x00000002
+#define UART_IER_LINESTSINT 0x00000004
+#define UART_IER_MODEMSTSINT 0x00000008 /* IrDA UART only */
+#define UART_IER_XOFFINT 0x00000020
+#define UART_IER_RTSINT 0x00000040 /* IrDA UART only */
+#define UART_IER_CTSINT 0x00000080 /* IrDA UART only */
+#define UART_IER_INTMASK 0x000000ff
+
+#define BAUD_115200 0x00000007
+#define BAUD_57600 0x00000014
+#define BAUD_38400 0x00000021
+#define BAUD_19200 0x00000006
+#define BAUD_9600 0x0000000C
+#define BAUD_4800 0x00000018
+#define BAUD_2400 0x00000030
+#define BAUD_1200 0x00000060
+
+#define MDR_UART_MODE 0x00000000 /* Both IrDA and Modem UARTs */
+#define MDR_SIR_MODE 0x00000001 /* IrDA UART only */
+#define MDR_AUTOBAUDING_MODE 0x00000002 /* Modem UART only */
+#define MDR_RESET_MODE 0x00000007 /* Both IrDA and Modem UARTs */
+
+/* SPI **********************************************************************/
+
+#define MAX_SPI 3
+
+#define SPI_REGISTER_BASE 0xffff2000
+
+/* ARMIO ********************************************************************/
+/* Timers / Watchdog ********************************************************/
+
+#define C5471_TIMER0_CTRL 0xffff2a00
+#define C5471_TIMER0_CNT 0xffff2a04
+#define C5471_TIMER1_CTRL 0xffff2b00
+#define C5471_TIMER1_CNT 0xffff2b04
+#define C5471_TIMER2_CTRL 0xffff2c00
+#define C5471_TIMER2_CNT 0xffff2c04
+
+/* Interrupts ***************************************************************/
+
+#define HAVE_SRC_IRQ_BIN_REG 0
+
+#define INT_FIRST_IO 0xffff2d00
+#define INT_IO_RANGE 0x5C
+
+#define IT_REG 0xffff2d00
+#define MASK_IT_REG 0xffff2d04
+#define SRC_IRQ_REG 0xffff2d08
+#define SRC_FIQ_REG 0xffff2d0c
+#define SRC_IRQ_BIN_REG 0xffff2d10
+#define INT_CTRL_REG 0xffff2d18
+
+#define ILR_IRQ0_REG 0xffff2d1C /* 0-Timer 0 */
+#define ILR_IRQ1_REG 0xffff2d20 /* 1-Timer 1 */
+#define ILR_IRQ2_REG 0xffff2d24 /* 2-Timer 2 */
+#define ILR_IRQ3_REG 0xffff2d28 /* 3-GPIO0 */
+#define ILR_IRQ4_REG 0xffff2d2c /* 4-Ethernet */
+#define ILR_IRQ5_REG 0xffff2d30 /* 5-KBGPIO[7:0] */
+#define ILR_IRQ6_REG 0xffff2d34 /* 6-Uart serial */
+#define ILR_IRQ7_REG 0xffff2d38 /* 7-Uart IRDA */
+#define ILR_IRQ8_REG 0xffff2d3c /* 8-KBGPIO[15:8] */
+#define ILR_IRQ9_REG 0xffff2d40 /* 9-GPIO3 */
+#define ILR_IRQ10_REG 0xffff2d44 /* 10-GPIO2 */
+#define ILR_IRQ11_REG 0xffff2d48 /* 11-I2C */
+#define ILR_IRQ12_REG 0xffff2d4c /* 12-GPIO1 */
+#define ILR_IRQ13_REG 0xffff2d50 /* 13-SPI */
+#define ILR_IRQ14_REG 0xffff2d54 /* 14-GPIO[19:4] */
+#define ILR_IRQ15_REG 0xffff2d58 /* 15-API */
+
+/* CLKM *********************************************************************/
+
+#define CLKM 0xffff2f00
+#define CLKM_CTL_RST 0xffff2f10
+#define CLKM_RESET 0xffff2f18
+
+#define CLKM_RESET_EIM 0x00000008
+#define CLKM_EIM_CLK_STOP 0x00000010
+#define CLKM_CTL_RST_LEAD_RESET 0x00000000
+#define CLKM_CTL_RST_EXT_RESET 0x00000002
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#endif /* __CALYPSO_CHIP_H */
diff --git a/nuttx/arch/arm/src/calypso/clock.c b/nuttx/arch/arm/src/calypso/clock.c
new file mode 100644
index 000000000..f2f36fbec
--- /dev/null
+++ b/nuttx/arch/arm/src/calypso/clock.c
@@ -0,0 +1,218 @@
+/****************************************************************************
+ * arch/arm/src/calypso/clock.c
+ * Driver for Calypso clock management
+ *
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * This source code is derivated from Osmocom-BB project and was
+ * relicensed as BSD with permission from original authors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdio.h>
+
+//#define DEBUG
+#include <arch/calypso/debug.h>
+
+#include <arch/calypso/memory.h>
+#include <arch/calypso/clock.h>
+
+#define REG_DPLL 0xffff9800
+#define DPLL_LOCK (1 << 0)
+#define DPLL_BREAKLN (1 << 1)
+#define DPLL_BYPASS_DIV_SHIFT 2 /* 2 bits */
+#define DPLL_PLL_ENABLE (1 << 4)
+#define DPLL_PLL_DIV_SHIFT 5 /* 2 bits */
+#define DPLL_PLL_MULT_SHIFT 7 /* 5 bits */
+#define DPLL_TEST (1 << 12)
+#define DPLL_IOB (1 << 13) /* Initialize on break */
+#define DPLL_IAI (1 << 14) /* Initialize after Idle */
+
+#define BASE_ADDR_CLKM 0xfffffd00
+#define CLKM_REG(m) (BASE_ADDR_CLKM+(m))
+
+enum clkm_reg {
+ CNTL_ARM_CLK = 0,
+ CNTL_CLK = 2,
+ CNTL_RST = 4,
+ CNTL_ARM_DIV = 8,
+};
+
+/* CNTL_ARM_CLK */
+#define ARM_CLK_BIG_SLEEP (1 << 0) /* MCU Master Clock enabled? */
+#define ARM_CLK_CLKIN_SEL0 (1 << 1) /* MCU source clock (0 = DPLL output, 1 = VTCXO or CLKIN */
+#define ARM_CLK_CLKIN_SEL (1 << 2) /* 0 = VTCXO or 1 = CLKIN */
+#define ARM_CLK_MCLK_DIV5 (1 << 3) /* enable 1.5 or 2.5 division factor */
+#define ARM_CLK_MCLK_DIV_SHIFT 4 /* 3 bits */
+#define ARM_CLK_DEEP_POWER_SHIFT 8
+#define ARM_CLK_DEEP_SLEEP 12
+
+/* CNTL_CLK */
+#define CLK_IRQ_CLK_DIS (1 << 0) /* IRQ clock control (0 always, 1 according ARM_MCLK_EN) */
+#define CLK_BRIDGE_CLK_DIS (1 << 1)
+#define CLK_TIMER_CLK_DIS (1 << 2)
+#define CLK_DPLL_DIS (1 << 3) /* 0: DPLL is not stopped during SLEEP */
+#define CLK_CLKOUT_EN (1 << 4) /* Enable CLKOUT output pins */
+#define CLK_EN_IDLE3_FLG (1 << 5) /* DSP idle flag control (1 =
+ * SAM/HOM register forced to HOM when DSP IDLE3) */
+#define CLK_VCLKOUT_DIV2 (1 << 6) /* 1: VCLKOUT-FR is divided by 2 */
+#define CLK_VTCXO_DIV2 (1 << 7) /* 1: VTCXO is dividied by 2 */
+
+#define BASE_ADDR_MEMIF 0xfffffb00
+#define MEMIF_REG(x) (BASE_ADDR_MEMIF+(x))
+
+enum memif_reg {
+ API_RHEA_CTL = 0x0e,
+ EXTRA_CONF = 0x10,
+};
+
+static void dump_reg16(uint32_t addr, char *name)
+{
+ printf("%s=0x%04x\n", name, readw(addr));
+}
+
+void calypso_clk_dump(void)
+{
+ dump_reg16(REG_DPLL, "REG_DPLL");
+ dump_reg16(CLKM_REG(CNTL_ARM_CLK), "CNTL_ARM_CLK");
+ dump_reg16(CLKM_REG(CNTL_CLK), "CNTL_CLK");
+ dump_reg16(CLKM_REG(CNTL_RST), "CNTL_RST");
+ dump_reg16(CLKM_REG(CNTL_ARM_DIV), "CNTL_ARM_DIV");
+}
+
+void calypso_pll_set(uint16_t inp)
+{
+ uint8_t mult = inp >> 8;
+ uint8_t div = inp & 0xff;
+ uint16_t reg = readw(REG_DPLL);
+
+ reg &= ~0x0fe0;
+ reg |= (div & 0x3) << DPLL_PLL_DIV_SHIFT;
+ reg |= (mult & 0x1f) << DPLL_PLL_MULT_SHIFT;
+ reg |= DPLL_PLL_ENABLE;
+
+ writew(reg, REG_DPLL);
+}
+
+void calypso_reset_set(enum calypso_rst calypso_rst, int active)
+{
+ uint8_t reg = readb(CLKM_REG(CNTL_RST));
+
+ if (active)
+ reg |= calypso_rst;
+ else
+ reg &= ~calypso_rst;
+
+ writeb(reg, CLKM_REG(CNTL_RST));
+}
+
+int calypso_reset_get(enum calypso_rst calypso_rst)
+{
+ uint8_t reg = readb(CLKM_REG(CNTL_RST));
+
+ if (reg & calypso_rst)
+ return 1;
+ else
+ return 0;
+}
+
+void calypso_clock_set(uint8_t vtcxo_div2, uint16_t inp, enum mclk_div mclk_div)
+{
+ uint16_t cntl_clock = readw(CLKM_REG(CNTL_CLK));
+ uint16_t cntl_arm_clk = readw(CLKM_REG(CNTL_ARM_CLK));
+
+ /* First set the vtcxo_div2 */
+ cntl_clock &= ~CLK_VCLKOUT_DIV2;
+ if (vtcxo_div2)
+ cntl_clock |= CLK_VTCXO_DIV2;
+ else
+ cntl_clock &= ~CLK_VTCXO_DIV2;
+ writew(cntl_clock, CLKM_REG(CNTL_CLK));
+
+ /* Then configure the MCLK divider */
+ cntl_arm_clk &= ~ARM_CLK_CLKIN_SEL0;
+ if (mclk_div & 0x80) {
+ mclk_div &= ~0x80;
+ cntl_arm_clk |= ARM_CLK_MCLK_DIV5;
+ } else
+ cntl_arm_clk &= ~ARM_CLK_MCLK_DIV5;
+ cntl_arm_clk &= ~(0x7 << ARM_CLK_MCLK_DIV_SHIFT);
+ cntl_arm_clk |= (mclk_div << ARM_CLK_MCLK_DIV_SHIFT);
+ writew(cntl_arm_clk, CLKM_REG(CNTL_ARM_CLK));
+
+ /* Then finally set the PLL */
+ calypso_pll_set(inp);
+}
+
+void calypso_mem_cfg(enum calypso_bank bank, uint8_t ws,
+ enum calypso_mem_width width, int we)
+{
+ writew((ws & 0x1f) | ((width & 3) << 5) | ((we & 1) << 7),
+ BASE_ADDR_MEMIF + bank);
+}
+
+void calypso_bootrom(int enable)
+{
+ uint16_t conf = readw(MEMIF_REG(EXTRA_CONF));
+
+ conf |= (3 << 8);
+
+ if (enable)
+ conf &= ~(1 << 9);
+
+ writew(conf, MEMIF_REG(EXTRA_CONF));
+}
+
+void calypso_debugunit(int enable)
+{
+ uint16_t conf = readw(MEMIF_REG(EXTRA_CONF));
+
+ if (enable)
+ conf &= ~(1 << 11);
+ else
+ conf |= (1 << 11);
+
+ writew(conf, MEMIF_REG(EXTRA_CONF));
+}
+
+#define REG_RHEA_CNTL 0xfffff900
+#define REG_API_CNTL 0xfffff902
+#define REG_ARM_RHEA 0xfffff904
+
+void calypso_rhea_cfg(uint8_t fac0, uint8_t fac1, uint8_t timeout,
+ uint8_t ws_h, uint8_t ws_l, uint8_t w_en0, uint8_t w_en1)
+{
+ writew(fac0 | (fac1 << 4) | (timeout << 8), REG_RHEA_CNTL);
+ writew(ws_h | (ws_l << 5), REG_API_CNTL);
+ writew(w_en0 | (w_en1 << 1), REG_ARM_RHEA);
+}