#ifndef __armvic_h__
#define __armvic_h__

/* 
 * Register definitions for ARM PrimeCell Vectored Interrupt Controller (VIC) 
 *   in Philips LPC210x (ARM7TDMI-S)
 *
 * Registers must be read/written as a 32-bit quantity, 16- and 8- bit
 * operations are not permitted. Also note that the ARM7TDMI-S core 
 * implements a write-posting buffer to keep back-to-back memory writes
 * from stalling the ARM7 core. This means that values written to memory 
 * won't actually generate bus cycles unless followed by a second write. 
 * This does not affect internal register accesses (at least it is not noted
 * in the Philips documentation).
 *
 * Reference: ARM PrimeCell(tm) Vectored Interrupt Controller (PL192)
 *            Technical Reference Manual
 *            (December 2002, Issue A)
 *
 * Tim Meese
 * $Id: $
 * 
 */

#include "lpc210x.h"   /* for lpc210x_reg typedef and vector numbers */
#include "armirq.h"    /* ARM arch-specific IRQ handling defines */

#define VICIRQStatus    (*(lpc210x_reg *)0xfffff000) /* IRQ Status Register */
#define VICFIQStatus    (*(lpc210x_reg *)0xfffff004) /* FIQ Status Register */
#define VICRawIntr      (*(lpc210x_reg *)0xfffff008) /* Raw IRQ Status Reg */
#define VICIntSelect    (*(lpc210x_reg *)0xfffff00c) /* Interrupt Select Reg*/
#define VICIntEnable    (*(lpc210x_reg *)0xfffff010) /* Interrupt Enable Reg*/
#define VICIntEnClr     (*(lpc210x_reg *)0xfffff014) /* Interrupt Enable Clr*/
#define VICSoftInt      (*(lpc210x_reg *)0xfffff018) /* Software Int Reg*/
#define VICSoftIntClear (*(lpc210x_reg *)0xfffff01c) /* Software Int Clr Reg*/
#define VICProtection   (*(lpc210x_reg *)0xfffff020) /* Protection Enable Reg*/

#define VICSoftPrioMask (*(lpc210x_reg *)0xfffff024) /* SW Priority Mask Reg */
#define VICPrioDaisy    (*(lpc210x_reg *)0xfffff028) /* Daisy Chain Vec Prio */

#define VICVectAddrN(n) (*(lpc210x_reg *)(0xfffff100 + ((n)*4)))

#define VICVectAddr0     VICVectAddrN(0)   /* Vector ISR Addr  0  */
#define VICVectAddr1     VICVectAddrN(1)   /* Vector ISR Addr  1  */
#define VICVectAddr2     VICVectAddrN(2)   /* Vector ISR Addr  2  */
#define VICVectAddr3     VICVectAddrN(3)   /* Vector ISR Addr  3  */
#define VICVectAddr4     VICVectAddrN(4)   /* Vector ISR Addr  4  */
#define VICVectAddr5     VICVectAddrN(5)   /* Vector ISR Addr  5  */
#define VICVectAddr6     VICVectAddrN(6)   /* Vector ISR Addr  6  */
#define VICVectAddr7     VICVectAddrN(7)   /* Vector ISR Addr  7  */
#define VICVectAddr8     VICVectAddrN(8)   /* Vector ISR Addr  8  */
#define VICVectAddr9     VICVectAddrN(9)   /* Vector ISR Addr  9  */
#define VICVectAddr10    VICVectAddrN(10)  /* Vector ISR Addr  10 */
#define VICVectAddr11    VICVectAddrN(11)  /* Vector ISR Addr  11 */
#define VICVectAddr12    VICVectAddrN(12)  /* Vector ISR Addr  12 */
#define VICVectAddr13    VICVectAddrN(13)  /* Vector ISR Addr  13 */
#define VICVectAddr14    VICVectAddrN(14)  /* Vector ISR Addr  14 */
#define VICVectAddr15    VICVectAddrN(15)  /* Vector ISR Addr  15 */
#define VICVectAddr16    VICVectAddrN(16)  /* Vector ISR Addr  16 */
#define VICVectAddr17    VICVectAddrN(17)  /* Vector ISR Addr  17 */
#define VICVectAddr18    VICVectAddrN(18)  /* Vector ISR Addr  18 */
#define VICVectAddr19    VICVectAddrN(19)  /* Vector ISR Addr  19 */
#define VICVectAddr20    VICVectAddrN(20)  /* Vector ISR Addr  20 */
#define VICVectAddr21    VICVectAddrN(21)  /* Vector ISR Addr  21 */
#define VICVectAddr22    VICVectAddrN(22)  /* Vector ISR Addr  22 */
#define VICVectAddr23    VICVectAddrN(23)  /* Vector ISR Addr  23 */
#define VICVectAddr24    VICVectAddrN(24)  /* Vector ISR Addr  24 */
#define VICVectAddr25    VICVectAddrN(25)  /* Vector ISR Addr  25 */
#define VICVectAddr26    VICVectAddrN(26)  /* Vector ISR Addr  26 */
#define VICVectAddr27    VICVectAddrN(27)  /* Vector ISR Addr  27 */
#define VICVectAddr28    VICVectAddrN(28)  /* Vector ISR Addr  28 */
#define VICVectAddr29    VICVectAddrN(29)  /* Vector ISR Addr  29 */
#define VICVectAddr30    VICVectAddrN(30)  /* Vector ISR Addr  30 */
#define VICVectAddr31    VICVectAddrN(31)  /* Vector ISR Addr  31 */
#define VICVectAddr32    VICVectAddrN(32)  /* Vector ISR Addr  32 */

#define VICVectPrioN(n) (*(lpc210x_reg *)(0xfffff200 + ((n)*4)))

#define VICVectPrio0     VICVectPrioN(0)   /* Vector Priority  0  */
#define VICVectPrio1     VICVectPrioN(1)   /* Vector Priority  1  */
#define VICVectPrio2     VICVectPrioN(2)   /* Vector Priority  2  */
#define VICVectPrio3     VICVectPrioN(3)   /* Vector Priority  3  */
#define VICVectPrio4     VICVectPrioN(4)   /* Vector Priority  4  */
#define VICVectPrio5     VICVectPrioN(5)   /* Vector Priority  5  */
#define VICVectPrio6     VICVectPrioN(6)   /* Vector Priority  6  */
#define VICVectPrio7     VICVectPrioN(7)   /* Vector Priority  7  */
#define VICVectPrio8     VICVectPrioN(8)   /* Vector Priority  8  */
#define VICVectPrio9     VICVectPrioN(9)   /* Vector Priority  9  */
#define VICVectPrio10    VICVectPrioN(10)  /* Vector Priority  10 */
#define VICVectPrio11    VICVectPrioN(11)  /* Vector Priority  11 */
#define VICVectPrio12    VICVectPrioN(12)  /* Vector Priority  12 */
#define VICVectPrio13    VICVectPrioN(13)  /* Vector Priority  13 */
#define VICVectPrio14    VICVectPrioN(14)  /* Vector Priority  14 */
#define VICVectPrio15    VICVectPrioN(15)  /* Vector Priority  15 */
#define VICVectPrio16    VICVectPrioN(16)  /* Vector Priority  16 */
#define VICVectPrio17    VICVectPrioN(17)  /* Vector Priority  17 */
#define VICVectPrio18    VICVectPrioN(18)  /* Vector Priority  18 */
#define VICVectPrio19    VICVectPrioN(19)  /* Vector Priority  19 */
#define VICVectPrio20    VICVectPrioN(20)  /* Vector Priority  20 */
#define VICVectPrio21    VICVectPrioN(21)  /* Vector Priority  21 */
#define VICVectPrio22    VICVectPrioN(22)  /* Vector Priority  22 */
#define VICVectPrio23    VICVectPrioN(23)  /* Vector Priority  23 */
#define VICVectPrio24    VICVectPrioN(24)  /* Vector Priority  24 */
#define VICVectPrio25    VICVectPrioN(25)  /* Vector Priority  25 */
#define VICVectPrio26    VICVectPrioN(26)  /* Vector Priority  26 */
#define VICVectPrio27    VICVectPrioN(27)  /* Vector Priority  27 */
#define VICVectPrio28    VICVectPrioN(28)  /* Vector Priority  28 */
#define VICVectPrio29    VICVectPrioN(29)  /* Vector Priority  29 */
#define VICVectPrio30    VICVectPrioN(30)  /* Vector Priority  30 */
#define VICVectPrio31    VICVectPrioN(31)  /* Vector Priority  31 */
#define VICVectPrio32    VICVectPrioN(32)  /* Vector Priority  32 */

#define VICAddress      (*(lpc210x_reg *)0xffffff00) /* Vector Address Reg */

#define VICPeriphIdN(n) (*(lpc210x_reg *)(0xffffffe0 + ((n)*4)))

#define VICPeriphId0    VICPeriphIdN(0)  /* Periph Id [ 7: 0] */
#define VICPeriphId1    VICPeriphIdN(1)  /* Periph Id [15: 8] */
#define VICPeriphId2    VICPeriphIdN(2)  /* Periph Id [23:16] */
#define VICPeriphId3    VICPeriphIdN(3)  /* Periph Id [31:24] */

#define VICPCellIdN(n)  (*(lpc210x_reg *)(0xfffffff0 + ((n)*4)))

#define VICPCellId0     VICPCellIdN(0)  /* PrimeCell Id [ 7: 0] */
#define VICPCellId1     VICPCellIdN(1)  /* PrimeCell Id [15: 8] */
#define VICPCellId2     VICPCellIdN(2)  /* PrimeCell Id [23:16] */
#define VICPCellId3     VICPCellIdN(3)  /* PrimeCell Id [31:24] */

#ifdef __cplusplus
extern "C" {
#endif

int armvicInit(void);

int armvicIntConnect(int vecNum, void * isr);
int armvicIntDisconnect(int vecNum);

int armvicSoftIntAssert(int vecNum);
int armvicSoftIntNegate(int vecNum);
int armvicSoftIntNegateAll(void);

int armvicIntEnable(int vecNum);
int armvicIntDisable(int vecNum);

#ifdef __cplusplus
}
#endif

#endif /* __armvic_h__ */
