From f712427135d6c180e413a3a22ba75290bb19a6b5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 18 Sep 2007 12:39:01 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- ports/ARM7-LPC214x/GCC/lpc214x.h | 456 ++++++++++++++++++++++++++++++++ ports/ARM7-LPC214x/GCC/lpc214x_serial.c | 150 +++++++++++ ports/ARM7-LPC214x/GCC/lpc214x_serial.h | 30 +++ 3 files changed, 636 insertions(+) create mode 100644 ports/ARM7-LPC214x/GCC/lpc214x.h create mode 100644 ports/ARM7-LPC214x/GCC/lpc214x_serial.c create mode 100644 ports/ARM7-LPC214x/GCC/lpc214x_serial.h (limited to 'ports/ARM7-LPC214x') diff --git a/ports/ARM7-LPC214x/GCC/lpc214x.h b/ports/ARM7-LPC214x/GCC/lpc214x.h new file mode 100644 index 000000000..63be5c36c --- /dev/null +++ b/ports/ARM7-LPC214x/GCC/lpc214x.h @@ -0,0 +1,456 @@ +/* + 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 _LPC214X_H_ +#define _LPC214X_H_ + +typedef volatile unsigned char IOREG8; +typedef volatile unsigned int IOREG32; + +/* + * The following values are implementation dependent. You may change them in + * order to match your HW. + */ +#define FOSC 12000000 +#define CCLK 48000000 +#define PCLK 12000000 + +/* + * System. + */ +#define MEMMAP (*((IOREG32 *)0xE01FC040)) +#define PCON (*((IOREG32 *)0xE01FC0C0)) +#define PCONP (*((IOREG32 *)0xE01FC0C4)) +#define VPBDIV (*((IOREG32 *)0xE01FC100)) +#define EXTINT (*((IOREG32 *)0xE01FC140)) +#define INTWAKE (*((IOREG32 *)0xE01FC144)) +#define EXTMODE (*((IOREG32 *)0xE01FC148)) +#define EXTPOLAR (*((IOREG32 *)0xE01FC14C)) +#define RSID (*((IOREG32 *)0xE01FC180)) +#define CSPR (*((IOREG32 *)0xE01FC184)) +#define SCS (*((IOREG32 *)0xE01FC1A0)) + +#define VPD_D4 0 +#define VPD_D1 1 +#define VPD_D2 2 +#define VPD_RESERVED 3 + +#define PCTIM0 (1 << 1) +#define PCTIM1 (1 << 2) +#define PCUART0 (1 << 3) +#define PCUART1 (1 << 4) +#define PCPWM0 (1 << 5) +#define PCI2C0 (1 << 7) +#define PCSPI0 (1 << 8) +#define PCRTC (1 << 9) +#define PCSPI1 (1 << 10) +#define PCAD0 (1 << 12) +#define PCI2C1 (1 << 19) +#define PCAD1 (1 << 20) +#define PCUSB (1 << 31) +#define PCALL (PCTIM0 | PCTIM1 | PCUART0 | PCUART1 | \ + PCPWM0 | PCI2C0 | PCSPI0 | PCRTC | PCSPI1 | \ + PCAD0 | PCI2C1 | PCAD1 | PCUSB) + +typedef struct { + IOREG32 PLL0_CON; + IOREG32 PLL0_CFG; + IOREG32 PLL0_STAT; + IOREG32 PLL0_FEED; + IOREG32 PLL1_CON; + IOREG32 PLL1_CFG; + IOREG32 PLL1_STAT; + IOREG32 PLL1_FEED; +} PLL; + +#define PLLBase ((PLL *)0xE01FC080) +#define PLL0CON (PLLBase->PLL0_CON) +#define PLL0CFG (PLLBase->PLL0_CFG) +#define PLL0STAT (PLLBase->PLL0_STAT) +#define PLL0FEED (PLLBase->PLL0_FEED) +#define PLL1CON (PLLBase->PLL1_CON) +#define PLL1CFG (PLLBase->PLL1_CFG) +#define PLL1STAT (PLLBase->PLL1_STAT) +#define PLL1FEED (PLLBase->PLL1_FEED) + +/* + * Pins. + */ +typedef struct { + IOREG32 PS_SEL0; + IOREG32 PS_SEL1; + IOREG32 PS_SEL2; +} PS; + +#define PSBase ((PS *)0xE002C000) +#define PINSEL0 (PSBase->PS_SEL0) +#define PINSEL1 (PSBase->PS_SEL1) +#define PINSEL2 (PSBase->PS_SEL2) + +/* + * VIC + */ +#define SOURCE_WDT 0 +#define SOURCE_ARMCore0 2 +#define SOURCE_ARMCore1 3 +#define SOURCE_Timer0 4 +#define SOURCE_Timer1 5 +#define SOURCE_UART0 6 +#define SOURCE_UART1 7 +#define SOURCE_PWM0 8 +#define SOURCE_I2C0 9 +#define SOURCE_SPI0 10 +#define SOURCE_SPI1 11 +#define SOURCE_PLL 12 +#define SOURCE_RTC 13 +#define SOURCE_EINT0 14 +#define SOURCE_EINT1 15 +#define SOURCE_EINT2 16 +#define SOURCE_EINT3 17 +#define SOURCE_ADC0 18 +#define SOURCE_I2C1 19 +#define SOURCE_BOD 20 +#define SOURCE_ADC1 21 +#define SOURCE_USB 22 + +#define INTMASK(n) (1 << (n)) + +typedef struct { + IOREG32 VIC_IRQStatus; + IOREG32 VIC_FIQStatus; + IOREG32 VIC_RawIntr; + IOREG32 VIC_IntSelect; + IOREG32 VIC_IntEnable; + IOREG32 VIC_IntEnClear; + IOREG32 VIC_SoftInt; + IOREG32 VIC_SoftIntClear; + IOREG32 VIC_Protection; + IOREG32 unused1[3]; + IOREG32 VIC_VectAddr; + IOREG32 VIC_DefVectAddr; + IOREG32 unused2[50]; + IOREG32 VIC_VectAddrs[16]; + IOREG32 unused3[48]; + IOREG32 VIC_VectCntls[16]; +} VIC; + +#define VICBase ((VIC *)0xFFFFF000) +#define VICVectorsBase ((IOREG32 *)0xFFFFF100) +#define VICControlsBase ((IOREG32 *)0xFFFFF200) + +#define VICIRQStatus (VICBase->VIC_IRQStatus) +#define VICFIQStatus (VICBase->VIC_FIQStatus) +#define VICRawIntr (VICBase->VIC_RawIntr) +#define VICIntSelect (VICBase->VIC_IntSelect) +#define VICIntEnable (VICBase->VIC_IntEnable) +#define VICIntEnClear (VICBase->VIC_IntEnClear) +#define VICSoftInt (VICBase->VIC_SoftInt) +#define VICSoftIntClear (VICBase->VIC_SoftIntClear) +#define VICProtection (VICBase->VIC_Protection) +#define VICVectAddr (VICBase->VIC_VectAddr) +#define VICDefVectAddr (VICBase->VIC_DefVectAddr) + +#define VICVectAddrs(n) (VICBase->VIC_VectAddrs[n]) +#define VICVectCntls(n) (VICBase->VIC_VectCntls[n]) + +/* + * MAM. + */ +typedef struct { + IOREG32 MAM_Control; + IOREG32 MAM_Timing; +} MAM; + +#define MAMBase ((MAM *)0xE01FC000) +#define MAMCR (MAMBase->MAM_Control) +#define MAMTIM (MAMBase->MAM_Timing) + +/* + * GPIO - FIO. + */ +typedef struct { + IOREG32 IO_PIN; + IOREG32 IO_SET; + IOREG32 IO_DIR; + IOREG32 IO_CLR; +} GPIO; + +#define GPIO0Base ((GPIO *)0xE0028000) +#define IO0PIN (GPIO0Base->IO_PIN) +#define IO0SET (GPIO0Base->IO_SET) +#define IO0DIR (GPIO0Base->IO_DIR) +#define IO0CLR (GPIO0Base->IO_CLR) + +#define GPIO1Base ((GPIO *)0xE0028010) +#define IO1PIN (GPIO1Base->IO_PIN) +#define IO1SET (GPIO1Base->IO_SET) +#define IO1DIR (GPIO1Base->IO_DIR) +#define IO1CLR (GPIO1Base->IO_CLR) + +typedef struct { + IOREG32 FIO_DIR; + IOREG32 unused1; + IOREG32 unused2; + IOREG32 unused3; + IOREG32 FIO_MASK; + IOREG32 FIO_PIN; + IOREG32 FIO_SET; + IOREG32 FIO_CLR; +} FIO; + +#define FIO0Base ((FIO *)0x3FFFC000) +#define FIO0DIR (FIO0Base->FIO_DIR) +#define FIO0MASK (FIO0Base->FIO_MASK) +#define FIO0PIN (FIO0Base->FIO_PIN) +#define FIO0SET (FIO0Base->FIO_SET) +#define FIO0CLR (FIO0Base->FIO_CLR) + +#define FIO1Base ((FIO *)0x3FFFC020) +#define FIO1DIR (FIO1Base->FIO_DIR) +#define FIO1MASK (FIO1Base->FIO_MASK) +#define FIO1PIN (FIO1Base->FIO_PIN) +#define FIO1SET (FIO1Base->FIO_SET) +#define FIO1CLR (FIO1Base->FIO_CLR) + +/* + * UART. + */ +typedef struct { + union { + IOREG32 UART_RBR; + IOREG32 UART_THR; + IOREG32 UART_DLL; + }; + union { + IOREG32 UART_IER; + IOREG32 UART_DLM; + }; + union { + IOREG32 UART_IIR; + IOREG32 UART_FCR; + }; + IOREG32 UART_LCR; + IOREG32 UART_MCR; // UART1 only + IOREG32 UART_LSR; + IOREG32 unused18; + IOREG32 UART_SCR; + IOREG32 UART_ACR; + IOREG32 unused24; + IOREG32 UART_FDR; + IOREG32 unused2C; + IOREG32 UART_TER; +} UART; + +/*typedef struct { + union { + IOREG8 UART_RBR; + IOREG8 UART_THR; + IOREG8 UART_DLL; + IOREG8 f1[4]; + }; + union { + IOREG8 UART_IER; + IOREG8 UART_DLM; + IOREG8 f2[4]; + }; + union { + IOREG8 UART_IIR; + IOREG8 UART_FCR; + IOREG8 f3[4]; + }; + IOREG8 UART_LCR; + IOREG8 f4[3]; + IOREG8 UART_MCR; // UART1 only + IOREG8 f5[3]; + IOREG8 UART_LSR; + IOREG8 f6[3]; + IOREG32 unused18; + IOREG8 UART_SCR; + IOREG8 f7[3]; + IOREG8 UART_ACR; + IOREG8 f8[3]; + IOREG32 unused24; + IOREG8 UART_FDR; + IOREG8 f9[3]; + IOREG32 unused2C; + IOREG8 UART_TER; + IOREG8 f10[3]; +} UART;*/ + +#define U0Base ((UART *)0xE000C000) +#define U0RBR (U0Base->UART_RBR) +#define U0THR (U0Base->UART_THR) +#define U0DLL (U0Base->UART_DLL) +#define U0IER (U0Base->UART_IER) +#define U0DLM (U0Base->UART_DLM) +#define U0IIR (U0Base->UART_IIR) +#define U0FCR (U0Base->UART_FCR) +#define U0LCR (U0Base->UART_LCR) +#define U0LSR (U0Base->UART_LSR) +#define U0SCR (U0Base->UART_SCR) +#define U0ACR (U0Base->UART_ACR) +#define U0FDR (U0Base->UART_FDR) +#define U0TER (U0Base->UART_TER) + +#define U1Base ((UART *)0xE0010000) +#define U1RBR (U1Base->UART_RBR) +#define U1THR (U1Base->UART_THR) +#define U1DLL (U1Base->UART_DLL) +#define U1IER (U1Base->UART_IER) +#define U1DLM (U1Base->UART_DLM) +#define U1IIR (U1Base->UART_IIR) +#define U1FCR (U1Base->UART_FCR) +#define U1MCR (U1Base->UART_MCR) +#define U1LCR (U1Base->UART_LCR) +#define U1LSR (U1Base->UART_LSR) +#define U1SCR (U1Base->UART_SCR) +#define U1ACR (U1Base->UART_ACR) +#define U1FDR (U1Base->UART_FDR) +#define U1TER (U1Base->UART_TER) + +#define IIR_SRC_MASK 0x0F +#define IIR_SRC_NONE 0x01 +#define IIR_SRC_TX 0x02 +#define IIR_SRC_RX 0x04 +#define IIR_SRC_ERROR 0x06 +#define IIR_SRC_TIMEOUT 0x0C + +#define IER_RBR 1 +#define IER_THRE 2 +#define IER_STATUS 4 + +#define IIR_INT_PENDING 1 + +#define LCR_WL5 0 +#define LCR_WL6 1 +#define LCR_WL7 2 +#define LCR_WL8 3 +#define LCR_STOP1 0 +#define LCR_STOP2 4 +#define LCR_NOPARITY 0 +#define LCR_PARITYODD 0x08 +#define LCR_PARITYEVEN 0x18 +#define LCR_PARITYONE 0x28 +#define LCR_PARITYZERO 0x38 +#define LCR_BREAK_ON 0x40 +#define LCR_DLAB 0x80 + +#define FCR_ENABLE 1 +#define FCR_RXRESET 2 +#define FCR_TXRESET 4 +#define FCR_TRIGGER0 0 +#define FCR_TRIGGER1 0x40 +#define FCR_TRIGGER2 0x80 +#define FCR_TRIGGER3 0xC0 + +#define LSR_RBR_FULL 1 +#define LSR_OVERRUN 2 +#define LSR_PARITY 4 +#define LSR_FRAMING 8 +#define LSR_BREAK 0x10 +#define LSR_THRE 0x20 +#define LSR_TEMT 0x40 +#define LSR_RXFE 0x80 + +#define TER_ENABLE 0x80 + +/* + * Timers/Counters. + */ +typedef struct { + IOREG32 TC_IR; + IOREG32 TC_TCR; + IOREG32 TC_TC; + IOREG32 TC_PR; + IOREG32 TC_PC; + IOREG32 TC_MCR; + IOREG32 TC_MR0; + IOREG32 TC_MR1; + IOREG32 TC_MR2; + IOREG32 TC_MR3; + IOREG32 TC_CCR; + IOREG32 TC_CR0; + IOREG32 TC_CR1; + IOREG32 TC_CR2; + IOREG32 TC_CR3; + IOREG32 TC_EMR; + IOREG32 TC_CTCR; +} TC; + +#define T0Base ((TC *)0xE0004000) +#define T0IR (T0Base->TC_IR) +#define T0TCR (T0Base->TC_TCR) +#define T0TC (T0Base->TC_TC) +#define T0PR (T0Base->TC_PR) +#define T0PC (T0Base->TC_PC) +#define T0MCR (T0Base->TC_MCR) +#define T0MR0 (T0Base->TC_MR0) +#define T0MR1 (T0Base->TC_MR1) +#define T0MR2 (T0Base->TC_MR2) +#define T0MR3 (T0Base->TC_MR3) +#define T0CCR (T0Base->TC_CCR) +#define T0CR0 (T0Base->TC_CR0) +#define T0CR1 (T0Base->TC_CR1) +#define T0CR2 (T0Base->TC_CR2) +#define T0CR3 (T0Base->TC_CR3) +#define T0EMR (T0Base->TC_EMR) +#define T0CTCR (T0Base->TC_CTCR) + +#define T1Base ((TC *)0xE0008000) +#define T1IR (T1Base->TC_IR) +#define T1TCR (T1Base->TC_TCR) +#define T1TC (T1Base->TC_TC) +#define T1PR (T1Base->TC_PR) +#define T1PC (T1Base->TC_PC) +#define T1MCR (T1Base->TC_MCR) +#define T1MR0 (T1Base->TC_MR0) +#define T1MR1 (T1Base->TC_MR1) +#define T1MR2 (T1Base->TC_MR2) +#define T1MR3 (T1Base->TC_MR3) +#define T1CCR (T1Base->TC_CCR) +#define T1CR0 (T1Base->TC_CR0) +#define T1CR1 (T1Base->TC_CR1) +#define T1CR2 (T1Base->TC_CR2) +#define T1CR3 (T1Base->TC_CR3) +#define T1EMR (T1Base->TC_EMR) +#define T1CTCR (T1Base->TC_CTCR) + +/* + * Watchdog. + */ +typedef struct { + IOREG32 WD_MOD; + IOREG32 WD_TC; + IOREG32 WD_FEED; + IOREG32 WD_TV; +} WD; + +#define WDBase ((WD *)0xE0000000) +#define WDMOD (WDBase->WD_MOD) +#define WDTC (WDBase->WD_TC) +#define WDFEED (WDBase->WD_FEED) +#define WDTV (WDBase->WD_TV) + +/* + * DAC. + */ +#define DACR (*((IOREG32 *)0xE006C000)) + +#endif /* _LPC214X_H_ */ + diff --git a/ports/ARM7-LPC214x/GCC/lpc214x_serial.c b/ports/ARM7-LPC214x/GCC/lpc214x_serial.c new file mode 100644 index 000000000..59aa75b6b --- /dev/null +++ b/ports/ARM7-LPC214x/GCC/lpc214x_serial.c @@ -0,0 +1,150 @@ +/* + 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" + +#define SERIAL_BUFFERS_SIZE 128 + +FullDuplexDriver COM1; +BYTE8 ib1[SERIAL_BUFFERS_SIZE]; +BYTE8 ob1[SERIAL_BUFFERS_SIZE]; + +FullDuplexDriver COM2; +BYTE8 ib2[SERIAL_BUFFERS_SIZE]; +BYTE8 ob2[SERIAL_BUFFERS_SIZE]; + +static void SetError(IOREG32 err, FullDuplexDriver *com) { + UWORD16 sts = 0; + + if (err & LSR_OVERRUN) + sts |= SD_OVERRUN_ERROR; + if (err & LSR_PARITY) + sts |= SD_PARITY_ERROR; + if (err & LSR_FRAMING) + sts |= SD_FRAMING_ERROR; + if (err & LSR_BREAK) + sts |= SD_BREAK_DETECTED; + chFDDAddFlagsI(com, sts); +} + +/* + * Tries hard to clear all the pending interrupt sources, we dont want to + * go through the whole ISR and have another interrupt soon after. + */ +static void ServeInterrupt(UART *u, FullDuplexDriver *com) { + + while (TRUE) { + + switch (u->UART_IIR & IIR_SRC_MASK) { + case IIR_SRC_NONE: + VICVectAddr = 0; + return; + case IIR_SRC_ERROR: + SetError(u->UART_LSR, com); + break; + case IIR_SRC_TIMEOUT: + case IIR_SRC_RX: + while (u->UART_LSR & LSR_RBR_FULL) + chFDDIncomingDataI(com, u->UART_RBR); + break; + case IIR_SRC_TX: + { + t_msg b = chFDDRequestDataI(com); + if (b < Q_OK) + u->UART_IER &= ~IER_THRE; + else + u->UART_THR = b; + } + default: + u->UART_THR; + u->UART_RBR; + u->UART_IIR; + } + } +} + +/* + * Invoked by the high driver when one or more bytes are inserted in the + * output queue. + */ +static void OutNotify1(void) { + UART *u = U0Base; + + if (u->UART_LSR & LSR_THRE) + u->UART_THR = chOQGetI(&COM1.sd_oqueue); + u->UART_IER |= IER_THRE; +} + +/* + * Invoked by the high driver when one or more bytes are inserted in the + * output queue. + */ +static void OutNotify2(void) { + UART *u = U1Base; + + if (u->UART_LSR & LSR_THRE) + u->UART_THR = chOQGetI(&COM1.sd_oqueue); + u->UART_IER |= IER_THRE; +} + +void UART0Irq(void){ + + ServeInterrupt(U0Base, &COM1); +} + +void UART1Irq(void){ + + ServeInterrupt(U1Base, &COM2); +} + +/* + * UART setup, must be invoked with interrupts disabled. + */ +void SetUARTI(UART *u, int speed, int lcr, int fcr) { + + int div = PCLK / (speed << 4); + u->UART_LCR = lcr | LCR_DLAB; + u->UART_DLL = div; + u->UART_DLM = div >> 8; + u->UART_LCR = lcr; + u->UART_FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | fcr; + u->UART_ACR = 0; + u->UART_FDR = 0x10; + u->UART_TER = TER_ENABLE; + u->UART_IER = IER_RBR | IER_STATUS; +} + +/* + * Serial subsystem initialization. + */ +void InitSerial(void) { + + PCONP = (PCONP & PCALL) | PCUART0 | PCUART1; + + chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1); + SetUARTI(U0Base, 38400, LCR_WL8 | LCR_STOP1 | LCR_NOPARITY, FCR_TRIGGER0); + + chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2); + SetUARTI(U1Base, 38400, LCR_WL8 | LCR_STOP1 | LCR_NOPARITY, FCR_TRIGGER0); + + VICIntEnable |= INTMASK(SOURCE_UART0) | INTMASK(SOURCE_UART1); +} diff --git a/ports/ARM7-LPC214x/GCC/lpc214x_serial.h b/ports/ARM7-LPC214x/GCC/lpc214x_serial.h new file mode 100644 index 000000000..340856fdc --- /dev/null +++ b/ports/ARM7-LPC214x/GCC/lpc214x_serial.h @@ -0,0 +1,30 @@ +/* + 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 _LPC2000_SERIAL_H_ +#define _LPC2000_SERIAL_H_ + +void InitSerial(void); +void SetUARTI(UART *u, int speed, int lcr, int fcr); +void UART0IrqHandler(void); +void UART1IrqHandler(void); + +extern FullDuplexDriver COM1, COM2; + +#endif /* _LPC2000_SERIAL_H_*/ -- cgit v1.2.3