summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-06-30 09:17:42 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-06-30 09:17:42 -0600
commita3d37c277c2c23d0d6a1f5b00dcf8ee52041bf3f (patch)
tree23efed9f892a44b5d0f781c3c8957feda761ab47
parenta18eb2d5ed2564bd4b2cca1deaa42f65f2ee5cd6 (diff)
downloadnuttx-a3d37c277c2c23d0d6a1f5b00dcf8ee52041bf3f.tar.gz
nuttx-a3d37c277c2c23d0d6a1f5b00dcf8ee52041bf3f.tar.bz2
nuttx-a3d37c277c2c23d0d6a1f5b00dcf8ee52041bf3f.zip
SAMA5D4: Don't touch ISLR unless PIO is configured as an interrupt
-rw-r--r--nuttx/arch/arm/src/sama5/sam_pio.c46
-rw-r--r--nuttx/arch/arm/src/sama5/sam_pioirq.c36
2 files changed, 48 insertions, 34 deletions
diff --git a/nuttx/arch/arm/src/sama5/sam_pio.c b/nuttx/arch/arm/src/sama5/sam_pio.c
index eb336db25..44d1f0103 100644
--- a/nuttx/arch/arm/src/sama5/sam_pio.c
+++ b/nuttx/arch/arm/src/sama5/sam_pio.c
@@ -137,7 +137,7 @@ static inline int sam_piopin(pio_pinset_t cfgset)
static inline int sam_configinput(uintptr_t base, uint32_t pin,
pio_pinset_t cfgset)
{
-#if defined(PIO_HAVE_SCHMITT) || defined(PIO_HAVE_DRIVE) || defined(SAM_PIO_ISLR_OFFSET)
+#if defined(PIO_HAVE_SCHMITT) || defined(PIO_HAVE_DRIVE)
uint32_t regval;
#endif
#if defined(PIO_HAVE_DRIVE)
@@ -151,14 +151,6 @@ static inline int sam_configinput(uintptr_t base, uint32_t pin,
putreg32(pin, base + SAM_PIO_IDR_OFFSET);
-#if defined(SAM_PIO_ISLR_OFFSET)
- /* Assume unsecure */
-
- regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
- regval |= pin;
- putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
-#endif
-
/* Enable/disable the pull-up as requested */
if ((cfgset & PIO_CFG_PULLUP) != 0)
@@ -256,22 +248,10 @@ static inline int sam_configinput(uintptr_t base, uint32_t pin,
static inline int sam_configoutput(uintptr_t base, uint32_t pin,
pio_pinset_t cfgset)
{
-#if defined(SAM_PIO_ISLR_OFFSET)
- uint32_t regval;
-#endif
-
/* Disable interrupts on the pin */
putreg32(pin, base + SAM_PIO_IDR_OFFSET);
-#if defined(SAM_PIO_ISLR_OFFSET)
- /* Assume unsecure */
-
- regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
- regval |= pin;
- putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
-#endif
-
/* Enable/disable the pull-up as requested */
if ((cfgset & PIO_CFG_PULLUP) != 0)
@@ -343,14 +323,6 @@ static inline int sam_configperiph(uintptr_t base, uint32_t pin,
putreg32(pin, base + SAM_PIO_IDR_OFFSET);
-#if defined(SAM_PIO_ISLR_OFFSET)
- /* Assume unsecure */
-
- regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
- regval |= pin;
- putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
-#endif
-
/* Enable/disable the pull-up as requested */
if ((cfgset & PIO_CFG_PULLUP) != 0)
@@ -466,7 +438,21 @@ int sam_configpio(pio_pinset_t cfgset)
flags = irqsave();
- /* Enable writing to PIO registers */
+ /* Enable writing to PIO registers. The following registers are protected:
+ *
+ * - PIO Enable/Disable Registers (PER/PDR)
+ * - PIO Output Enable/Disable Registers (OER/ODR)
+ * - PIO Interrupt Security Level Register (ISLR)
+ * - PIO Input Filter Enable/Disable Registers (IFER/IFDR)
+ * - PIO Multi-driver Enable/Disable Registers (MDER/MDDR)
+ * - PIO Pull-Up Enable/Disable Registers (PUER/PUDR)
+ * - PIO Peripheral ABCD Select Register 1/2 (ABCDSR1/2)
+ * - PIO Output Write Enable/Disable Registers
+ * - PIO Pad Pull-Down Enable/Disable Registers (PPER/PPDR)
+ *
+ * I suspect that the default state is the WPMR is unprotected, so these
+ * operations could probably all be avoided.
+ */
putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET);
diff --git a/nuttx/arch/arm/src/sama5/sam_pioirq.c b/nuttx/arch/arm/src/sama5/sam_pioirq.c
index 0d9269a46..4557eb48f 100644
--- a/nuttx/arch/arm/src/sama5/sam_pioirq.c
+++ b/nuttx/arch/arm/src/sama5/sam_pioirq.c
@@ -375,22 +375,48 @@ void sam_pioirqinitialize(void)
void sam_pioirq(pio_pinset_t pinset)
{
+#if defined(SAM_PIO_ISLR_OFFSET)
+ uint32_t regval;
+#endif
uint32_t base = sam_piobase(pinset);
int pin = sam_piopin(pinset);
- /* Enable writing to PIO registers */
+#if defined(SAM_PIO_ISLR_OFFSET)
+ /* Enable writing to PIO registers. The following registers are protected:
+ *
+ * - PIO Enable/Disable Registers (PER/PDR)
+ * - PIO Output Enable/Disable Registers (OER/ODR)
+ * - PIO Interrupt Security Level Register (ISLR)
+ * - PIO Input Filter Enable/Disable Registers (IFER/IFDR)
+ * - PIO Multi-driver Enable/Disable Registers (MDER/MDDR)
+ * - PIO Pull-Up Enable/Disable Registers (PUER/PUDR)
+ * - PIO Peripheral ABCD Select Register 1/2 (ABCDSR1/2)
+ * - PIO Output Write Enable/Disable Registers
+ * - PIO Pad Pull-Down Enable/Disable Registers (PPER/PPDR)
+ *
+ * I suspect that the default state is the WPMR is unprotected, so these
+ * operations could probably all be avoided.
+ */
putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET);
-#if defined(SAMA5_SAIC) && defined(SAM_PIO_ISLR_OFFSET)
/* Is the interrupt secure? */
+ regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
if ((pinset & PIO_INT_SECURE) != 0)
{
- uint32_t regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
+ /* Yes.. make sure that the corresponding bit in ISLR is cleared */
+
regval &= ~pin;
- putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
}
+ else
+ {
+ /* Yes.. make sure that the corresponding bit in ISLR is set */
+
+ regval |= pin;
+ }
+
+ putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
#endif
/* Are any additional interrupt modes selected? */
@@ -430,9 +456,11 @@ void sam_pioirq(pio_pinset_t pinset)
putreg32(pin, base + SAM_PIO_AIMDR_OFFSET);
}
+#if defined(SAM_PIO_ISLR_OFFSET)
/* Disable writing to PIO registers */
putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET);
+#endif
}
/************************************************************************************