UserPreferences

Projects/RobotDemo2005/ClubFairCode


See also:

  1. robotest.c
  2. Makefile
  3. LPC2106-ROM.ld
  4. crt0.S
  5. lpc213x.h

1. robotest.c

#include "lpc213x.h"

#define MIN(a, b) (((a) < (b))? (a) : (b))

//#define ONE_SECOND 3000000 // PCLK = 3 MHz (12 MHz / 4)
#define ONE_SECOND 15000000 // PCLK = 15 MHz (60 MHz / 4)
#define HEARTBEAT_DELAY ONE_SECOND/1000
#define PWM_PERIOD ONE_SECOND/1000
#define ATD_PRESCALER 4 // divide PCLK by this value+1

// IRQ v. FIQ v. SWI v. ?
void t0_isr() __attribute__((interrupt("IRQ")));
void dummy_isr() __attribute__((interrupt("IRQ")));
void ad0_isr() __attribute__((interrupt("IRQ")));

void dummy_isr()
{
    IOPIN1 = 0x0f00000;
    return;
}

volatile unsigned long g_right_ctr;
volatile unsigned long g_left_ctr;
volatile int g_heartbeat;
volatile unsigned long g_time;
volatile unsigned int g_avin;
volatile unsigned int g_right_distance;
volatile unsigned int g_center_distance;
volatile unsigned int g_left_distance;
volatile unsigned int g_right_distance1;
volatile unsigned int g_center_distance1;
volatile unsigned int g_left_distance1;

void update_LEDs()
{
    // FIXME: % 3 is not stable wrt overflows
    IOPIN1 =
        0x0040000 >> ((g_right_ctr/512/4) % 3)
        | 0x0080000 << ((g_left_ctr/512/4) % 3)
        | g_heartbeat * 0x0400000;
    /*
    IOPIN1 = (g_ad0chnl) << 16;
    IOPIN1 = (g_avin) << 16;
    */
}


void update_sensors()
{
    static init = 0;
    static int i = 0;
    static int min_center;
    if(init == 0) {
        init = 1;
        g_center_distance1 = g_center_distance;
    }
    if(i == 0) {
        min_center = g_center_distance;
        i++;
    }
    else {
        min_center = MIN(min_center, g_center_distance);
        i++;
    }
    if(i == 10) {
        //g_center_distance1 = min_center;
        i = 0;
    }
    g_center_distance1 = (g_center_distance * 5 + g_center_distance1 * 95)/100;
}

void set_right_pwm(int value) // value: -1000...1000
{
    int value1;
    if(value < 0) {
        value1 = -value;
        IOPIN0 &= ~(1 << 23);
    }
    else {
        value1 = value;
        IOPIN0 |= 1 << 23;
    }
    if(value1 > 1000) value1 = 1000;
    PWMMR2 = PWM_PERIOD - PWM_PERIOD * value1 / 1000;
    PWMLER = 0x7f; // enable latch loading on PWMMR0 match
}

void set_left_pwm(int value) // value: -1000...1000
{
    int value1;
    if(value < 0) {
        value1 = -value;
        IOPIN0 |= 1 << 17;
    }
    else {
        value1 = value;
        IOPIN0 &= ~(1 << 17);
    }
    if(value1 > 1000) value1 = 1000;
    PWMMR5 = PWM_PERIOD - PWM_PERIOD * value1 / 1000;
    PWMLER = 0x7f; // enable latch loading on PWMMR0 match
}

void t0_isr()
{
    if(T0IR & 0x01) { // MR0
        g_heartbeat = !g_heartbeat;
        g_time++;
        T0MR0 = T0MR0 + HEARTBEAT_DELAY;
        T0IR = 0x01;
    }
    if(T0IR & 0x40) { // CR2 Brwn - right ch A - P0.16
        int direction = !!(IOPIN0 & (1 << 27)); // Red - right ch B - P0.27
        if(direction) {
            g_right_ctr++;
        }
        else {
            g_right_ctr--;
        }
        T0IR = 0x40;
    }
    if(T0IR & 0x80) { // CR3 Orng - left ch A - P0.29
        int direction = !(IOPIN0 & (1 << 30)); // Yell - left ch B - P0.30
        if(direction) {
            g_left_ctr++;
        }
        else {
            g_left_ctr--;
        }
        T0IR = 0x80;
    }

    // Don't do this:
    //T0IR = T0IR; // clear all timer0 interrupt sources
    VICVectAddr = 0x0ff; // what is this all about???
    return;
}

void ad0_isr()
{
    unsigned long ad0dr;
    int chnl;
    int value;
    ad0dr = AD0DR;
    chnl = (ad0dr >> 24) & 0x07;
    value = (ad0dr >> 6) & 0x03ff;
    switch(chnl) {
    case 1: g_avin = value; break;
    case 6: g_right_distance = value; break;
    case 7: g_center_distance = value; break;
    case 8: g_left_distance = value; break;
    default:
        break;
    }
    VICVectAddr = 0x0ff; // what is this all about???
    return;
}

int main()
{
    // p. 172: Register map
    // p. 180: Timer block diagram
    T0TCR = 0x01; // Counter enable
    T0CTCR = 0x00; // Mode: timer (v. counter)
    T0PR = 0x0; // No prescaling on PCLK
    T0MCR = 0x01; // Enable interrupt MR0I
    T0CCR = 0x00; // No capture;
    T0MR0 = T0TC + 10000; // 12000000/2;
    g_time = 0;

    // setup PLL: 60 MHz CCLK, 15 MHz PCLK
    // p. 27
    // P    Divide by       M   Mulitply by
    // 0    1               0   1
    // 1    2               1   2
    // 2    4               2   3
    // 3    8               3   4
    //                      4   5 etc.
    PLLCFG = 0x024; // P = 2 (div 4), M = 4 (mult 5)
    PLLCON = 0x01; // enable PLL
    PLLFEED = 0x0aa;
    PLLFEED = 0x055;
    IOPIN1 = 0x0810000;
    while(!(PLLSTAT & 0x0400)); // wait for lock...
    PLLCON = 0x03; // connect the PLL
    PLLFEED = 0x0aa;
    PLLFEED = 0x055;
    // p. 38
    // PCLK:
    // 0 = CCLK divide by 4
    // 1 = CCLK divide by 1
    // 2 = CCLK divide by 2
    VPBDIV = 0x00;

    // setup cap0.2 interrupt (Brwn - right ch A - P0.16)
    // p. 177 - capture rising edges and generate interrupt
    T0CCR |= 5 << 6;
    // p. 76 - P0.16 -> CAP0.2
    PINSEL1 |= 3 << 0;
    g_right_ctr = 0;

    // setup cap0.3 interrupt (Orng - left ch A - P0.29)
    T0CCR |= 5 << 9;
    PINSEL1 |= 2 << 26;
    g_left_ctr = 0;

    // Setup and enable PWM
    PWMPR = 0;
    PWMMR0 = ONE_SECOND/1000;
    //PWMEMR = ;
    PWMTCR = 0x02; // reset
    PWMTCR = 0x09; // enable
    //PWMMCR |= 2 << 0; // PWMMR0 causes reset of PWMTC
    PWMMCR = 3;

    // setup PWM2 (Grn - right enable - P0.7)
    // p. 183 - block diagram
    // p. 186
    // PWMTC is incremented every PWMPR+1 of PCLK
    PINSEL0 |= 2 << 14;
    PWMPCR |= 0 << 2; // Single edge (PWMMR0 causes set)
    PWMPCR |= 1 << 10; // Enable PWM2 output
    IODIR0 |= 1 << 23;

    // setup PWM5 (Violet - left enable - P0.21)
    PINSEL1 |= 1 << 10;
    PWMPCR |= 0 << 5; // Single edge (PWMMR0 causes set)
    PWMPCR |= 1 << 13; // Enable PWM5 output
    IODIR0 |= 1 << 17;
    //IOPIN0 |= (1 << 17);
    //IOPIN0 &= ~(1 << 17);

    // setup ATD (pot on P0.28/AIN1)
    // p. 194
    PINSEL1 |= 1 << 24; // AVIN Pot
    PINSEL0 |= 3 << 8; // Whit - right GP2D12 - P0.4 AIN6
    PINSEL0 |= 3 << 10;  // Orng - center GP2D120 - P0.5 AIN7
    AD0CR = 0x0ff  // enable all channels
             | (ATD_PRESCALER << 8)
             | (1 << 16)  // burst mode
             | (0 << 17)  // CLKS: 11 clock cycles, 10 bits
             | (1 << 21)  // PDN: ATD is operational (v. powered down)
             | (0 << 24); // START: use burst mode
    g_avin = 0x055;

    // setup LED's
    IOPIN1 |= 0x0f00000;
    IODIR1 |= 0x0ff0000;

    MEMMAP = 1; // interrupt vectors reside in flash

    VICProtection = 0;
    VICIntEnClr = 0xffffffbf;
    VICDefVectAddr = dummy_isr;


    // FIXME: hyperlink this to relevant documentation
    // p. 49: VIC register map
    VICVectCntl4 = 0x20 | 4; // connect interrupt TIMER0 to VICVectAddr4
    VICVectAddr4 = t0_isr; // connect VICVectAddr4 to t0_irq()
    VICIntEnable = 1 << 4; // enable TIMER0 IRQ
    VICIntSelect = 0;
    
    VICVectCntl5 = (1 << 5) | 18;
    VICVectAddr5 = ad0_isr;
    VICIntEnable |= 1 << 18; // Enable AD0
    //VICIntEnClr = 1 << 4; // This disables the interrupt

    {
        int error;
        int time = g_time;
        int min_center;
        int x = -1000;
        int xi = 1;
        while(1) {
            update_LEDs();
            if((T0MR0 - T0TC) > HEARTBEAT_DELAY) {
                // hope this doesn't happen: it's bad!
                // ...but, sadly it does happen (when T0IR is frequent).  Why?
                T0MR0 = T0TC + HEARTBEAT_DELAY;
            }
            error = 512 - g_center_distance1;
            if(g_center_distance > 220) {
                set_right_pwm(2*error);
                set_left_pwm(2*error);
            }
            else {
                set_right_pwm(0);
                set_left_pwm(0);
            }
            if((g_time - time) > 0) {
                time++;
                update_sensors();
            }
        }
    }
    return 9876;
}

2. Makefile

TARGET = robotest.hex

CC = arm-unknown-elf-newlib-gcc
OBJCOPY = arm-unknown-elf-newlib-objcopy
OBJDUMP = arm-unknown-elf-newlib-objdump
SIZE = arm-unknown-elf-newlib-size
READELF = arm-unknown-elf-newlib-readelf
LDFLAGS = -nostartfiles -nostdlib -TLPC2106-ROM.ld
CFLAGS = -mcpu=arm7tdmi -O2

ISP = ./lpc21isp

.PHONY: info clean scan load

%.hex: %
        $(OBJCOPY) -O ihex $< $@
        echo Size of $<:
        $(SIZE) --target=ihex $<

%.lst: %
        $(OBJDUMP) -S $< > $@

%.d: %.hex
        # FIXME: this doesn't produce any assembly code...
        $(OBJDUMP) --target=ihex -m arm7tdmi -S $< > $@

%.S: %.c
        $(CC) $(CFLAGS) -S $< -o $@

all: $(TARGET)

clean:
        rm robotest.hex robotest *.o

scan:
        $(ISP) -detectonly -control foo /dev/ttyS0 9600 15000 # 12000

load:
        $(ISP) -PHILIPSARM -control $(TARGET) /dev/ttyS0 9600 12000

info:
        $(READELF) -S robotest
        $(SIZE) --target=ihex robotest.hex

robotest: robotest.o crt0.o

3. LPC2106-ROM.ld

I don't know where the copyright for this files belongs. I did not write it...

/***********************************************************************/
/*                                                                     */
/*  ROM.ld:  Linker Script File                                        */
/*                                                                     */
/***********************************************************************/
ENTRY(_boot)
STACK_SIZE = 0x400;

/* Memory Definitions */
MEMORY
{
  ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000
  RAM (rw) : ORIGIN = 0x40000000, LENGTH = 0x00010000
}

/* Section Definitions */
SECTIONS
{
  /* first section is .text which is used for code */
  .text :
  {
    *crt0.o (.text)            /* Startup code */
    *(.text)                   /* remaining code */
    *(.rodata)                 /* read-only data (constants) */
    *(.rodata*)
    *(.glue_7)
    *(.glue_7t)
  } > ROM

  . = ALIGN(4);
  _etext = . ;
  PROVIDE (etext = .);

  /* .data section which is used for initialized data */
  .data : AT (_etext)
  {
    _data = .;
    *(.data)
  } > RAM
 
  . = ALIGN(4);
  _edata = . ;
  PROVIDE (edata = .);

  /* .bss section which is used for uninitialized data */
  .bss (NOLOAD) :
  {
    __bss_start = . ;
    __bss_start__ = . ;
    *(.bss)
    *(COMMON)
    . = ALIGN(4);
  } > RAM

  . = ALIGN(4);
  __bss_end__ = . ;
  PROVIDE (__bss_end = .);

  .stack ALIGN(256) :
  {
    . += STACK_SIZE;
    PROVIDE (_stack = .);
  } > RAM

  _end = . ;
  PROVIDE (end = .);

  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
}

4. crt0.S

        .global main                    // int main(void)

        .global _etext                  // -> .data initial values in ROM
        .global _data                   // -> .data area in RAM
        .global _edata                  // end of .data area
        .global __bss_start             // -> .bss area in RAM
        .global __bss_end__             // end of .bss area
        .global _stack                  // top of stack

// Stack Sizes
        .set  UND_STACK_SIZE, 0x00000004
        .set  ABT_STACK_SIZE, 0x00000004
        .set  FIQ_STACK_SIZE, 0x00000004
        .set  IRQ_STACK_SIZE, 0X00000080
        .set  SVC_STACK_SIZE, 0x00000004

// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
        .set  MODE_USR, 0x10            // User Mode
        .set  MODE_FIQ, 0x11            // FIQ Mode
        .set  MODE_IRQ, 0x12            // IRQ Mode
        .set  MODE_SVC, 0x13            // Supervisor Mode
        .set  MODE_ABT, 0x17            // Abort Mode
        .set  MODE_UND, 0x1B            // Undefined Mode
        .set  MODE_SYS, 0x1F            // System Mode

        .equ  I_BIT, 0x80               // when I bit is set, IRQ is disabled
        .equ  F_BIT, 0x40               // when F bit is set, FIQ is disabled

        .text
        .code 32
        .align 2

        .global _boot
        .func   _boot
_boot:

// Runtime Interrupt Vectors
// -------------------------
Vectors:
        b     _start                    // reset - _start
        ldr   pc,_undf                  // undefined - _undf
        ldr   pc,_swi                   // SWI - _swi
        ldr   pc,_pabt                  // program abort - _pabt
        ldr   pc,_dabt                  // data abort - _dabt
        nop                             // reserved
        ldr   pc,[pc,#-0xFF0]           // IRQ - read the VIC
        ldr   pc,_fiq                   // FIQ - _fiq

#if 0
// Use this group for production
_undf:  .word _reset                    // undefined - _reset
_swi:   .word _reset                    // SWI - _reset
_pabt:  .word _reset                    // program abort - _reset
_dabt:  .word _reset                    // data abort - _reset
_irq:   .word _reset                    // IRQ - _reset
_fiq:   .word _reset                    // FIQ - _reset

#else
// Use this group for development
_undf:  .word __undf                    // undefined
_swi:   .word __swi                     // SWI
_pabt:  .word __pabt                    // program abort
_dabt:  .word __dabt                    // data abort
_irq:   .word __irq                     // IRQ
_fiq:   .word __fiq                     // FIQ

__undf: b     .                         // undefined
__swi:  b     .                         // SWI
__pabt: b     .                         // program abort
__dabt: b     .                         // data abort
__irq:  b     .                         // IRQ
__fiq:  b     .                         // FIQ
#endif
        .size _boot, . - _boot
        .endfunc


// Setup the operating mode & stack.
// ---------------------------------
        .global _start, start, _mainCRTStartup
        .func   _start

_start:
start:
_mainCRTStartup:

// Initialize Interrupt System
// - Set stack location for each mode
// - Leave in System Mode with Interrupts Disabled
// -----------------------------------------------
        ldr   r0,=_stack
        msr   CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
        mov   sp,r0
        sub   r0,r0,#UND_STACK_SIZE
        msr   CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
        mov   sp,r0
        sub   r0,r0,#ABT_STACK_SIZE
        msr   CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
        mov   sp,r0
        sub   r0,r0,#FIQ_STACK_SIZE
        msr   CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
        mov   sp,r0
        sub   r0,r0,#IRQ_STACK_SIZE
        msr   CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
        mov   sp,r0
        sub   r0,r0,#SVC_STACK_SIZE
        //msr   CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
        msr   CPSR_c,#MODE_SYS|F_BIT // System Mode
        mov   sp,r0

// Copy initialized data to its execution address in RAM
// -----------------------------------------------------
#ifdef ROM_RUN
        ldr   r1,=_etext                // -> ROM data start
        ldr   r2,=_data                 // -> data start
        ldr   r3,=_edata                // -> end of data
1:      cmp   r2,r3                     // check if data to move
        ldrlo r0,[r1],#4                // copy it
        strlo r0,[r2],#4
        blo   1b                        // loop until done
#endif
// Clear .bss
// ----------
        mov   r0,#0                     // get a zero
        ldr   r1,=__bss_start           // -> bss start
        ldr   r2,=__bss_end__           // -> bss end
2:      cmp   r1,r2                     // check if data to clear
        strlo r0,[r1],#4                // clear 4 bytes
        blo   2b                        // loop until done

// Call main program: main(0)
// --------------------------
        mov   r0,#0                     // no arguments (argc = 0)
        mov   r1,r0
        mov   r2,r0
        mov   fp,r0                     // null frame pointer
        mov   r7,r0                     // null frame pointer for thumb
        ldr   r10,=main
        mov   lr,pc
        bx    r10                       // enter main()

        .size   _start, . - _start
        .endfunc

        .global _reset, reset, exit, abort
        .func   _reset
_reset:
reset:
exit:
abort:
#if 0
// Disable interrupts, then force a hardware reset by driving P23 low
// -------------------------------------------------------------------
        mrs   r0,cpsr                   // get PSR
        orr   r0,r0,#I_BIT|F_BIT        // disable IRQ and FIQ
        msr   cpsr,r0                   // set up status register

        ldr   r1,=(PS_BASE)             // PS Base Address
        ldr   r0,=(PS_PIO)              // PIO Module
        str   r0,[r1,#PS_PCER_OFF]      // enable its clock
        ldr   r1,=(PIO_BASE)            // PIO Base Address
        ldr   r0,=(1<<23)               // P23
        str   r0,[r1,#PIO_PER_OFF]      // make sure pin is contolled by PIO
        str   r0,[r1,#PIO_CODR_OFF]     // set the pin low
        str   r0,[r1,#PIO_OER_OFF]      // make it an output
#endif
        b     .                         // loop until reset

        .size _reset, . - _reset
        .endfunc

        .end

5. lpc213x.h

/***********************************************************************/
/*  This file is part of the uVision/ARM development tools             */
/*  Copyright KEIL ELEKTRONIK GmbH 2002-2004                           */
/***********************************************************************/
/*                                                                     */
/*  LPC213X.H:  Header file for Philips LPC2132 / LPC2138              */
/*                                                                     */
/***********************************************************************/

#ifndef __LPC213x_H
#define __LPC213x_H

/* Vectored Interrupt Controller (VIC) */
#define VICIRQStatus   (*((volatile unsigned long *) 0xFFFFF000))
#define VICFIQStatus   (*((volatile unsigned long *) 0xFFFFF004))
#define VICRawIntr     (*((volatile unsigned long *) 0xFFFFF008))
#define VICIntSelect   (*((volatile unsigned long *) 0xFFFFF00C))
#define VICIntEnable   (*((volatile unsigned long *) 0xFFFFF010))
#define VICIntEnClr    (*((volatile unsigned long *) 0xFFFFF014))
#define VICSoftInt     (*((volatile unsigned long *) 0xFFFFF018))
#define VICSoftIntClr  (*((volatile unsigned long *) 0xFFFFF01C))
#define VICProtection  (*((volatile unsigned long *) 0xFFFFF020))
#define VICVectAddr    (*((volatile unsigned long *) 0xFFFFF030))
#define VICDefVectAddr (*((volatile unsigned long *) 0xFFFFF034))
#define VICVectAddr0   (*((volatile unsigned long *) 0xFFFFF100))
#define VICVectAddr1   (*((volatile unsigned long *) 0xFFFFF104))
#define VICVectAddr2   (*((volatile unsigned long *) 0xFFFFF108))
#define VICVectAddr3   (*((volatile unsigned long *) 0xFFFFF10C))
#define VICVectAddr4   (*((volatile unsigned long *) 0xFFFFF110))
#define VICVectAddr5   (*((volatile unsigned long *) 0xFFFFF114))
#define VICVectAddr6   (*((volatile unsigned long *) 0xFFFFF118))
#define VICVectAddr7   (*((volatile unsigned long *) 0xFFFFF11C))
#define VICVectAddr8   (*((volatile unsigned long *) 0xFFFFF120))
#define VICVectAddr9   (*((volatile unsigned long *) 0xFFFFF124))
#define VICVectAddr10  (*((volatile unsigned long *) 0xFFFFF128))
#define VICVectAddr11  (*((volatile unsigned long *) 0xFFFFF12C))
#define VICVectAddr12  (*((volatile unsigned long *) 0xFFFFF130))
#define VICVectAddr13  (*((volatile unsigned long *) 0xFFFFF134))
#define VICVectAddr14  (*((volatile unsigned long *) 0xFFFFF138))
#define VICVectAddr15  (*((volatile unsigned long *) 0xFFFFF13C))
#define VICVectCntl0   (*((volatile unsigned long *) 0xFFFFF200))
#define VICVectCntl1   (*((volatile unsigned long *) 0xFFFFF204))
#define VICVectCntl2   (*((volatile unsigned long *) 0xFFFFF208))
#define VICVectCntl3   (*((volatile unsigned long *) 0xFFFFF20C))
#define VICVectCntl4   (*((volatile unsigned long *) 0xFFFFF210))
#define VICVectCntl5   (*((volatile unsigned long *) 0xFFFFF214))
#define VICVectCntl6   (*((volatile unsigned long *) 0xFFFFF218))
#define VICVectCntl7   (*((volatile unsigned long *) 0xFFFFF21C))
#define VICVectCntl8   (*((volatile unsigned long *) 0xFFFFF220))
#define VICVectCntl9   (*((volatile unsigned long *) 0xFFFFF224))
#define VICVectCntl10  (*((volatile unsigned long *) 0xFFFFF228))
#define VICVectCntl11  (*((volatile unsigned long *) 0xFFFFF22C))
#define VICVectCntl12  (*((volatile unsigned long *) 0xFFFFF230))
#define VICVectCntl13  (*((volatile unsigned long *) 0xFFFFF234))
#define VICVectCntl14  (*((volatile unsigned long *) 0xFFFFF238))
#define VICVectCntl15  (*((volatile unsigned long *) 0xFFFFF23C))

/* Pin Connect Block */
#define PINSEL0        (*((volatile unsigned long *) 0xE002C000))
#define PINSEL1        (*((volatile unsigned long *) 0xE002C004))
#define PINSEL2        (*((volatile unsigned long *) 0xE002C014))

/* General Purpose Input/Output (GPIO) */
#define IOPIN0         (*((volatile unsigned long *) 0xE0028000))
#define IOSET0         (*((volatile unsigned long *) 0xE0028004))
#define IODIR0         (*((volatile unsigned long *) 0xE0028008))
#define IOCLR0         (*((volatile unsigned long *) 0xE002800C))
#define IOPIN1         (*((volatile unsigned long *) 0xE0028010))
#define IOSET1         (*((volatile unsigned long *) 0xE0028014))
#define IODIR1         (*((volatile unsigned long *) 0xE0028018))
#define IOCLR1         (*((volatile unsigned long *) 0xE002801C))

/* Memory Accelerator Module (MAM) */
#define MAMCR          (*((volatile unsigned char *) 0xE01FC000))
#define MAMTIM         (*((volatile unsigned char *) 0xE01FC004))
#define MEMMAP         (*((volatile unsigned char *) 0xE01FC040))

/* Phase Locked Loop (PLL) */
#define PLLCON         (*((volatile unsigned char *) 0xE01FC080))
#define PLLCFG         (*((volatile unsigned char *) 0xE01FC084))
#define PLLSTAT        (*((volatile unsigned short*) 0xE01FC088))
#define PLLFEED        (*((volatile unsigned char *) 0xE01FC08C))

/* VPB Divider */
#define VPBDIV         (*((volatile unsigned char *) 0xE01FC100))

/* Power Control */
#define PCON           (*((volatile unsigned char *) 0xE01FC0C0))
#define PCONP          (*((volatile unsigned long *) 0xE01FC0C4))

/* External Interrupts */
#define EXTINT         (*((volatile unsigned char *) 0xE01FC140))
#define INTWAKE        (*((volatile unsigned char *) 0xE01FC144))
#define EXTMODE        (*((volatile unsigned char *) 0xE01FC148))
#define EXTPOLAR       (*((volatile unsigned char *) 0xE01FC14C))

/* Reset */
#define RSID           (*((volatile unsigned char *) 0xE01FC180))

/* Code Security / Debugging */
#define CSPR           (*((volatile unsigned char *) 0xE01FC184))

/* Timer 0 */
#define T0IR           (*((volatile unsigned long *) 0xE0004000))
#define T0TCR          (*((volatile unsigned long *) 0xE0004004))
#define T0TC           (*((volatile unsigned long *) 0xE0004008))
#define T0PR           (*((volatile unsigned long *) 0xE000400C))
#define T0PC           (*((volatile unsigned long *) 0xE0004010))
#define T0MCR          (*((volatile unsigned long *) 0xE0004014))
#define T0MR0          (*((volatile unsigned long *) 0xE0004018))
#define T0MR1          (*((volatile unsigned long *) 0xE000401C))
#define T0MR2          (*((volatile unsigned long *) 0xE0004020))
#define T0MR3          (*((volatile unsigned long *) 0xE0004024))
#define T0CCR          (*((volatile unsigned long *) 0xE0004028))
#define T0CR0          (*((volatile unsigned long *) 0xE000402C))
#define T0CR1          (*((volatile unsigned long *) 0xE0004030))
#define T0CR2          (*((volatile unsigned long *) 0xE0004034))
#define T0CR3          (*((volatile unsigned long *) 0xE0004038))
#define T0EMR          (*((volatile unsigned long *) 0xE000403C))
#define T0CTCR         (*((volatile unsigned long *) 0xE0004070))

/* Timer 1 */
#define T1IR           (*((volatile unsigned long *) 0xE0008000))
#define T1TCR          (*((volatile unsigned long *) 0xE0008004))
#define T1TC           (*((volatile unsigned long *) 0xE0008008))
#define T1PR           (*((volatile unsigned long *) 0xE000800C))
#define T1PC           (*((volatile unsigned long *) 0xE0008010))
#define T1MCR          (*((volatile unsigned long *) 0xE0008014))
#define T1MR0          (*((volatile unsigned long *) 0xE0008018))
#define T1MR1          (*((volatile unsigned long *) 0xE000801C))
#define T1MR2          (*((volatile unsigned long *) 0xE0008020))
#define T1MR3          (*((volatile unsigned long *) 0xE0008024))
#define T1CCR          (*((volatile unsigned long *) 0xE0008028))
#define T1CR0          (*((volatile unsigned long *) 0xE000802C))
#define T1CR1          (*((volatile unsigned long *) 0xE0008030))
#define T1CR2          (*((volatile unsigned long *) 0xE0008034))
#define T1CR3          (*((volatile unsigned long *) 0xE0008038))
#define T1EMR          (*((volatile unsigned long *) 0xE000803C))
#define T1CTCR         (*((volatile unsigned long *) 0xE0008070))

/* Pulse Width Modulator (PWM) */
#define PWMIR          (*((volatile unsigned long *) 0xE0014000))
#define PWMTCR         (*((volatile unsigned long *) 0xE0014004))
#define PWMTC          (*((volatile unsigned long *) 0xE0014008))
#define PWMPR          (*((volatile unsigned long *) 0xE001400C))
#define PWMPC          (*((volatile unsigned long *) 0xE0014010))
#define PWMMCR         (*((volatile unsigned long *) 0xE0014014))
#define PWMMR0         (*((volatile unsigned long *) 0xE0014018))
#define PWMMR1         (*((volatile unsigned long *) 0xE001401C))
#define PWMMR2         (*((volatile unsigned long *) 0xE0014020))
#define PWMMR3         (*((volatile unsigned long *) 0xE0014024))
#define PWMMR4         (*((volatile unsigned long *) 0xE0014040))
#define PWMMR5         (*((volatile unsigned long *) 0xE0014044))
#define PWMMR6         (*((volatile unsigned long *) 0xE0014048))
#define PWMCCR         (*((volatile unsigned long *) 0xE0014028))
#define PWMCR0         (*((volatile unsigned long *) 0xE001402C))
#define PWMCR1         (*((volatile unsigned long *) 0xE0014030))
#define PWMCR2         (*((volatile unsigned long *) 0xE0014034))
#define PWMCR3         (*((volatile unsigned long *) 0xE0014038))
#define PWMEMR         (*((volatile unsigned long *) 0xE001403C))
#define PWMPCR         (*((volatile unsigned long *) 0xE001404C))
#define PWMLER         (*((volatile unsigned long *) 0xE0014050))

/* Universal Asynchronous Receiver Transmitter 0 (UART0) */
#define U0RBR          (*((volatile unsigned char *) 0xE000C000))
#define U0THR          (*((volatile unsigned char *) 0xE000C000))
#define U0IER          (*((volatile unsigned char *) 0xE000C004))
#define U0IIR          (*((volatile unsigned char *) 0xE000C008))
#define U0FCR          (*((volatile unsigned char *) 0xE000C008))
#define U0LCR          (*((volatile unsigned char *) 0xE000C00C))
#define U0MCR          (*((volatile unsigned char *) 0xE000C010))
#define U0LSR          (*((volatile unsigned char *) 0xE000C014))
#define U0MSR          (*((volatile unsigned char *) 0xE000C018))
#define U0SCR          (*((volatile unsigned char *) 0xE000C01C))
#define U0DLL          (*((volatile unsigned char *) 0xE000C000))
#define U0DLM          (*((volatile unsigned char *) 0xE000C004))

/* Universal Asynchronous Receiver Transmitter 1 (UART1) */
#define U1RBR          (*((volatile unsigned char *) 0xE0010000))
#define U1THR          (*((volatile unsigned char *) 0xE0010000))
#define U1IER          (*((volatile unsigned char *) 0xE0010004))
#define U1IIR          (*((volatile unsigned char *) 0xE0010008))
#define U1FCR          (*((volatile unsigned char *) 0xE0010008))
#define U1LCR          (*((volatile unsigned char *) 0xE001000C))
#define U1MCR          (*((volatile unsigned char *) 0xE0010010))
#define U1LSR          (*((volatile unsigned char *) 0xE0010014))
#define U1MSR          (*((volatile unsigned char *) 0xE0010018))
#define U1SCR          (*((volatile unsigned char *) 0xE001001C))
#define U1DLL          (*((volatile unsigned char *) 0xE0010000))
#define U1DLM          (*((volatile unsigned char *) 0xE0010004))

/* I2C Interface 0 */
#define I20CONSET      (*((volatile unsigned char *) 0xE001C000))
#define I20STAT        (*((volatile unsigned char *) 0xE001C004))
#define I20DAT         (*((volatile unsigned char *) 0xE001C008))
#define I20ADR         (*((volatile unsigned char *) 0xE001C00C))
#define I20SCLH        (*((volatile unsigned short*) 0xE001C010))
#define I20SCLL        (*((volatile unsigned short*) 0xE001C014))
#define I20CONCLR      (*((volatile unsigned char *) 0xE001C018))

/* I2C Interface 1 */
#define I21CONSET      (*((volatile unsigned char *) 0xE005C000))
#define I21STAT        (*((volatile unsigned char *) 0xE005C004))
#define I21DAT         (*((volatile unsigned char *) 0xE005C008))
#define I21ADR         (*((volatile unsigned char *) 0xE005C00C))
#define I21SCLH        (*((volatile unsigned short*) 0xE005C010))
#define I21SCLL        (*((volatile unsigned short*) 0xE005C014))
#define I21CONCLR      (*((volatile unsigned char *) 0xE005C018))

/* SPI0 (Serial Peripheral Interface 0) */
#define S0SPCR         (*((volatile unsigned char *) 0xE0020000))
#define S0SPSR         (*((volatile unsigned char *) 0xE0020004))
#define S0SPDR         (*((volatile unsigned char *) 0xE0020008))
#define S0SPCCR        (*((volatile unsigned char *) 0xE002000C))
#define S0SPTCR        (*((volatile unsigned char *) 0xE0020010))
#define S0SPTSR        (*((volatile unsigned char *) 0xE0020014))
#define S0SPTOR        (*((volatile unsigned char *) 0xE0020018))
#define S0SPINT        (*((volatile unsigned char *) 0xE002001C))

/* SSP Controller */
#define SSPCR0         (*((volatile unsigned short* ) 0xE0068000))
#define SSPCR1         (*((volatile unsigned char * ) 0xE0068004))
#define SSPDR          (*((volatile unsigned short* ) 0xE0068008))
#define SSPSR          (*((volatile unsigned char * ) 0xE006800C))
#define SSPCPSR        (*((volatile unsigned char * ) 0xE0068010))
#define SSPIMSC        (*((volatile unsigned char * ) 0xE0068014))
#define SSPRIS         (*((volatile unsigned char * ) 0xE0068018))
#define SSPMIS         (*((volatile unsigned char * ) 0xE006801C))
#define SSPICR         (*((volatile unsigned char * ) 0xE0068020))
#define SSPDMACR       (*((volatile unsigned char * ) 0xE0068024))

/* Real Time Clock */
#define ILR            (*((volatile unsigned char *) 0xE0024000))
#define CTC            (*((volatile unsigned short*) 0xE0024004))
#define CCR            (*((volatile unsigned char *) 0xE0024008))
#define CIIR           (*((volatile unsigned char *) 0xE002400C))
#define AMR            (*((volatile unsigned char *) 0xE0024010))
#define CTIME0         (*((volatile unsigned long *) 0xE0024014))
#define CTIME1         (*((volatile unsigned long *) 0xE0024018))
#define CTIME2         (*((volatile unsigned long *) 0xE002401C))
#define SEC            (*((volatile unsigned char *) 0xE0024020))
#define MIN            (*((volatile unsigned char *) 0xE0024024))
#define HOUR           (*((volatile unsigned char *) 0xE0024028))
#define DOM            (*((volatile unsigned char *) 0xE002402C))
#define DOW            (*((volatile unsigned char *) 0xE0024030))
#define DOY            (*((volatile unsigned short*) 0xE0024034))
#define MONTH          (*((volatile unsigned char *) 0xE0024038))
#define YEAR           (*((volatile unsigned short*) 0xE002403C))
#define ALSEC          (*((volatile unsigned char *) 0xE0024060))
#define ALMIN          (*((volatile unsigned char *) 0xE0024064))
#define ALHOUR         (*((volatile unsigned char *) 0xE0024068))
#define ALDOM          (*((volatile unsigned char *) 0xE002406C))
#define ALDOW          (*((volatile unsigned char *) 0xE0024070))
#define ALDOY          (*((volatile unsigned short*) 0xE0024074))
#define ALMON          (*((volatile unsigned char *) 0xE0024078))
#define ALYEAR         (*((volatile unsigned short*) 0xE002407C))
#define PREINT         (*((volatile unsigned short*) 0xE0024080))
#define PREFRAC        (*((volatile unsigned short*) 0xE0024084))

/* A/D Converter 0 (AD0) */
#define AD0CR          (*((volatile unsigned long *) 0xE0034000))
#define AD0DR          (*((volatile unsigned long *) 0xE0034004))

/* A/D Converter 1 (AD1) */
#define AD1CR          (*((volatile unsigned long *) 0xE0060000))
#define AD1DR          (*((volatile unsigned long *) 0xE0060004))

/* D/A Converter */
#define DACR           (*((volatile unsigned long *) 0xE006C000))


/* Watchdog */
#define WDMOD          (*((volatile unsigned char *) 0xE0000000))
#define WDTC           (*((volatile unsigned long *) 0xE0000004))
#define WDFEED         (*((volatile unsigned char *) 0xE0000008))
#define WDTV           (*((volatile unsigned long *) 0xE000000C))

#endif  // __LPC213x_H