diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-19 18:29:40 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-19 18:29:40 +0000 |
commit | fc82157191bad57057ad7ae97ed74a26a05d307b (patch) | |
tree | 4d9c1ca7dbeb7c9be5c56797f9733e8caad4add0 | |
parent | 3c9ac1908bae6d6d4eb147366361aa28a1ca972a (diff) | |
download | px4-nuttx-fc82157191bad57057ad7ae97ed74a26a05d307b.tar.gz px4-nuttx-fc82157191bad57057ad7ae97ed74a26a05d307b.tar.bz2 px4-nuttx-fc82157191bad57057ad7ae97ed74a26a05d307b.zip |
Add PIC32 interrupt controls and timer initialization
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3628 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | nuttx/arch/arm/src/cortexm3/up_svcall.c | 2 | ||||
-rwxr-xr-x | nuttx/arch/mips/include/pic32mx/irq.h | 2 | ||||
-rwxr-xr-x | nuttx/arch/mips/src/common/up_internal.h | 1 | ||||
-rwxr-xr-x | nuttx/arch/mips/src/pic32mx/Make.defs | 2 | ||||
-rwxr-xr-x | nuttx/arch/mips/src/pic32mx/pic32mx-int.h | 86 | ||||
-rwxr-xr-x | nuttx/arch/mips/src/pic32mx/pic32mx-irq.c | 264 | ||||
-rwxr-xr-x | nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h | 3 | ||||
-rwxr-xr-x | nuttx/arch/mips/src/pic32mx/pic32mx-timerisr.c | 174 | ||||
-rw-r--r-- | nuttx/configs/pcblogic-pic32mx/README.txt | 60 | ||||
-rwxr-xr-x | nuttx/configs/pcblogic-pic32mx/include/board.h | 21 |
10 files changed, 550 insertions, 65 deletions
diff --git a/nuttx/arch/arm/src/cortexm3/up_svcall.c b/nuttx/arch/arm/src/cortexm3/up_svcall.c index 2ec1228b9..7764f9c09 100644 --- a/nuttx/arch/arm/src/cortexm3/up_svcall.c +++ b/nuttx/arch/arm/src/cortexm3/up_svcall.c @@ -234,7 +234,7 @@ static inline void dispatch_syscall(uint32_t *regs) int up_svcall(int irq, FAR void *context) { - uint32_t *regs = (uint32_t*)context; + uint32_t *regs = (uint32_t*)context; DEBUGASSERT(regs && regs == current_regs); diff --git a/nuttx/arch/mips/include/pic32mx/irq.h b/nuttx/arch/mips/include/pic32mx/irq.h index 0b55e9229..0d2aff173 100755 --- a/nuttx/arch/mips/include/pic32mx/irq.h +++ b/nuttx/arch/mips/include/pic32mx/irq.h @@ -164,7 +164,7 @@ #define PIC32MX_IRQSRC_DMA3 (128+51) /* Vector: 39, DMA Channel 3 */ #define PIC32MX_IRQSRC_FCE (128+56) /* Vector: 44, Flash Control Event */ #define PIC32MX_IRQSRC_USB (128+57) /* Vector: 45, USB */ -#define PIC32MX_IRQSRC1_FIRST (128+57) +#define PIC32MX_IRQSRC1_LAST (128+57) /**************************************************************************** * Public Types diff --git a/nuttx/arch/mips/src/common/up_internal.h b/nuttx/arch/mips/src/common/up_internal.h index 3baa91235..0ec2da698 100755 --- a/nuttx/arch/mips/src/common/up_internal.h +++ b/nuttx/arch/mips/src/common/up_internal.h @@ -218,6 +218,7 @@ extern void up_timerinit(void); /* Defined in up_irq.c */ extern void up_maskack_irq(int irq); +extern void up_clrpend_irq(int irq); /* Defined in board/up_leds.c */ diff --git a/nuttx/arch/mips/src/pic32mx/Make.defs b/nuttx/arch/mips/src/pic32mx/Make.defs index 3d607d64c..bcb267d33 100755 --- a/nuttx/arch/mips/src/pic32mx/Make.defs +++ b/nuttx/arch/mips/src/pic32mx/Make.defs @@ -61,7 +61,7 @@ endif # Required PIC32MX files CHIP_ASRCS = -CHIP_CSRCS = pic32mx-irq.c +CHIP_CSRCS = pic32mx-irq.c pic32mx-timerisr.c # Configuration-dependent PIC32MX files diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-int.h b/nuttx/arch/mips/src/pic32mx/pic32mx-int.h index 3479e6a03..985c350ba 100755 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-int.h +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-int.h @@ -61,10 +61,10 @@ #define PIC32MX_INT_TPTMRCLR_OFFSET 0x0024 /* Temporal proximity timer clear register */
#define PIC32MX_INT_TPTMRSET_OFFSET 0x0028 /* Temporal proximity timer set register */
#define PIC32MX_INT_TPTMRINV_OFFSET 0x002c /* Temporal proximity timer invert register */
-#define PIC32MX_INT_IFS_OFFSET(n) (0x0030 + 0x10*(n))
-#define PIC32MX_INT_IFSCLR_OFFSET(n) (0x0034 + 0x10*(n))
-#define PIC32MX_INT_IFSSET_OFFSET(n) (0x0038 + 0x10*(n))
-#define PIC32MX_INT_IFSINV_OFFSET(n) (0x003c + 0x10*(n))
+#define PIC32MX_INT_IFS_OFFSET(n) (0x0030 + ((n) << 4))
+#define PIC32MX_INT_IFSCLR_OFFSET(n) (0x0034 + ((n) << 4))
+#define PIC32MX_INT_IFSSET_OFFSET(n) (0x0038 + ((n) << 4))
+#define PIC32MX_INT_IFSINV_OFFSET(n) (0x003c + ((n) << 4))
#define PIC32MX_INT_IFS0_OFFSET 0x0030 /* Interrupt flag status register 0 */
#define PIC32MX_INT_IFS0CLR_OFFSET 0x0034 /* Interrupt flag status clear register 0 */
#define PIC32MX_INT_IFS0SET_OFFSET 0x0038 /* Interrupt flag status set register 0 */
@@ -73,10 +73,10 @@ #define PIC32MX_INT_IFS1CLR_OFFSET 0x0044 /* Interrupt flag status clear register 1 */
#define PIC32MX_INT_IFS1SET_OFFSET 0x0048 /* Interrupt flag status set register 1 */
#define PIC32MX_INT_IFS1INV_OFFSET 0x004c /* Interrupt flag status invert register 1 */
-#define PIC32MX_INT_IEC_OFFSET(n) (0x0060 + 0x10*(n))
-#define PIC32MX_INT_IECCLR_OFFSET(n) (0x0064 + 0x10*(n))
-#define PIC32MX_INT_IECSET_OFFSET(n) (0x0068 + 0x10*(n))
-#define PIC32MX_INT_IECINV_OFFSET(n) (0x006c + 0x10*(n))
+#define PIC32MX_INT_IEC_OFFSET(n) (0x0060 + ((n) << 4))
+#define PIC32MX_INT_IECCLR_OFFSET(n) (0x0064 + ((n) << 4))
+#define PIC32MX_INT_IECSET_OFFSET(n) (0x0068 + ((n) << 4))
+#define PIC32MX_INT_IECINV_OFFSET(n) (0x006c + ((n) << 4))
#define PIC32MX_INT_IEC0_OFFSET 0x0060 /* Interrupt enable control register 0 */
#define PIC32MX_INT_IEC0CLR_OFFSET 0x0064 /* Interrupt enable control clear register 0 */
#define PIC32MX_INT_IEC0SET_OFFSET 0x0068 /* Interrupt enable control set register 0 */
@@ -85,10 +85,10 @@ #define PIC32MX_INT_IEC1CLR_OFFSET 0x0074 /* Interrupt enable control clear register 1 */
#define PIC32MX_INT_IEC1SET_OFFSET 0x0078 /* Interrupt enable control set register 1 */
#define PIC32MX_INT_IEC1INV_OFFSET 0x007c /* Interrupt enable control invert register 1 */
-#define PIC32MX_INT_IPC_OFFSET(n) (0x0090 + 0x10*(n))
-#define PIC32MX_INT_IPCCLR_OFFSET(n) (0x0094 + 0x10*(n))
-#define PIC32MX_INT_IPCSET_OFFSET(n) (0x0098 + 0x10*(n))
-#define PIC32MX_INT_IPCINV_OFFSET(n) (0x009c + 0x10*(n))
+#define PIC32MX_INT_IPC_OFFSET(n) (0x0090 + ((n) << 4))
+#define PIC32MX_INT_IPCCLR_OFFSET(n) (0x0094 + ((n) << 4))
+#define PIC32MX_INT_IPCSET_OFFSET(n) (0x0098 + ((n) << 4))
+#define PIC32MX_INT_IPCINV_OFFSET(n) (0x009c + ((n) << 4))
#define PIC32MX_INT_IPC0_OFFSET 0x0090 /* Interrupt priority control register 0 */
#define PIC32MX_INT_IPC0CLR_OFFSET 0x0094 /* Interrupt priority control clear register 0 */
#define PIC32MX_INT_IPC0SET_OFFSET 0x0098 /* Interrupt priority control set register 0 */
@@ -165,11 +165,11 @@ #define PIC32MX_INT_IECSET(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IECSET_OFFSET(n))
#define PIC32MX_INT_IECINV(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IECINV_OFFSET(n))
#define PIC32MX_INT_IEC0 (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0_OFFSET)
-#define PIC32MX_INT_IECCLR0 (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0CLR_OFFSET)
+#define PIC32MX_INT_IEC0CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0CLR_OFFSET)
#define PIC32MX_INT_IEC0SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0SET_OFFSET)
#define PIC32MX_INT_IEC0INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC0_OFFSET)
#define PIC32MX_INT_IEC1 (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1_OFFSET)
-#define PIC32MX_INT_IECCLR1 (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1CLR_OFFSET)
+#define PIC32MX_INT_IEC1CLR (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1CLR_OFFSET)
#define PIC32MX_INT_IEC1SET (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1SET_OFFSET)
#define PIC32MX_INT_IEC1INV (PIC32MX_INT_K1BASE+PIC32MX_INT_IEC1INV_OFFSET)
#define PIC32MX_INT_IPC(n) (PIC32MX_INT_K1BASE+PIC32MX_INT_IPC_OFFSET(n))
@@ -317,6 +317,12 @@ /* Interrupt priority control register 0-11 */
+#define INT_CP0_MIN_PRIORITY 0 /* Disabled! */
+#define INT_CP0_MID_PRIORITY 4 /* Can be used as the default */
+#define INT_CP0_MAX_PRIORITY 7 /* Maximum priority */
+#define INT_CP0_MIN_SUBPRIORITY 0 /* Minimum sub-priority */
+#define INT_CP0_MAX_SUBPRIORITY 0 /* Maximum sub-priority */
+
#define INT_IPC0_CTIS_SHIFT (0) /* Bits 0-1, Vector: 0, Core Timer Interrupt */
#define INT_IPC0_CTIS_MASK (3 << INT_IPC0_CTIS_SHIFT)
#define INT_IPC0_CTIP_SHIFT (2) /* Bits 2-4, Vector: 0, Core Timer Interrupt */
@@ -440,60 +446,60 @@ #define INT_IPC7_PMPIS_MASK (3 << INT_IPC7_PMPIS_SHIFT)
#define INT_IPC7_PMPIP_SHIFT (2) /* Bits 2-4, Vector: 28, Parallel Master Port */
#define INT_IPC7_PMPIP_MASK (7 << INT_IPC7_PMPIP_SHIFT)
-#define INT_IPC7_CMP1IS_SHIFT (8) /* Bits 8-9, /* Vector: 29, Comparator Interrupt */
+#define INT_IPC7_CMP1IS_SHIFT (8) /* Bits 8-9, Vector: 29, Comparator Interrupt */
#define INT_IPC7_CMP1IS_MASK (3 << INT_IPC7_CMP1IS_SHIFT)
-#define INT_IPC7_CMP1IP_SHIFT (10) /* Bits 10-12, /* Vector: 29, Comparator Interrupt */
+#define INT_IPC7_CMP1IP_SHIFT (10) /* Bits 10-12, Vector: 29, Comparator Interrupt */
#define INT_IPC7_CMP1IP_MASK (7 << INT_IPC7_CMP1IP_SHIFT)
-#define INT_IPC7_CMP2IS_SHIFT (16) /* Bits 16-17, /* Vector: 30, Comparator Interrupt */
+#define INT_IPC7_CMP2IS_SHIFT (16) /* Bits 16-17, Vector: 30, Comparator Interrupt */
#define INT_IPC7_CMP2IS_MASK (3 << INT_IPC7_CMP2IS_SHIFT)
-#define INT_IPC7_CMP2IP_SHIFT (18) /* Bits 18-20, /* Vector: 30, Comparator Interrupt */
+#define INT_IPC7_CMP2IP_SHIFT (18) /* Bits 18-20, Vector: 30, Comparator Interrupt */
#define INT_IPC7_CMP2IP_MASK (7 << INT_IPC7_CMP2IP_SHIFT)
-#define INT_IPC7_SPI2IS_SHIFT (24) /* Bits 24-25, /* Vector: 31, SPI2 */
+#define INT_IPC7_SPI2IS_SHIFT (24) /* Bits 24-25, Vector: 31, SPI2 */
#define INT_IPC7_SPI2IS_MASK (3 << INT_IPC7_SPI2IS_SHIFT)
-#define INT_IPC7_SPI2IP_SHIFT (26) /* Bits 26-28, /* Vector: 31, SPI2 */
+#define INT_IPC7_SPI2IP_SHIFT (26) /* Bits 26-28, Vector: 31, SPI2 */
#define INT_IPC7_SPI2IP_MASK (7 << INT_IPC7_SPI2IP_SHIFT)
-#define INT_IPC8_U2IS_SHIFT (0) /* Bits 0-1, /* Vector: 32, UART2 */
+#define INT_IPC8_U2IS_SHIFT (0) /* Bits 0-1, Vector: 32, UART2 */
#define INT_IPC8_U2IS_MASK (3 << INT_IPC8_U2IS_SHIFT)
-#define INT_IPC8_U2IP_SHIFT (2) /* Bits 2-4, /* Vector: 32, UART2 */
+#define INT_IPC8_U2IP_SHIFT (2) /* Bits 2-4, Vector: 32, UART2 */
#define INT_IPC8_U2IP_MASK (7 << INT_IPC8_U2IP_SHIFT)
-#define INT_IPC8_I2C2IS_SHIFT (8) /* Bits 8-9, /* Vector: 33, I2C2 */
+#define INT_IPC8_I2C2IS_SHIFT (8) /* Bits 8-9, Vector: 33, I2C2 */
#define INT_IPC8_I2C2IS_MASK (3 << INT_IPC8_I2C2IS_SHIFT)
-#define INT_IPC8_I2C2IP_SHIFT (10) /* Bits 10-12, /* Vector: 33, I2C2 */
+#define INT_IPC8_I2C2IP_SHIFT (10) /* Bits 10-12, Vector: 33, I2C2 */
#define INT_IPC8_I2C2IP_MASK (7 << INT_IPC8_I2C2IP_SHIFT)
-#define INT_IPC8_FSCMIS_SHIFT (16) /* Bits 16-17, /* Vector: 34, Fail-Safe Clock Monitor */
+#define INT_IPC8_FSCMIS_SHIFT (16) /* Bits 16-17, Vector: 34, Fail-Safe Clock Monitor */
#define INT_IPC8_FSCMIS_MASK (3 << INT_IPC8_FSCMIS_SHIFT)
-#define INT_IPC8_FSCMIP_SHIFT (18) /* Bits 18-20, /* Vector: 34, Fail-Safe Clock Monitor */
+#define INT_IPC8_FSCMIP_SHIFT (18) /* Bits 18-20, Vector: 34, Fail-Safe Clock Monitor */
#define INT_IPC8_FSCMIP_MASK (7 << INT_IPC8_FSCMIP_SHIFT)
-#define INT_IPC8_RTCCIS_SHIFT (24) /* Bits 24-25, /* Vector: 35, Real-Time Clock and Calendar */
+#define INT_IPC8_RTCCIS_SHIFT (24) /* Bits 24-25, Vector: 35, Real-Time Clock and Calendar */
#define INT_IPC8_RTCCIS_MASK (3 << INT_IPC8_RTCCIS_SHIFT)
-#define INT_IPC8_RTCCIP_SHIFT (26) /* Bits 26-28, /* Vector: 35, Real-Time Clock and Calendar */
+#define INT_IPC8_RTCCIP_SHIFT (26) /* Bits 26-28, Vector: 35, Real-Time Clock and Calendar */
#define INT_IPC8_RTCCIP_MASK (7 << INT_IPC8_RTCCIP_SHIFT)
-#define INT_IPC9_DMA0IS_SHIFT (0) /* Bits 0-1, /* Vector: 36, DMA Channel 0 */
+#define INT_IPC9_DMA0IS_SHIFT (0) /* Bits 0-1, Vector: 36, DMA Channel 0 */
#define INT_IPC9_DMA0IS_MASK (3 << INT_IPC9_DMA0IS_SHIFT)
-#define INT_IPC9_DMA0IP_SHIFT (2) /* Bits 2-4, /* Vector: 36, DMA Channel 0 */
+#define INT_IPC9_DMA0IP_SHIFT (2) /* Bits 2-4, Vector: 36, DMA Channel 0 */
#define INT_IPC9_DMA0IP_MASK (7 << INT_IPC9_DMA0IP_SHIFT)
-#define INT_IPC9_DMA1IS_SHIFT (8) /* Bits 8-9, /* Vector: 37, DMA Channel 1 */
+#define INT_IPC9_DMA1IS_SHIFT (8) /* Bits 8-9, Vector: 37, DMA Channel 1 */
#define INT_IPC9_DMA1IS_MASK (3 << INT_IPC9_DMA1IS_SHIFT)
-#define INT_IPC9_DMA1IP_SHIFT (10) /* Bits 10-12, /* Vector: 37, DMA Channel 1 */
+#define INT_IPC9_DMA1IP_SHIFT (10) /* Bits 10-12, Vector: 37, DMA Channel 1 */
#define INT_IPC9_DMA1IP_MASK (7 << INT_IPC9_DMA1IP_SHIFT)
-#define INT_IPC9_DMA2IS_SHIFT (16) /* Bits 16-17, /* Vector: 38, DMA Channel 2 */
+#define INT_IPC9_DMA2IS_SHIFT (16) /* Bits 16-17, Vector: 38, DMA Channel 2 */
#define INT_IPC9_DMA2IS_MASK (3 << INT_IPC9_DMA2IS_SHIFT)
-#define INT_IPC9_DMA2IP_SHIFT (18) /* Bits 18-20, /* Vector: 38, DMA Channel 2 */
+#define INT_IPC9_DMA2IP_SHIFT (18) /* Bits 18-20, Vector: 38, DMA Channel 2 */
#define INT_IPC9_DMA2IP_MASK (7 << INT_IPC9_DMA2IP_SHIFT)
-#define INT_IPC9_DMA3IS_SHIFT (24) /* Bits 24-25, /* Vector: 39, DMA Channel 3 */
+#define INT_IPC9_DMA3IS_SHIFT (24) /* Bits 24-25, Vector: 39, DMA Channel 3 */
#define INT_IPC9_DMA3IS_MASK (3 << INT_IPC9_DMA3IS_SHIFT)
-#define INT_IPC9_DMA3IP_SHIFT (26) /* Bits 26-28, /* Vector: 39, DMA Channel 3 */
+#define INT_IPC9_DMA3IP_SHIFT (26) /* Bits 26-28, Vector: 39, DMA Channel 3 */
#define INT_IPC9_DMA3IP_MASK (7 << INT_IPC9_DMA3IP_SHIFT)
-#define INT_IPC11_FCEIS_SHIFT (0) /* Bits 0-1, /* Vector: 44, Flash Control Event */
+#define INT_IPC11_FCEIS_SHIFT (0) /* Bits 0-1, Vector: 44, Flash Control Event */
#define INT_IPC11_FCEIS_MASK (3 << INT_IPC11_FCEIS_SHIFT)
-#define INT_IPC11_FCEIP_SHIFT (2) /* Bits 2-4, /* Vector: 44, Flash Control Event */
+#define INT_IPC11_FCEIP_SHIFT (2) /* Bits 2-4, Vector: 44, Flash Control Event */
#define INT_IPC11_FCEIP_MASK (7 << INT_IPC11_FCEIP_SHIFT)
-#define INT_IPC11_USBIS_SHIFT (8) /* Bits 8-9, /* Vector: 45, USB */
+#define INT_IPC11_USBIS_SHIFT (8) /* Bits 8-9, Vector: 45, USB */
#define INT_IPC11_USBIS_MASK (3 << INT_IPC11_USBIS_SHIFT)
-#define INT_IPC11_USBIP_SHIFT (10) /* Bits 10-12, /* Vector: 45, USB */
+#define INT_IPC11_USBIP_SHIFT (10) /* Bits 10-12, Vector: 45, USB */
#define INT_IPC11_USBIP_MASK (7 << INT_IPC11_USBIP_SHIFT)
/****************************************************************************
diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c b/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c index 19ecfb8e7..3d7d363bc 100755 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c @@ -53,6 +53,8 @@ #include "up_arch.h" #include "os_internal.h" #include "up_internal.h" + +#include "pic32mx-int.h" #include "pic32mx-internal.h" /**************************************************************************** @@ -83,14 +85,43 @@ volatile uint32_t *current_regs; void up_irqinitialize(void) { + uint32_t regval; + int irq; + /* Disable all interrupts */ -#warning "Missing logic" + + putreg32(0xffff, PIC32MX_INT_IEC0CLR); + putreg32(0xffff, PIC32MX_INT_IEC1CLR); + + /* Set all interrupts to the default (middle) priority */ + + for (irq = 0; irq < NR_IRQS; irq++) + { + (void)up_prioritize_irq(irq, (INT_CP0_MID_PRIORITY << 2)); + } + + /* Set the CP0 cause IV bit meaning that the interrupt exception uses + * the "special interrupt vector" + */ + + asm volatile("\tmfc0 %0,$13,0\n" : "=r"(regval)); + regval |= CP0_CAUSE_IV; + asm volatile("\tmtc0 %0,$13,0\n" : : "r"(regval)); + + /* Configure multi- or single- vector interrupts */ + +#ifdef CONFIG_PIC32MX_MVEC + putreg32(INT_INTCON_MVEC, PIC32MX_INT_INTCONSET); +#else + putreg32(INT_INTCON_MVEC, PIC32MX_INT_INTCONCLR); +#endif /* currents_regs is non-NULL only while processing an interrupt */ current_regs = NULL; /* Attach processor exceptions */ +#warning "Missing logic" /* Initialize logic to support a second level of interrupt decoding for * IOPORT pins. @@ -103,6 +134,14 @@ void up_irqinitialize(void) /* And finally, enable interrupts */ #ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* Interrupts are enabled by setting the IE bit in the CP0 status register */ + + regval = 0; + asm volatile("ei %0" : "=r"(regval)); + + /* Then enable all interrupt levels */ + irqrestore(CP0_STATUS_IM_ALL); #endif } @@ -117,7 +156,39 @@ void up_irqinitialize(void) void up_disable_irq(int irq) { -#warning "Missing logic" + uint32_t regaddr; + int bitno; + + /* Disable the interrupt by clearing the associated bit in the IEC register */ + + DEBUGASSERT(irq >= PIC32MX_IRQSRC0_FIRST && irq <= PIC32MX_IRQSRC1_LAST) + if (irq >= PIC32MX_IRQSRC0_FIRST) + { + if (irq <= PIC32MX_IRQSRC0_LAST) + { + /* Use IEC0 */ + + regaddr = PIC32MX_INT_IEC0CLR; + bitno -= PIC32MX_IRQSRC0_FIRST; + } + else if (irq <= PIC32MX_IRQSRC1_LAST) + { + /* Use IEC1 */ + + regaddr = PIC32MX_INT_IEC1CLR; + bitno -= PIC32MX_IRQSRC1_FIRST; + } + else + { + /* Value out of range.. just ignore */ + + return; + } + + /* Disable the interrupt */ + + putreg32((1 << bitno), regaddr); + } } /**************************************************************************** @@ -130,24 +201,201 @@ void up_disable_irq(int irq) void up_enable_irq(int irq) { -#warning "Missing logic" + uint32_t regaddr; + int bitno; + + /* Enable the interrupt by setting the associated bit in the IEC register */ + + DEBUGASSERT(irq >= PIC32MX_IRQSRC0_FIRST && irq <= PIC32MX_IRQSRC1_LAST) + if (irq >= PIC32MX_IRQSRC0_FIRST) + { + if (irq <= PIC32MX_IRQSRC0_LAST) + { + /* Use IEC0 */ + + regaddr = PIC32MX_INT_IEC0SET; + bitno -= PIC32MX_IRQSRC0_FIRST; + } + else if (irq <= PIC32MX_IRQSRC1_LAST) + { + /* Use IEC1 */ + + regaddr = PIC32MX_INT_IEC1SET; + bitno -= PIC32MX_IRQSRC1_FIRST; + } + else + { + /* Value out of range.. just ignore */ + + return; + } + + /* Disable the interrupt */ + + putreg32((1 << bitno), regaddr); + } +} + +/**************************************************************************** + * Name: up_clrpend_irq + * + * Description: + * Clear any pending interrupt + * + ****************************************************************************/ + +void up_clrpend_irq(int irq) +{ + uint32_t regaddr; + int bitno; + + /* Disable the interrupt by clearing the associated bit in the IEC and then + * acknowledge the interrupt by clearing the associated bit in the IFS + * register. It is necessary to do this BEFORE lowering the interrupt + * priority level otherwise recursive interrupts would occur. + */ + + DEBUGASSERT(irq >= PIC32MX_IRQSRC0_FIRST && irq <= PIC32MX_IRQSRC1_LAST) + if (irq >= PIC32MX_IRQSRC0_FIRST) + { + if (irq <= PIC32MX_IRQSRC0_LAST) + { + /* Use IFS0 */ + + regaddr = PIC32MX_INT_IFS0CLR; + bitno -= PIC32MX_IRQSRC0_FIRST; + } + else if (irq <= PIC32MX_IRQSRC1_LAST) + { + /* Use IFS1 */ + + regaddr = PIC32MX_INT_IFS1CLR; + bitno -= PIC32MX_IRQSRC1_FIRST; + } + else + { + /* Value out of range.. just ignore */ + + return; + } + + /* Disable then acknowledge interrupt */ + + putreg32((1 << bitno), regaddr); + } +} + +/**************************************************************************** + * Name: up_maskack_irq + * + * Description: + * Mask the IRQ and acknowledge it. This could be done by calling + * up_disable_irq followed by up_clrpend_irq, but since these function is + * called from interrupt handling logic it is probably worth the improved + * performance by doing doing both here. + * + ****************************************************************************/ + +void up_maskack_irq(int irq) +{ + uint32_t iecaddr; + uint32_t ifsaddr; + int bitno; + + /* Disable the interrupt by clearing the associated bit in the IEC and then + * acknowledge the interrupt by clearing the associated bit in the IFS + * register. It is necessary to do this BEFORE lowering the interrupt + * priority level otherwise recursive interrupts would occur. + */ + + DEBUGASSERT(irq >= PIC32MX_IRQSRC0_FIRST && irq <= PIC32MX_IRQSRC1_LAST) + if (irq >= PIC32MX_IRQSRC0_FIRST) + { + if (irq <= PIC32MX_IRQSRC0_LAST) + { + /* Use IEC0 and IFS0*/ + + iecaddr = PIC32MX_INT_IEC0CLR; + ifsaddr = PIC32MX_INT_IFS0CLR; + bitno -= PIC32MX_IRQSRC0_FIRST; + } + else if (irq <= PIC32MX_IRQSRC1_LAST) + { + /* Use IEC1 and IFS1 */ + + iecaddr = PIC32MX_INT_IEC1CLR; + ifsaddr = PIC32MX_INT_IFS1CLR; + bitno -= PIC32MX_IRQSRC1_FIRST; + } + else + { + /* Value out of range.. just ignore */ + + return; + } + + /* Disable then acknowledge interrupt */ + + putreg32((1 << bitno), iecaddr); + putreg32((1 << bitno), ifsaddr); + } } /**************************************************************************** * Name: up_prioritize_irq * * Description: - * Set the priority of an IRQ. + * Set the priority of an IRQ by setting the priority and sub-priority + * fields in the PIC32MX IPC registers. There are 12 IPC registers, IPC0 + * through IPC11. Each has sub-priority fields for 8 interrupts for a + * total of 96 interrupts max. + * + * Each interrupt priority is represent by a group of 5 bits: a 3-bit + * priority and a 2-bit sub-priority. These have different meanings to + * the hardware. The priority is the priority level that is enabled + * or masked by the IPL field of the CAUSE register. The sub-priority + * only mediates ties when two interrupts with the same priority pend + * simultaneously. + * + * In this function, we just treat this as a single 5-bit priority. + * (MS 3-bits=priority; LS 2-bits=sub-priority). * - * Since this API is not supported on all architectures, it should be - * avoided in common implementations where possible. + * The 5-bit priority/sub-priority fields are arranged at byte boundaries + * within each IPC register: + * + * xxxP PPSS xxxP PPSS xxxP PPSS xxxP PPSS * ****************************************************************************/ #ifdef CONFIG_ARCH_IRQPRIO int up_prioritize_irq(int irq, int priority) { -#warning "Missing logic" - return -ENOSYS; + int regndx; + int shift; + + /* Don't allow this function to be used for disabling interrupts. There is + * no good reason for this restriction other than I want to make sure that + * the 5-bit priority values passed to this function are *not* confused with + * the 3-bit hardware priority values. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS && (unsigned)(priority >> 2) > 0); + if (irq < NR_IRQS) + { + /* Get the index to the IPC register and the shift to the 5-bit priority + * field for this IRQ. + */ + + regndx = irq >> 2; /* Range: 0-11 */ + shift = (irq & 3) << 3; /* {0, 8, 16, 24 } */ + + /* Set the new interrupt priority (momentarily disabling interrupts) */ + + putreg32(0x1f << shift, PIC32MX_INT_IPCCLR(regndx)); + putreg32(priority << shift, PIC32MX_INT_IPCSET(regndx)); + return OK; + } + + return -EINVAL; } #endif diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h b/nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h index f81e9695c..9cf1e8a13 100755 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h @@ -43,13 +43,14 @@ #include <nuttx/config.h>
#include "chip.h"
+#include "mips32-memorymap.h"
/************************************************************************************
* Pre-Processor Definitions
************************************************************************************/
/* This memory may be valid for other chips as well, but I don't know that */
-#if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX3)
+#if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4)
/* Physical Memory Map **************************************************************/
diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-timerisr.c b/nuttx/arch/mips/src/pic32mx/pic32mx-timerisr.c new file mode 100755 index 000000000..4b3addf2c --- /dev/null +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-timerisr.c @@ -0,0 +1,174 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx_timerisr.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <time.h> +#include <debug.h> + +#include <nuttx/arch.h> +#include <arch/board/board.h> + +#include "clock_internal.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "pic32mx-timer.h" +#include "pic32mx-int.h" +#include "pic32mx-internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_PIC32MX_T1PRIO +# define CONFIG_PIC32MX_T1PRIO (INT_CP0_MID_PRIORITY << 2) +#endif + +#if CONFIG_PIC32MX_T1PRIO < 4 +# error "CONFIG_PIC32MX_T1PRIO is too small" +#endif + +#if CONFIG_PIC32MX_T1PRIO > 31 +# error "CONFIG_PIC32MX_T1PRIO is too large" +#endif + +/* Timer Setup **************************************************************/ +/* Select a timer prescale value. Our goal is to select the timer MATCH + * register value givent the board's periperhal clock frequency and the + * desired system timer frequency: + * + * TIMER1_MATCH = BOARD_PERIPHERAL_CLOCK / TIMER1_PRESCALE / CLOCKS_PER_SEC + * + * We want the largest possible value for MATCH that is less than 65,535, the + * maximum value for the 16-bit timer register: + * + * TIMER1_PRESCALE >= BOARD_PERIPHERAL_CLOCK / CLOCKS_PER_SEC / 65535 + * + * Timer 1 does not have very many options for the perscaler value. So we + * can pick the best by brute force. Example: + * + * BOARD_PERIPHERAL_CLOCK = 40000000 + * CLOCKS_PER_SEC = 100 + * OPTIMAL_PRESCALE = 6 + * TIMER1_PRESCALE = 8 + * TIMER1_MATCH = 50,000 + */ + +#define OPTIMAL_PRESCALE (BOARD_PERIPHERAL_CLOCK / CLOCKS_PER_SEC / 65535) +#if OPTIMAL_PRESCALE <= 1 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_1 +# define TIMER1_PRESCALE 1 +#elif OPTIMAL_PRESCALE <= 8 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_8 +# define TIMER1_PRESCALE 8 +#elif OPTIMAL_PRESCALE <= 64 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_64 +# define TIMER1_PRESCALE 64 +#elif OPTIMAL_PRESCALE <= 256 +# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_256 +# define TIMER1_PRESCALE 256 +#else +# error "This timer frequency cannot be represented" +#endif + +#define TIMER1_MATCH (BOARD_PERIPHERAL_CLOCK / TIMER1_PRESCALE / CLOCKS_PER_SEC) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timerinit + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timerinit(void) +{ + /* Configure and enable TIMER1 -- source internal (TCS=0) */ + + putreg32(TIMER1_CON_TCKPS, PIC32MX_TIMER1_CON); + putreg32(0, PIC32MX_TIMER1_CNT); + putreg32(TIMER1_MATCH-1, PIC32MX_TIMER1_PR); + putreg32(TIMER_CON_ON, PIC32MX_TIMER1_CONSET); + + /* Configure the timer interrupt */ + + up_clrpend_irq(PIC32MX_IRQSRC_T1); + (void)up_prioritize_irq(PIC32MX_IRQ_T1, CONFIG_PIC32MX_T1PRIO); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(PIC32MX_IRQ_T1, (xcpt_t)up_timerisr); + + /* And enable the timer interrupt */ + + up_enable_irq(PIC32MX_IRQSRC_T1); +} diff --git a/nuttx/configs/pcblogic-pic32mx/README.txt b/nuttx/configs/pcblogic-pic32mx/README.txt index d9c4a8588..f36fd2ee8 100644 --- a/nuttx/configs/pcblogic-pic32mx/README.txt +++ b/nuttx/configs/pcblogic-pic32mx/README.txt @@ -144,15 +144,18 @@ PIC32MX Configuration Options the 100 second delay then adjust CONFIG_ARCH_LOOPSPERMSEC until the delay actually is 100 seconds. + PIC32MX Configuration + + CONFIG_PIC32MX_MVEC - Select muli- vs. single-vectored interrupts + Individual subsystems can be enabled: CONFIG_PIC32MX_WDT CONFIG_PIC32MX_RTCC - CONFIG_PIC32MX_TIMER1 - CONFIG_PIC32MX_TIMER2 - CONFIG_PIC32MX_TIMER3 - CONFIG_PIC32MX_TIMER4 - CONFIG_PIC32MX_TIMER5 + CONFIG_PIC32MX_T2 /* Timer 1 is the system time and always enabled */ + CONFIG_PIC32MX_T3 + CONFIG_PIC32MX_T4 + CONFIG_PIC32MX_T5 CONFIG_PIC32MX_IC1 CONFIG_PIC32MX_IC2 CONFIG_PIC32MX_IC3 @@ -189,6 +192,53 @@ PIC32MX Configuration Options CONFIG_PIC32MX_IOPORTF CONFIG_PIC32MX_IOPORTG + The priority of interrupts may be specified. The value ranage of + priority is 4-31. The default (16) will be used if these any of these + are undefined. + + CONFIG_PIC32MX_WDTPRIO + CONFIG_PIC32MX_RTCCPRIO + CONFIG_PIC32MX_T1PRIO /* System timer priority */ + CONFIG_PIC32MX_T2PRIO + CONFIG_PIC32MX_T3PRIO + CONFIG_PIC32MX_T4PRIO + CONFIG_PIC32MX_T5PRIO + CONFIG_PIC32MX_IC1PRIO + CONFIG_PIC32MX_IC2PRIO + CONFIG_PIC32MX_IC3PRIO + CONFIG_PIC32MX_IC4PRIO + CONFIG_PIC32MX_IC5PRIO + CONFIG_PIC32MX_OC1PRIO + CONFIG_PIC32MX_OC2PRIO + CONFIG_PIC32MX_OC3PRIO + CONFIG_PIC32MX_OC4PRIO + CONFIG_PIC32MX_OC5PRIO + CONFIG_PIC32MX_I2C1PRIO + CONFIG_PIC32MX_I2C2PRIO + CONFIG_PIC32MX_SPI1PRIO + CONFIG_PIC32MX_SPI2PRIO + CONFIG_PIC32MX_UART1PRIO + CONFIG_PIC32MX_UART2PRIO + CONFIG_PIC32MX_PMPPRIO + CONFIG_PIC32MX_ADCPRIO + CONFIG_PIC32MX_CVRPRIO + CONFIG_PIC32MX_CM1PRIO + CONFIG_PIC32MX_CM2PRIO + CONFIG_PIC32MX_OSCPRIO + CONFIG_PIC32MX_DDPPRIO + CONFIG_PIC32MX_FLASHPRIO + CONFIG_PIC32MX_BMXPRIO + CONFIG_PIC32MX_DMAPRIO + CONFIG_PIC32MX_CHEPRIO + CONFIG_PIC32MX_USBPRIO + CONFIG_PIC32MX_IOPORTAPRIO + CONFIG_PIC32MX_IOPORTBPRIO + CONFIG_PIC32MX_IOPORTCPRIO + CONFIG_PIC32MX_IOPORTDPRIO + CONFIG_PIC32MX_IOPORTEPRIO + CONFIG_PIC32MX_IOPORTFPRIO + CONFIG_PIC32MX_IOPORTGPRIO + PIC32MXx specific device driver settings CONFIG_UARTn_SERIAL_CONSOLE - selects the UARTn for the diff --git a/nuttx/configs/pcblogic-pic32mx/include/board.h b/nuttx/configs/pcblogic-pic32mx/include/board.h index 92102fda3..00fa2f585 100755 --- a/nuttx/configs/pcblogic-pic32mx/include/board.h +++ b/nuttx/configs/pcblogic-pic32mx/include/board.h @@ -48,16 +48,21 @@ ****************************************************************************/
/* Configuration ************************************************************/
+/* Clocking *****************************************************************/
+
+#define BOARD_CPU_CLOCK 80000000
+#define BOARD_PERIPHERAL_CLOCK 40000000
+
/* LED definitions **********************************************************/
-#define LED_STARTED 0
-#define LED_HEAPALLOCATE 1
-#define LED_IRQSENABLED 2
-#define LED_STACKCREATED 3
-#define LED_INIRQ 4
-#define LED_SIGNAL 5
-#define LED_ASSERTION 6
-#define LED_PANIC 7
+#define LED_STARTED 0
+#define LED_HEAPALLOCATE 1
+#define LED_IRQSENABLED 2
+#define LED_STACKCREATED 3
+#define LED_INIRQ 4
+#define LED_SIGNAL 5
+#define LED_ASSERTION 6
+#define LED_PANIC 7
/****************************************************************************
* Public Types
|