From 9f5b0b0b76ed471a6765867511457eb90df8b741 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 18 Sep 2007 12:31:07 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@6 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/LPC214x-GCC/buzzer.c | 82 ++++++++++++++++ demos/LPC214x-GCC/buzzer.h | 28 ++++++ demos/LPC214x-GCC/ch.ld | 85 +++++++++++++++++ demos/LPC214x-GCC/chconf.h | 153 ++++++++++++++++++++++++++++++ demos/LPC214x-GCC/chcore.c | 225 ++++++++++++++++++++++++++++++++++++++++++++ demos/LPC214x-GCC/chcore.h | 98 +++++++++++++++++++ demos/LPC214x-GCC/chcore2.s | 168 +++++++++++++++++++++++++++++++++ demos/LPC214x-GCC/chtypes.h | 52 ++++++++++ demos/LPC214x-GCC/crt0.s | 146 ++++++++++++++++++++++++++++ demos/LPC214x-GCC/main.c | 79 ++++++++++++++++ demos/LPC214x-GCC/makefile | 156 ++++++++++++++++++++++++++++++ 11 files changed, 1272 insertions(+) create mode 100644 demos/LPC214x-GCC/buzzer.c create mode 100644 demos/LPC214x-GCC/buzzer.h create mode 100644 demos/LPC214x-GCC/ch.ld create mode 100644 demos/LPC214x-GCC/chconf.h create mode 100644 demos/LPC214x-GCC/chcore.c create mode 100644 demos/LPC214x-GCC/chcore.h create mode 100644 demos/LPC214x-GCC/chcore2.s create mode 100644 demos/LPC214x-GCC/chtypes.h create mode 100644 demos/LPC214x-GCC/crt0.s create mode 100644 demos/LPC214x-GCC/main.c create mode 100644 demos/LPC214x-GCC/makefile (limited to 'demos') diff --git a/demos/LPC214x-GCC/buzzer.c b/demos/LPC214x-GCC/buzzer.c new file mode 100644 index 000000000..4700bfb45 --- /dev/null +++ b/demos/LPC214x-GCC/buzzer.c @@ -0,0 +1,82 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * Buzzer driver for Olimex LPC-P2148. + * Uses the timer 1 for wave generation and a Virtual Timer for the sound + * duration. + * The driver also generates an event when the sound is done and the buzzer + * goes silent. + */ +#include + +#include "lpc214x.h" +#include "buzzer.h" + +EventSource BuzzerSilentEventSource; + +#define StartCounter(t) ((t)->TC_EMR = 0xF1, (t)->TC_TCR = 1) +#define StopCounter(t) ((t)->TC_EMR = 0, (t)->TC_TCR = 2) + +void InitBuzzer(void) { + + chEvtInit(&BuzzerSilentEventSource); + + /* + * Switches P0.12 and P0.13 to MAT1.0 and MAT1.1 functions. + * Enables Timer1 clock. + */ + PINSEL0 &= 0xF0FFFFFF; + PINSEL0 |= 0x0A000000; + PCONP = (PCONP & PCALL) | PCTIM1; + + /* + * Timer setup. + */ + TC *tc = T1Base; + StopCounter(tc); + tc->TC_CTCR = 0; // Clock source is PCLK. + tc->TC_PR = 0; // Prescaler disabled. + tc->TC_MCR = 2; // Clear TC on match MR0. +} + +static void stop(void *p) { + TC *tc = T1Base; + + StopCounter(tc); + chEvtSendI(&BuzzerSilentEventSource); +} + +void PlaySound(int freq, t_time duration) { + static VirtualTimer bvt; + TC *tc = T1Base; + + chSysLock(); + + if (bvt.vt_func) { // If a sound is already being played + chVTResetI(&bvt); // then aborts it. + StopCounter(tc); + } + + tc->TC_MR0 = tc->TC_MR1 = (PCLK / (freq * 2)); + StartCounter(tc); + chVTSetI(&bvt, duration, stop, NULL); + + chSysUnlock(); +} diff --git a/demos/LPC214x-GCC/buzzer.h b/demos/LPC214x-GCC/buzzer.h new file mode 100644 index 000000000..3334d8b5c --- /dev/null +++ b/demos/LPC214x-GCC/buzzer.h @@ -0,0 +1,28 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _BUZZER_H_ +#define _BUZZER_H_ + +void InitBuzzer(void); +void PlaySound(int freq, t_time duration); + +extern EventSource BuzzerSilentEventSource; + +#endif /* _BUZZER_H_ */ diff --git a/demos/LPC214x-GCC/ch.ld b/demos/LPC214x-GCC/ch.ld new file mode 100644 index 000000000..6ce8a0b32 --- /dev/null +++ b/demos/LPC214x-GCC/ch.ld @@ -0,0 +1,85 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * LPC2148 memory setup. + */ +__und_stack_size__ = 0x0004; +__abt_stack_size__ = 0x0004; +__fiq_stack_size__ = 0x0010; +__irq_stack_size__ = 0x0080; +__svc_stack_size__ = 0x0004; +__sys_stack_size__ = 0x0080; +__stacks_total_size__ = __und_stack_size__ + __abt_stack_size__ + __fiq_stack_size__ + __irq_stack_size__ + __svc_stack_size__ + __sys_stack_size__; + +MEMORY +{ + flash : org = 0x00000000, len = 512k - 12k + ram : org = 0x40000200, len = 32k - 0x200 - 288 +} + +__ram_start__ = ORIGIN(ram); +__ram_size__ = LENGTH(ram); +__ram_end__ = __ram_start__ + __ram_size__; +__dma_start__ = 0x7FD00000; +__dma_size__ = 8k; +__dma_end__ = 0x7FD00000 + __dma_size__; + +SECTIONS +{ + . = 0; + + .text : + { + _text = .; + *(.text); + *(.rodata); + *(.rodata*); + *(.glue_7t); + *(.glue_7); + . = ALIGN(4); + _etext = .; + } > flash + + _textdata = _etext; + + .data : + { + _data = .; + *(.data) + . = ALIGN(4); + _edata = .; + } > ram AT > flash + + .bss : + { + _bss_start = .; + *(.bss) + . = ALIGN(4); + *(COMMON) + . = ALIGN(4); + _bss_end = .; + } > ram +} + +PROVIDE(end = .); +_end = .; + +__heap_base__ = _end; +__heap_end__ = __ram_end__ - __stacks_total_size__; diff --git a/demos/LPC214x-GCC/chconf.h b/demos/LPC214x-GCC/chconf.h new file mode 100644 index 000000000..bb03058c8 --- /dev/null +++ b/demos/LPC214x-GCC/chconf.h @@ -0,0 +1,153 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * Configuration file for LPC214x-GCC demo project. + */ + +/** + * @addtogroup Config + * @{ + */ + +#ifndef _CHCONF_H_ +#define _CHCONF_H_ + +/** Configuration option: if specified then time efficient rather than space + * efficient code is used when two possible implementations exist, note + * that this is not related to the compiler optimization options.*/ +#define CH_OPTIMIZE_SPEED + +/** Configuration option: if specified then the Virtual Timers subsystem is + * included in the kernel.*/ +#define CH_USE_VIRTUAL_TIMERS + +/** Configuration option: if specified then the System Timer subsystem is + * included in the kernel.*/ +#define CH_USE_SYSTEMTIME + +/** Configuration option: if specified then the \p chThdSleep() function is + * included in the kernel. + * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ +#define CH_USE_SLEEP + +/** Configuration option: if specified then the \p chThdResume() + * function is included in the kernel.*/ +#define CH_USE_RESUME + +/** Configuration option: if specified then the \p chThdTerminate() + * and \p chThdShouldTerminate() functions are included in the kernel.*/ +#define CH_USE_TERMINATE + +/** Configuration option: if specified then the \p chThdWait() function + * is included in the kernel.*/ +#define CH_USE_WAITEXIT + +/** Configuration option: if specified then the Semaphores APIs are included + * in the kernel.*/ +#define CH_USE_SEMAPHORES + +/** Configuration option: if specified then the Semaphores with timeout APIs + * are included in the kernel. + * @note requires \p CH_USE_SEMAPHORES. + * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ +#define CH_USE_SEMAPHORES_TIMEOUT + +/** Configuration option: if specified then the Semaphores APIs with priority + * shift are included in the kernel. + * @note requires \p CH_USE_SEMAPHORES.*/ +//#define CH_USE_RT_SEMAPHORES + +/** Configuration option: if specified then the Events APIs are included in + * the kernel.*/ +#define CH_USE_EVENTS + +/** Configuration option: if specified then the \p chEvtWaitTimeout() + * function is included in the kernel. + * @note requires \p CH_USE_EVENTS. + * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ +//#define CH_USE_EVENTS_TIMEOUT + +/** Configuration option: if specified then the Synchronous Messages APIs are + * included in the kernel.*/ +#define CH_USE_MESSAGES + +/** Configuration option: if specified then the \p chMsgSendTimeout() + * function is included in the kernel. + * @note requires \p CH_USE_MESSAGES. + * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ +//#define CH_USE_MESSAGES_TIMEOUT + +/** Configuration option: if specified then the \p chMsgSendWithEvent() + * function is included in the kernel. + * @note requires \p CH_USE_MESSAGES. + * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ +//#define CH_USE_MESSAGES_EVENT + +/** Configuration option: if specified then the + * \p chThdGetExitEventSource() function is included in the kernel. + * @note requires \p CH_USE_MESSAGES. + * @note requires \p CH_USE_EVENTS.*/ +#define CH_USE_EXIT_EVENT + +/** Configuration option: if specified then the I/O queues APIs are included + * in the kernel.*/ +#define CH_USE_QUEUES + +/** Configuration option: if specified then the halfduplex queue APIs are + * included in the kernel.*/ +#define CH_USE_QUEUES_HALFDUPLEX + +/** Configuration option: if specified then the I/O queues with timeout + * APIs are included in the kernel. + * @note requires \p CH_USE_SEMAPHORES_TIMEOUT.*/ +#define CH_USE_QUEUES_TIMEOUT + +/** Configuration option: if specified then the full duplex serial driver APIs + * are included in the kernel.*/ +#define CH_USE_SERIAL_FULLDUPLEX + +/** Configuration option: if specified then the half duplex serial driver APIs + * are included in the kernel.*/ +#define CH_USE_SERIAL_HALFDUPLEX + +/** Configuration option: Frequency of the system timer that drives the system + * ticks. This also defines the system time unit.*/ +#define CH_FREQUENCY 1000 + +/** Configuration option: This constant is the number of ticks allowed for the + * threads before preemption occurs.*/ +#define CH_TIME_QUANTUM 20 + +/** Configuration option: Defines a CPU register to be used as storage for the + * global \p currp variable. Caching this variable in a register can greatly + * improve both space and time efficiency of the generated code. Another side + * effect is that one less register has to be saved during the context switch + * resulting in lower RAM usage and faster code. + * @note This option is only useable with the GCC compiler and is only useful + * on processors with many registers like ARM cores. + * @note If this option is enabled then ALL the libraries linked to the + * ChibiOS/RT code must be recompiled with the GCC option \p + * -ffixed-. + */ +//#define CH_CURRP_REGISTER_CACHE "r7" + +#endif /* _CHCONF_H_ */ + +/** @} */ diff --git a/demos/LPC214x-GCC/chcore.c b/demos/LPC214x-GCC/chcore.c new file mode 100644 index 000000000..3d72c20db --- /dev/null +++ b/demos/LPC214x-GCC/chcore.c @@ -0,0 +1,225 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include + +#include "lpc214x.h" +#include "lpc214x_serial.h" +#include "buzzer.h" + +extern void IrqHandler(void); +extern void T0IrqHandler(void); + +#define VAL_TC0_PRESCALER 0 + +/* + * Pins configuration for Olimex LPC-P2148. + * + * PINSEL0 + * P0 P0 P0 P0 P0 P0 RXD TXD SSE MOS MIS SCK SDA SCL RXD TXD + * 15 14 13 12 11 10 1 1 L0 I0 O0 0 0 0 0 0 + * 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 + * IN IN OUT OUT OUT OUT -- -- -- -- -- -- -- -- -- -- + * 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 + * + * PINSEL1 + * P0 AD P0 P0 -- -- AO -- VB P0 P0 SSE MOS MIS SCK P0 + * 31 03 29 28 -- -- UT -- US 22 21 L1 I1 O1 1 16 + * 00 01 00 00 00 00 10 00 01 00 00 10 10 10 10 00 + * OUT -- OUT OUT -- -- -- -- -- OUT OUT -- -- -- -- IN + * 1 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 + * + * PINSEL2 + * -- -- -- -- -- -- -- -- -- -- -- -- -- -- GP DBG -- + * -- -- -- -- -- -- -- -- -- -- -- -- -- -- IO -- + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 1 00 + * -- -- -- -- -- -- -- -- -- -- -- -- -- -- IN -- -- + */ +#define VAL_PINSEL0 0x00055555 +#define VAL_PINSEL1 0x100842A8 +#define VAL_PINSEL2 0x00000004 +#define VAL_FIO0DIR 0xB0603C00 +#define VAL_FIO1DIR 0x00000000 + +/* + * Hardware initialization goes here. + * NOTE: Interrupts are still disabled. + */ +void hwinit(void) { + int i; + + /* + * All peripherals clock disabled by default in order to save power. + */ + PCONP = PCRTC | PCTIM0; + + /* + * MAM setup. + */ + MAMTIM = 0x3; /* 3 cycles for flash accesses. */ + MAMCR = 0x2; /* MAM fully enabled. */ + + /* + * PLL setup for Fosc=12MHz and CCLK=48MHz. + * P=2 M=3. + */ + PLL *pll = PLLBase; + pll->PLL0_CFG = 0x23; /* P and M values. */ + pll->PLL0_CON = 0x1; /* Enalbles the PLL 0. */ + pll->PLL0_FEED = 0xAA; + pll->PLL0_FEED = 0x55; + while (!(pll->PLL0_STAT & 0x400)) + ; /* Wait for PLL lock. */ + + pll->PLL0_CON = 0x3; /* Connects the PLL. */ + pll->PLL0_FEED = 0xAA; + pll->PLL0_FEED = 0x55; + + /* + * VPB setup. + * PCLK = CCLK / 4. + */ + VPBDIV = VPD_D4; + + /* + * I/O pins configuration. + */ + PINSEL0 = VAL_PINSEL0; + PINSEL1 = VAL_PINSEL1; + PINSEL2 = VAL_PINSEL2; + IO0DIR = VAL_FIO0DIR; + IO0SET = 0xFFFFFFFF; + IO1DIR = VAL_FIO1DIR; + IO1SET = 0xFFFFFFFF; + + /* + * Interrupt vectors assignment. + * NOTE: Better reset everything in the VIC, it is a HUGE source of trouble. + */ + VIC *vic = VICBase; + vic->VIC_IntSelect = 0; + vic->VIC_IntEnable = 0; + vic->VIC_VectAddr = 0; + for (i = 0; i < 16; i++) { + vic->VIC_VectCntls[i] = 0; + vic->VIC_VectAddrs[i] = 0; + } + vic->VIC_DefVectAddr = (IOREG32)IrqHandler; + SetVICVector(T0IrqHandler, 0, SOURCE_Timer0); + SetVICVector(UART0IrqHandler, 1, SOURCE_UART0); + SetVICVector(UART1IrqHandler, 2, SOURCE_UART1); + + /* + * System Timer initialization, 1ms intervals. + */ + vic->VIC_IntEnable |= INTMASK(SOURCE_Timer0); + TC *timer = T0Base; + timer->TC_PR = VAL_TC0_PRESCALER; + timer->TC_MR0 = (PCLK / CH_FREQUENCY) / (VAL_TC0_PRESCALER + 1); + timer->TC_MCR = 3; /* Interrupt and clear TC on match MR0. */ + timer->TC_TCR = 2; /* Reset counter and prescaler. */ + timer->TC_TCR = 1; /* Timer enabled. */ + + /* + * Other subsystems. + */ + InitSerial(); + InitBuzzer(); +} + +void chSysPause(void) { + + while (TRUE) { +// Note, it is disabled because it causes trouble with the JTAG probe. +// Enable it in the final code only. +// PCON = 1; /* Stops CPU clock until next interrupt. */ + } +} + +/* + * System halt. + * Yellow LED only. + */ +void chSysHalt(void) { + + chSysLock(); + IO0SET = 0x80000C00; + IO0CLR = 0x80000000; + while (TRUE) + ; +} + +/* + * Set a vector for an interrupt source, the vector is enabled too. + */ +void SetVICVector(void *handler, int vector, int source) { + + VIC *vicp = VICBase; + vicp->VIC_VectAddrs[vector] = (IOREG32)handler; + vicp->VIC_VectCntls[vector] = (IOREG32)(source | 0x20); +} + +/* + * Undefined Instruction exception handler. + * Yellow LED + RED LED 2. + */ +void UndHandler(void) { + IO0SET = 0x80000C00; + IO0CLR = 0x80000800; + while(TRUE) + ; +} + +/* + * Prefetch exception handler. + * Yellow LED + RED LED 1. + */ +void PrefetchHandler(void) { + IO0SET = 0x80000C00; + IO0CLR = 0x80000400; + while(TRUE) + ; +} + +/* + * Abort exception handler. + * Yellow LED + both RED LEDs. + */ +void AbortHandler(void) { + IO0SET = 0x80000C00; + IO0CLR = 0x80000C00; + while(TRUE) + ; +} + +/* + * Non-vectored IRQs handling here. + */ +void NonVectoredIrq(void) { + VICVectAddr = 0; +} + +/* + * Timer 0 IRQ handling here. + */ +void Timer0Irq(void) { + chSchTimerHandlerI(); + T0IR = 1; /* Clear interrupt on match MR0. */ + VICVectAddr = 0; +} diff --git a/demos/LPC214x-GCC/chcore.h b/demos/LPC214x-GCC/chcore.h new file mode 100644 index 000000000..6dfdae6e9 --- /dev/null +++ b/demos/LPC214x-GCC/chcore.h @@ -0,0 +1,98 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _CHCORE_H_ +#define _CHCORE_H_ + +typedef void *regarm; + +/* + * Stack saved context. + */ +struct stackregs { + regarm r4; + regarm r5; + regarm r6; +#ifndef MK_CURRP_REGISTER_CACHE + regarm r7; +#endif + regarm r8; + regarm r9; + regarm r10; + regarm r11; + regarm lr; +}; + +typedef struct { + struct stackregs *r13; +} Context; + +#ifdef MK_CURRP_REGISTER_CACHE +#define SETUP_CONTEXT(workspace, wsize, pf, arg) \ +{ \ + tp->p_ctx.r13 = (struct stackregs *)((BYTE8 *)workspace + \ + wsize - \ + sizeof(struct stackregs)); \ + tp->p_ctx.r13->r4 = pf; \ + tp->p_ctx.r13->r5 = arg; \ + tp->p_ctx.r13->r6 = 0; \ + tp->p_ctx.r13->r8 = 0; \ + tp->p_ctx.r13->r9 = 0; \ + tp->p_ctx.r13->r10 = 0; \ + tp->p_ctx.r13->r11 = 0; \ + tp->p_ctx.r13->lr = threadstart; \ +} +#else +#define SETUP_CONTEXT(workspace, wsize, pf, arg) \ +{ \ + tp->p_ctx.r13 = (struct stackregs *)((BYTE8 *)workspace + \ + wsize - \ + sizeof(struct stackregs)); \ + tp->p_ctx.r13->r4 = pf; \ + tp->p_ctx.r13->r5 = arg; \ + tp->p_ctx.r13->r6 = 0; \ + tp->p_ctx.r13->r7 = 0; \ + tp->p_ctx.r13->r8 = 0; \ + tp->p_ctx.r13->r9 = 0; \ + tp->p_ctx.r13->r10 = 0; \ + tp->p_ctx.r13->r11 = 0; \ + tp->p_ctx.r13->lr = threadstart; \ +} +#endif + +#define chSysLock() asm("msr CPSR_c, #0x9F") + +#define chSysUnlock() asm("msr CPSR_c, #0x1F") + +#define INT_REQUIRED_STACK 0x40 // Must include registers and stack frames. + +#define UserStackSize(n) (sizeof(Thread) + \ + sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK)) + +void chSysHalt(void) __attribute__((noreturn)); +void chSysPause(void); +void chSysSwitchI(Context *oldp, Context *newp); +void threadstart(void); +void DefFiqHandler(void); +void DefIrqHandler(void); +void SpuriousHandler(void); + +void SetVICVector(void *handler, int vector, int source); + +#endif /* _CHCORE_H_ */ diff --git a/demos/LPC214x-GCC/chcore2.s b/demos/LPC214x-GCC/chcore2.s new file mode 100644 index 000000000..eec962655 --- /dev/null +++ b/demos/LPC214x-GCC/chcore2.s @@ -0,0 +1,168 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "chconf.h" + +.set MODE_USR, 0x10 +.set MODE_FIQ, 0x11 +.set MODE_IRQ, 0x12 +.set MODE_SVC, 0x13 +.set MODE_ABT, 0x17 +.set MODE_UND, 0x1B +.set MODE_SYS, 0x1F + +.equ I_BIT, 0x80 +.equ F_BIT, 0x40 + +.text +.code 32 +.balign 4 + +.globl threadstart +threadstart: + msr CPSR_c, #MODE_SYS + mov r0, r5 +/* blx r4*/ + mov lr, pc + bx r4 + bl chThdExit + +.globl SwiHandler +SwiHandler: + b SwiHandler + +.globl DefIrqHandler +DefIrqHandler: + b DefIrqHandler + +.globl FiqHandler +FiqHandler: + b FiqHandler + +.globl chSysSwitchI +chSysSwitchI: +#ifdef MK_CURRP_REGISTER_CACHE + stmfd sp!, {r4, r5, r6, r8, r9, r10, r11, lr} + str sp, [r0, #0] + ldr sp, [r1, #0] + ldmfd sp!, {r4, r5, r6, r8, r9, r10, r11, lr} + bx lr +#else + stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr} + str sp, [r0, #0] + ldr sp, [r1, #0] + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr} + bx lr +#endif + +/* + * System stack frame structure after a context switch in the + * interrupt handler: + * + * High +------------+ + * | R12 | -+ + * | R3 | | + * | R2 | | + * | R1 | | External context: IRQ handler frame + * | R0 | | + * | LR_IRQ | | (user code return address) + * | SPSR | -+ (user code status) + * | .... | <- mk_DoRescheduleI() stack frame, optimize it for space + * | LR | -+ (system code return address) + * | R11 | | + * | R10 | | + * | R9 | | + * | R8 | | Internal context: mk_SwitchI() frame + * | (R7) | | (optional, see MK_CURRP_REGISTER_CACHE) + * | R6 | | + * | R5 | | + * SP-> | R4 | -+ + * Low +------------+ + */ +.globl IrqHandler +IrqHandler: + sub lr, lr, #4 + stmfd sp!, {r0-r3, r12, lr} + mrs r0, SPSR // Workaround for ARM7TDMI+VIC + tst r0, #I_BIT // spurious interrupts. + ldmnefd sp!, {r0-r3, r12, pc} + bl NonVectoredIrq + b IrqCommon + +.globl T0IrqHandler +T0IrqHandler: + sub lr, lr, #4 + stmfd sp!, {r0-r3, r12, lr} + mrs r0, SPSR // Workaround for ARM7TDMI+VIC + tst r0, #I_BIT // spurious interrupts. + ldmnefd sp!, {r0-r3, r12, pc}^ + bl Timer0Irq + b IrqCommon + +.globl UART0IrqHandler +UART0IrqHandler: + sub lr, lr, #4 + stmfd sp!, {r0-r3, r12, lr} + mrs r0, SPSR // Workaround for ARM7TDMI+VIC + tst r0, #I_BIT // spurious interrupts. + ldmnefd sp!, {r0-r3, r12, pc}^ + bl UART0Irq + b IrqCommon + +.globl UART1IrqHandler +UART1IrqHandler: + sub lr, lr, #4 + stmfd sp!, {r0-r3, r12, lr} + mrs r0, SPSR // Workaround for ARM7TDMI+VIC + tst r0, #I_BIT // spurious interrupts. + ldmnefd sp!, {r0-r3, r12, pc}^ + bl UART1Irq + b IrqCommon + +/* + * Common exit point for all IRQ routines, it performs the rescheduling if + * required. + */ +IrqCommon: + bl chSchRescRequiredI + cmp r0, #0 // Simply returns if a + ldmeqfd sp!, {r0-r3, r12, pc}^ // reschedule is not required. + + // Saves the IRQ mode registers in the system stack. + ldmfd sp!, {r0-r3, r12, lr} // IRQ stack now empty. + msr CPSR_c, #MODE_SYS | I_BIT + stmfd sp!, {r0-r3, r12} // Registers on System Stack. + msr CPSR_c, #MODE_IRQ | I_BIT + mrs r0, SPSR + mov r1, lr + msr CPSR_c, #MODE_SYS | I_BIT + stmfd sp!, {r0, r1} // Push R0=SPSR, R1=LR_IRQ. + + // Context switch. + bl chSchDoRescheduleI + + // Re-establish the IRQ conditions again. + ldmfd sp!, {r0, r1} // Pop R0=SPSR, R1=LR_IRQ. + msr CPSR_c, #MODE_IRQ | I_BIT + msr SPSR_fsxc, r0 + mov lr, r1 + msr CPSR_c, #MODE_SYS | I_BIT + ldmfd sp!, {r0-r3, r12} + msr CPSR_c, #MODE_IRQ | I_BIT + subs pc, lr, #0 diff --git a/demos/LPC214x-GCC/chtypes.h b/demos/LPC214x-GCC/chtypes.h new file mode 100644 index 000000000..48bf7a7d9 --- /dev/null +++ b/demos/LPC214x-GCC/chtypes.h @@ -0,0 +1,52 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _CHTYPES_H_ +#define _CHTYPES_H_ + +/* + * Generic types often dependant on the compiler. + */ +#define BOOL char +#define BYTE8 unsigned char +#define WORD16 short +#define UWORD16 unsigned short +#define LONG32 int +#define ULONG32 unsigned int +#define PTR_EQ int + +typedef BYTE8 t_tmode; +typedef BYTE8 t_tstate; +typedef WORD16 t_prio; +typedef PTR_EQ t_msg; +typedef LONG32 t_eventid; +typedef ULONG32 t_eventmask; +typedef ULONG32 t_time; +typedef LONG32 t_semcnt; +typedef ULONG32 t_size; + +#define MINPRIO 0x8000 +#define MAXPRIO 0x7fff + +#define MINDELTA 0 +#define MAXDELTA 0xffff + +#define INLINE inline + +#endif /* _CHTYPES_H_ */ diff --git a/demos/LPC214x-GCC/crt0.s b/demos/LPC214x-GCC/crt0.s new file mode 100644 index 000000000..9b413191b --- /dev/null +++ b/demos/LPC214x-GCC/crt0.s @@ -0,0 +1,146 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * Generic ARM startup file for ChibiOS/RT. + */ + +.extern _main + +.set MODE_USR, 0x10 +.set MODE_FIQ, 0x11 +.set MODE_IRQ, 0x12 +.set MODE_SVC, 0x13 +.set MODE_ABT, 0x17 +.set MODE_UND, 0x1B +.set MODE_SYS, 0x1F + +.equ I_BIT, 0x80 +.equ F_BIT, 0x40 + +.text +.code 32 +.balign 4 +/* + * System entry points. + */ +_start: + b ResetHandler + ldr pc, _undefined + ldr pc, _swi + ldr pc, _prefetch + ldr pc, _abort + nop + ldr pc, [pc,#-0xFF0] /* VIC - IRQ Vector Register */ + ldr pc, _fiq + +_undefined: + .word UndHandler +_swi: + .word SwiHandler +_prefetch: + .word PrefetchHandler +_abort: + .word AbortHandler +_fiq: + .word FiqHandler + .word 0 + .word 0 + +/* + * Reset handler. + */ +ResetHandler: + /* + * Stack pointers initialization. + */ + ldr r0, =__ram_end__ + /* Undefined */ + msr CPSR_c, #MODE_UND | I_BIT | F_BIT + mov sp, r0 + ldr r1, =__und_stack_size__ + sub r0, r0, r1 + /* Abort */ + msr CPSR_c, #MODE_ABT | I_BIT | F_BIT + mov sp, r0 + ldr r1, =__abt_stack_size__ + sub r0, r0, r1 + /* FIQ */ + msr CPSR_c, #MODE_FIQ | I_BIT | F_BIT + mov sp, r0 + ldr r1, =__fiq_stack_size__ + sub r0, r0, r1 + /* IRQ */ + msr CPSR_c, #MODE_IRQ | I_BIT | F_BIT + mov sp, r0 + ldr r1, =__irq_stack_size__ + sub r0, r0, r1 + /* Supervisor */ + msr CPSR_c, #MODE_SVC | I_BIT | F_BIT + mov sp, r0 + ldr r1, =__svc_stack_size__ + sub r0, r0, r1 + /* System */ + msr CPSR_c, #MODE_SYS | I_BIT | F_BIT + mov sp, r0 + ldr r1, =__sys_stack_size__ + sub r0, r0, r1 + /* + * Check on allocated stacks size. This should never happen unless you + * don't care to verify the map file after compiling your application. + */ + ldr r1, =_bss_end + cmp r0, r1 + bge ramsizeok + bl chSysHalt +ramsizeok: + /* + * Data initialization. + * NOTE: It assumes that the DATA size is a multiple of 4. + */ + ldr r1, =_textdata + ldr r2, =_data + ldr r3, =_edata +dataloop: + cmp r2, r3 + ldrlo r0, [r1], #4 + strlo r0, [r2], #4 + blo dataloop + /* + * BSS initialization. + * NOTE: It assumes that the BSS size is a multiple of 4. + */ + mov r0, #0 + ldr r1, =_bss_start + ldr r2, =_bss_end +bssloop: + cmp r1, r2 + strlo r0, [r1], #4 + blo bssloop + /* + * Application-provided HW initialization routine. + */ + bl hwinit + /* + * main(0, NULL). + */ + mov r0, #0 + mov r1, #0 + bl main + bl chSysHalt diff --git a/demos/LPC214x-GCC/main.c b/demos/LPC214x-GCC/main.c new file mode 100644 index 000000000..94c68ed48 --- /dev/null +++ b/demos/LPC214x-GCC/main.c @@ -0,0 +1,79 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include + +#include "lpc214x.h" +#include "lpc214x_serial.h" +#include "buzzer.h" + +static BYTE8 waThread1[UserStackSize(16)]; + +static t_msg Thread1(void *arg) { + + while (TRUE) { + IO0CLR = 0x00000800; + chThdSleep(200); + IO0SET = 0x00000C00; + chThdSleep(800); + IO0CLR = 0x00000400; + chThdSleep(200); + IO0SET = 0x00000C00; + chThdSleep(800); + } + return 0; +} + +static BYTE8 waThread2[UserStackSize(16)]; + +static t_msg Thread2(void *arg) { + + while (TRUE) { + IO0CLR = 0x80000000; + chThdSleep(200); + IO0SET = 0x80000000; + chThdSleep(300); + } + return 0; +} + +static BYTE8 waThread3[UserStackSize(16)]; + +static t_msg Thread3(void *arg) { + + while (TRUE) { + if (!(IO0PIN & 0x00008000)) // Button 1 + PlaySound(1000, 100); + if (!(IO0PIN & 0x00010000)) // Button 2 + chFDDWrite(&COM1, (BYTE8 *)"Hello World!\r\n", 14); + chThdSleep(500); + + } + return 0; +} + +int main(int argc, char **argv) { + + chSysInit(); + chThdCreate(NORMALPRIO + 1, 0, waThread1, sizeof(waThread1), Thread1, NULL); + chThdCreate(NORMALPRIO + 1, 0, waThread2, sizeof(waThread2), Thread2, NULL); + chThdCreate(NORMALPRIO + 1, 0, waThread3, sizeof(waThread3), Thread3, NULL); + chSysPause(); + return 0; +} diff --git a/demos/LPC214x-GCC/makefile b/demos/LPC214x-GCC/makefile new file mode 100644 index 000000000..b07f8360f --- /dev/null +++ b/demos/LPC214x-GCC/makefile @@ -0,0 +1,156 @@ +# +# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! +# +############################################################################################## +# +# On command line: +# +# make all = Create project +# +# make clean = Clean project files. +# +# To rebuild project do "make clean" and "make all". +# + +############################################################################################## +# Start of default section +# + +TRGT = arm-elf- +CC = $(TRGT)gcc +CP = $(TRGT)objcopy +AS = $(TRGT)gcc -x assembler-with-cpp +OD = $(TRGT)objdump +HEX = $(CP) -O ihex +BIN = $(CP) -O binary + +MCU = arm7tdmi + +# List all default C defines here, like -D_DEBUG=1 +DDEFS = + +# List all default ASM defines here, like -D_DEBUG=1 +DADEFS = + +# List all default directories to look for include files here +DINCDIR = + +# List the default directory to look for the libraries here +DLIBDIR = + +# List all default libraries here +DLIBS = + +# +# End of default section +############################################################################################## + +############################################################################################## +# Start of user section +# + +# Define project name here +PROJECT = ch + +# Define linker script file here +LDSCRIPT= ch.ld + +# List all user C define here, like -D_DEBUG=1 +UDEFS = + +# Define ASM defines here +UADEFS = + +# List C source files here +SRC = chcore.c buzzer.c main.c \ + ../../ports/ARM7-LPC214x/GCC/lpc214x_serial.c \ + ../../src/chinit.c ../../src/chdelta.c ../../src/chschd.c ../../src/chthreads.c \ + ../../src/chsem.c ../../src/chevents.c ../../src/chmsg.c ../../src/chsleep.c \ + ../../src/chqueues.c ../../src/chserial.c + +# List ASM source files here +ASRC = crt0.s chcore2.s + +# List all user directories here +UINCDIR = ../../src/include ../../ports/ARM7-LPC214x/GCC + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# Define optimisation level here +# NOTE: -mthumb-interwork increases the code size, remove it if you don't really need it. +# NOTE: -ffixed-f7 is only needed if you enabled CH_CURRP_REGISTER_CACHE in chconf.h. +#OPT = -Os -ggdb -fomit-frame-pointer -fno-strict-aliasing +#OPT = -O0 -ggdb -fomit-frame-pointer -fno-strict-aliasing +OPT = -O2 -ggdb -fomit-frame-pointer -fno-strict-aliasing + +# Define warning options here +WARN = -Wall -Wstrict-prototypes + +# +# End of user defines +############################################################################################## + +INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) +LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) +DEFS = $(DDEFS) $(UDEFS) +ADEFS = $(DADEFS) $(UADEFS) +OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) +LIBS = $(DLIBS) $(ULIBS) +MCFLAGS = -mcpu=$(MCU) + +#ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(<:.s=.lst) $(ADEFS) +ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(<:.s=.lst) $(ADEFS) +CPFLAGS = $(MCFLAGS) $(OPT) $(WARN) -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) +LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR) +ODFLAGS = -x --syms + +# Generate dependency information +CPFLAGS += -MD -MP -MF .dep/$(@F).d + +# +# makefile rules +# + +all: $(OBJS) $(PROJECT).elf $(PROJECT).hex $(PROJECT).bin $(PROJECT).dmp + +%o : %c + $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ + +%o : %s + $(AS) -c $(ASFLAGS) $< -o $@ + +%elf: $(OBJS) + $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ + +%hex: %elf + $(HEX) $< $@ + +%bin: %elf + $(BIN) $< $@ + +%dmp: %elf + $(OD) $(ODFLAGS) $< > $@ + +clean: + -rm -f $(OBJS) + -rm -f $(PROJECT).elf + -rm -f $(PROJECT).dmp + -rm -f $(PROJECT).map + -rm -f $(PROJECT).hex + -rm -f $(PROJECT).bin + -rm -f $(SRC:.c=.c.bak) + -rm -f $(SRC:.c=.lst) + -rm -f $(ASRC:.s=.s.bak) + -rm -f $(ASRC:.s=.lst) + -rm -fR .dep + +# +# Include the dependency files, should be the last of the makefile +# +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# *** EOF *** -- cgit v1.2.3