The commit corrects the gpioirq when mismatch mode is selected and adds support for edge detect mode. Slew Rate was also added for completeness.
This commit is contained in:
parent
6f408b87bf
commit
e5f84dca39
@ -1,7 +1,7 @@
|
||||
/********************************************************************************************
|
||||
* arch/mips/src/pic32mz/pic32mz-ioport.h
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2015, 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -121,10 +121,30 @@
|
||||
#define PIC32MZ_IOPORT_CNENSET_OFFSET 0x0088 /* Change Notice Interrupt Enable set register */
|
||||
#define PIC32MZ_IOPORT_CNENINV_OFFSET 0x008c /* Change Notice Interrupt Enable invert register */
|
||||
|
||||
#define PIC32MZ_IOPORT_CNSTAT_OFFSET 0x0080 /* Change Notice Control register */
|
||||
#define PIC32MZ_IOPORT_CNSTATCLR_OFFSET 0x0084 /* Change Notice Control clear register*/
|
||||
#define PIC32MZ_IOPORT_CNSTATSET_OFFSET 0x0088 /* Change Notice Control set register */
|
||||
#define PIC32MZ_IOPORT_CNSTATINV_OFFSET 0x008c /* Change Notice Control invert register */
|
||||
#define PIC32MZ_IOPORT_CNSTAT_OFFSET 0x0090 /* Change Notice Status register */
|
||||
#define PIC32MZ_IOPORT_CNSTATCLR_OFFSET 0x0094 /* Change Notice Status clear register*/
|
||||
#define PIC32MZ_IOPORT_CNSTATSET_OFFSET 0x0098 /* Change Notice Status set register */
|
||||
#define PIC32MZ_IOPORT_CNSTATINV_OFFSET 0x009c /* Change Notice Status invert register */
|
||||
|
||||
#define PIC32MZ_IOPORT_CNNE_OFFSET 0x00a0 /* Change Notice Interrupt Enable register */
|
||||
#define PIC32MZ_IOPORT_CNNECLR_OFFSET 0x00a4 /* Change Notice Interrupt Enable clear register */
|
||||
#define PIC32MZ_IOPORT_CNNESET_OFFSET 0x00a8 /* Change Notice Interrupt Enable set register */
|
||||
#define PIC32MZ_IOPORT_CNNEINV_OFFSET 0x00ac /* Change Notice Interrupt Enable invert register */
|
||||
|
||||
#define PIC32MZ_IOPORT_CNF_OFFSET 0x00b0 /* Change Notice Status register */
|
||||
#define PIC32MZ_IOPORT_CNFCLR_OFFSET 0x00b4 /* Change Notice Status clear register */
|
||||
#define PIC32MZ_IOPORT_CNFSET_OFFSET 0x00b8 /* Change Notice Status set register */
|
||||
#define PIC32MZ_IOPORT_CNFINV_OFFSET 0x00bc /* Change Notice Status invert register */
|
||||
|
||||
#define PIC32MZ_IOPORT_SRCON0_OFFSET 0x00c0 /* Slew Rate Control0 register */
|
||||
#define PIC32MZ_IOPORT_SRCON0CLR_OFFSET 0x00c4 /* Slew Rate Control0 clear register */
|
||||
#define PIC32MZ_IOPORT_SRCON0SET_OFFSET 0x00c8 /* Slew Rate Control0 set register */
|
||||
#define PIC32MZ_IOPORT_SRCON0INV_OFFSET 0x00cc /* Slew Rate Control0 invert register */
|
||||
|
||||
#define PIC32MZ_IOPORT_SRCON1_OFFSET 0x00d0 /* Slew Rate Control1 register */
|
||||
#define PIC32MZ_IOPORT_SRCON1CLR_OFFSET 0x00d4 /* Slew Rate Control1 clear register */
|
||||
#define PIC32MZ_IOPORT_SRCON1SET_OFFSET 0x00d8 /* Slew Rate Control1 set register */
|
||||
#define PIC32MZ_IOPORT_SRCON1INV_OFFSET 0x00dc /* Slew Rate Control1 invert register */
|
||||
|
||||
/* IOPort Peripheral Addresses **************************************************************/
|
||||
|
||||
@ -823,7 +843,8 @@
|
||||
|
||||
/* Change Notice Control register */
|
||||
|
||||
#define IOPORT_CNCON_SIDL (1 << 13) /* Bit 13: Stop in idle mode */
|
||||
#define IOPORT_CNCON_EDGEDETECT (1 << 11) /* Bit 11: Change Notification Style bit */
|
||||
#define IOPORT_CNCON_SIDL (1 << 13) /* Bit 13: Stop in Idle Control bit */
|
||||
#define IOPORT_CNCON_ON (1 << 15) /* Bit 15: Change notice module enable */
|
||||
|
||||
/* Change Notice Interrupt Enable register */
|
||||
@ -836,6 +857,26 @@
|
||||
#define IOPORT_CNSTAT(n) (1 << (n)) /* Bits 0-15: Change notice control pin n */
|
||||
#define IOPORT_CNSTAT_ALL 0x0000ffff
|
||||
|
||||
/* Change Notice Interrupt Enable register (Negative edge) */
|
||||
|
||||
#define IOPORT_CNNE(n) (1 << (n)) /* Bits 0-15: 1=Interrupt enabled */
|
||||
#define IOPORT_CNNE_ALL 0x0000ffff
|
||||
|
||||
/* Change Notice Status register */
|
||||
|
||||
#define IOPORT_CNF(n) (1 << (n)) /* Bits 0-15: Change notice control pin n */
|
||||
#define IOPORT_CNF_ALL 0x0000ffff
|
||||
|
||||
/* Slew Rate Control0 register */
|
||||
|
||||
#define IOPORT_SRCON0(n) (1 << (n)) /* Bits 0-15: Slew Rate control pin n */
|
||||
#define IOPORT_SRCON0_ALL 0x0000ffff
|
||||
|
||||
/* Slew Rate Control1 register */
|
||||
|
||||
#define IOPORT_SRCON1(n) (1 << (n)) /* Bits 0-15: Slew Rate control pin n */
|
||||
#define IOPORT_SRCON1_ALL 0x0000ffff
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Types
|
||||
********************************************************************************************/
|
||||
|
@ -507,7 +507,7 @@
|
||||
|
||||
#undef CONFIG_PIC32MZ_FWDTEN
|
||||
#ifdef CONFIG_PIC32MZ_WDTENABLE
|
||||
# define CONFIG_PIC32MZ_FWDTEN DEVCFG1_FWDT_ENSABLED
|
||||
# define CONFIG_PIC32MZ_FWDTEN DEVCFG1_FWDT_ENABLED
|
||||
#else
|
||||
# define CONFIG_PIC32MZ_FWDTEN DEVCFG1_FWDT_DISABLED
|
||||
#endif
|
||||
|
@ -113,7 +113,7 @@ static inline bool pic32mz_output(pinset_t pinset)
|
||||
|
||||
static inline bool pic32mz_opendrain(pinset_t pinset)
|
||||
{
|
||||
return ((pinset & GPIO_MODE_MASK) == GPIO_OPENDRAN);
|
||||
return ((pinset & GPIO_MODE_MASK) == GPIO_OPENDRAIN);
|
||||
}
|
||||
|
||||
static inline bool pic32mz_outputhigh(pinset_t pinset)
|
||||
@ -141,6 +141,21 @@ static inline unsigned int pic32mz_analog(pinset_t pinset)
|
||||
return ((pinset & GPIO_ANALOG_MASK) != 0);
|
||||
}
|
||||
|
||||
static inline unsigned int pic32mz_slewrate(pinset_t pinset)
|
||||
{
|
||||
return ((pinset & GPIO_SR_MASK) >> GPIO_SR_SHIFT);
|
||||
}
|
||||
|
||||
static inline unsigned int pic32mz_slewratecon0(pinset_t pinset)
|
||||
{
|
||||
return (pic32mz_slewrate(pinset) & GPIO_SR_CON0_MASK) >> GPIO_SR_CON0_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned int pic32mz_slewratecon1(pinset_t pinset)
|
||||
{
|
||||
return (pic32mz_slewrate(pinset) & GPIO_SR_CON1_MASK) >> GPIO_SR_CON1_SHIFT;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -172,9 +187,24 @@ int pic32mz_configgpio(pinset_t cfgset)
|
||||
|
||||
base = g_gpiobase[port];
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Is Slew Rate control enabled? */
|
||||
|
||||
if (pic32mz_slewrate(cfgset) != GPIO_FASTEST)
|
||||
{
|
||||
/* Note: not every port nor every pin has the Slew Rate feature.
|
||||
* Writing to an unimplemented port/pin will have no effect.
|
||||
*/
|
||||
|
||||
putreg32(pic32mz_slewratecon0(cfgset),
|
||||
base + PIC32MZ_IOPORT_SRCON0_OFFSET);
|
||||
putreg32(pic32mz_slewratecon1(cfgset),
|
||||
base + PIC32MZ_IOPORT_SRCON1_OFFSET);
|
||||
}
|
||||
|
||||
/* Is this an input or an output? */
|
||||
|
||||
sched_lock();
|
||||
if (pic32mz_output(cfgset))
|
||||
{
|
||||
/* Not analog */
|
||||
@ -308,7 +338,7 @@ bool pic32mz_gpioread(pinset_t pinset)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_GPIO_INFO
|
||||
void pic32mz_dumpgpio(uint32_t pinset, const char *msg)
|
||||
void pic32mz_dumpgpio(pinset_t pinset, const char *msg)
|
||||
{
|
||||
unsigned int port = pic32mz_portno(pinset);
|
||||
irqstate_t flags;
|
||||
|
@ -51,28 +51,84 @@
|
||||
/* GPIO settings used in the configport, readport, writeport, etc.
|
||||
*
|
||||
* General encoding:
|
||||
* MMAV IIDR RRRx PPPP
|
||||
* xxxx xxxx xxxx xSSM MAVI IIII RRRR PPPP
|
||||
*
|
||||
* x = Not implemented
|
||||
* S = Slew Rate
|
||||
* M = Mode (input/output)
|
||||
* I = Interrupt
|
||||
* R = Register
|
||||
* P = Pin
|
||||
*/
|
||||
|
||||
#define GPIO_MODE_SHIFT (14) /* Bits 14-15: I/O mode */
|
||||
/* Slew Rate Control.
|
||||
*
|
||||
* .... .... .... .SS. .... .... .... ....
|
||||
*/
|
||||
|
||||
#define GPIO_SR_SHIFT (17) /* Bits 17-18: Slew Rate Control */
|
||||
#define GPIO_SR_MASK (3 << GPIO_SR_SHIFT)
|
||||
# define GPIO_FASTEST (0 << GPIO_SR_SHIFT) /* 00: Disabled and set to fastest */
|
||||
# define GPIO_MEDIUM (1 << GPIO_SR_SHIFT) /* 01: Enabled and set to medium */
|
||||
# define GPIO_SLOW (2 << GPIO_SR_SHIFT) /* 10: Enabled and set to slow */
|
||||
# define GPIO_SLOWEST (3 << GPIO_SR_SHIFT) /* 11: Enabled and set to slowest */
|
||||
#define GPIO_SR_CON0_SHIFT (0) /* Bit 0: SRCON0x */
|
||||
#define GPIO_SR_CON0_MASK (1 << GPIO_SR_CON0_SHIFT)
|
||||
#define GPIO_SR_CON1_SHIFT (1) /* Bit 1: SRCON1x */
|
||||
#define GPIO_SR_CON1_MASK (1 << GPIO_SR_CON1_SHIFT)
|
||||
|
||||
/* Input/Output mode:
|
||||
*
|
||||
* .... .... .... ...M M... .... .... ....
|
||||
*/
|
||||
|
||||
#define GPIO_MODE_SHIFT (15) /* Bits 15-16: I/O mode */
|
||||
#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT)
|
||||
# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* 00 Normal input */
|
||||
# define GPIO_OUTPUT (2 << GPIO_MODE_SHIFT) /* 10 Normal output */
|
||||
# define GPIO_OPENDRAN (3 << GPIO_MODE_SHIFT) /* 11 Open drain output */
|
||||
# define GPIO_OPENDRAIN (3 << GPIO_MODE_SHIFT) /* 11 Open drain output */
|
||||
|
||||
#define GPIO_ANALOG_MASK (1 << 13) /* Bit 13: Analog */
|
||||
# define GPIO_ANALOG (1 << 13)
|
||||
/* Analog mode.
|
||||
*
|
||||
* .... .... .... .... .A.. .... .... ....
|
||||
*/
|
||||
|
||||
#define GPIO_ANALOG_SHIFT (14) /* Bit 14: Analog */
|
||||
#define GPIO_ANALOG_MASK (1 << GPIO_ANALOG_SHIFT)
|
||||
# define GPIO_ANALOG (1 << GPIO_ANALOG_SHIFT)
|
||||
# define GPIO_DIGITAL (0)
|
||||
|
||||
#define GPIO_VALUE_MASK (1 << 12) /* Bit 12: Initial output value */
|
||||
# define GPIO_VALUE_ONE (1 << 12)
|
||||
/* Pin Value.
|
||||
*
|
||||
* .... .... .... .... ..V. .... .... ....
|
||||
*/
|
||||
|
||||
#define GPIO_VALUE_SHIFT (13) /* Bit 13: Initializetial output value */
|
||||
#define GPIO_VALUE_MASK (1 << GPIO_VALUE_SHIFT)
|
||||
# define GPIO_VALUE_ONE (1 << GPIO_VALUE_SHIFT)
|
||||
# define GPIO_VALUE_ZERO (0)
|
||||
|
||||
#define GPIO_INTERRUPT (1 << 11) /* Bit 11: Change notification enable */
|
||||
#define GPIO_PULLUP (1 << 10) /* Bit 10: Change notification pull-up */
|
||||
#define GPIO_PULLDOWN (1 << 9) /* Bit 9: Change notification pull-down */
|
||||
/* Change Notification config.
|
||||
*
|
||||
* .... .... .... .... ...I IIII .... ....
|
||||
*/
|
||||
|
||||
#define GPIO_PORT_SHIFT (5) /* Bits 5-8: Port number */
|
||||
#define GPIO_CN_SHIFT (8) /* Bit 8 - 12: Change notification bits */
|
||||
#define GPIO_CN_MASK (31 << GPIO_CN_SHIFT)
|
||||
# define GPIO_INTERRUPT (1 << GPIO_CN_SHIFT) /* Bit 8: Change notification enable bit */
|
||||
# define GPIO_PULLUP (2 << GPIO_CN_SHIFT) /* Bit 9: Change notification pull-up */
|
||||
# define GPIO_PULLDOWN (4 << GPIO_CN_SHIFT) /* Bit 10: Change notification pull-down */
|
||||
# define GPIO_EDGE_DETECT (8 << GPIO_CN_SHIFT) /* Bit 11: Change notification interrupt mode */
|
||||
# define GPIO_MISMATCH (0)
|
||||
# define GPIO_EDGE_RISING (12 << GPIO_CN_SHIFT) /* Bit 12: Change notification edge type */
|
||||
# define GPIO_EDGE_FALLING (0)
|
||||
|
||||
/* GPIO Port.
|
||||
*
|
||||
* .... .... .... .... .... .... RRRR ....
|
||||
*/
|
||||
|
||||
#define GPIO_PORT_SHIFT (4) /* Bits 4-7: Port number */
|
||||
#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
|
||||
@ -85,6 +141,11 @@
|
||||
# define GPIO_PORTJ (8 << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORTK (9 << GPIO_PORT_SHIFT)
|
||||
|
||||
/* GPIO Pin.
|
||||
*
|
||||
* .... .... .... .... .... .... .... PPPP
|
||||
*/
|
||||
|
||||
#define GPIO_PIN_SHIFT 0 /* Bits 0-3: GPIO number: 0-15 */
|
||||
#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT)
|
||||
#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT)
|
||||
@ -110,7 +171,7 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
typedef uint16_t pinset_t;
|
||||
typedef uint32_t pinset_t;
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
@ -210,7 +271,7 @@ void pic32mz_gpioirqinitialize(void);
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PIC32MZ_GPIOIRQ
|
||||
int pic32mz_gpioattach(uint32_t pinset, xcpt_t handler, void *arg);
|
||||
int pic32mz_gpioattach(pinset_t pinset, xcpt_t handler, void *arg);
|
||||
#else
|
||||
# define pic32mz_gpioattach(p,h,a) (0)
|
||||
#endif
|
||||
@ -252,7 +313,7 @@ void pic32mz_gpioirqdisable(pinset_t pinset);
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_GPIO_INFO
|
||||
void pic32mz_dumpgpio(uint32_t pinset, const char *msg);
|
||||
void pic32mz_dumpgpio(pinset_t pinset, const char *msg);
|
||||
#else
|
||||
# define pic32mz_dumpgpio(p,m)
|
||||
#endif
|
||||
|
@ -70,6 +70,8 @@ static inline unsigned int pic32mz_ioport(pinset_t pinset);
|
||||
static inline unsigned int pic32mz_pin(pinset_t pinset);
|
||||
static inline bool pic32mz_input(pinset_t pinset);
|
||||
static inline bool pic32mz_interrupt(pinset_t pinset);
|
||||
static inline bool pic32mz_edgedetect(pinset_t pinset);
|
||||
static inline unsigned int pic32mz_edgemode(pinset_t pinset);
|
||||
static inline bool pic32mz_pullup(pinset_t pinset);
|
||||
static inline bool pic32mz_pulldown(pinset_t pinset);
|
||||
static int pic32mz_cninterrupt(int irq, FAR void *context, FAR void *arg);
|
||||
@ -174,7 +176,7 @@ static struct ioport_level2_s * const g_level2_handlers[CHIP_NPORTS] =
|
||||
|
||||
static inline bool pic32mz_input(pinset_t pinset)
|
||||
{
|
||||
return ((pinset & GPIO_MODE_MASK) != GPIO_INPUT);
|
||||
return (((pinset & GPIO_MODE_MASK) >> GPIO_MODE_SHIFT) == GPIO_INPUT);
|
||||
}
|
||||
|
||||
static inline bool pic32mz_interrupt(pinset_t pinset)
|
||||
@ -182,6 +184,16 @@ static inline bool pic32mz_interrupt(pinset_t pinset)
|
||||
return ((pinset & GPIO_INTERRUPT) != 0);
|
||||
}
|
||||
|
||||
static inline bool pic32mz_edgedetect(pinset_t pinset)
|
||||
{
|
||||
return ((pinset & GPIO_EDGE_DETECT) != 0);
|
||||
}
|
||||
|
||||
static inline unsigned int pic32mz_edgemode(pinset_t pinset)
|
||||
{
|
||||
return ((pinset & GPIO_EDGE_RISING));
|
||||
}
|
||||
|
||||
static inline bool pic32mz_pullup(pinset_t pinset)
|
||||
{
|
||||
return ((pinset & GPIO_PULLUP) != 0);
|
||||
@ -215,8 +227,11 @@ static int pic32mz_cninterrupt(int irq, FAR void *context, FAR void *arg)
|
||||
struct ioport_level2_s *handlers;
|
||||
xcpt_t handler;
|
||||
uintptr_t base;
|
||||
uint32_t cnstat;
|
||||
uint32_t cncon;
|
||||
uint32_t cnen;
|
||||
uint32_t cnne;
|
||||
uint32_t cnstat;
|
||||
uint32_t cnf;
|
||||
uint32_t pending;
|
||||
uint32_t regval;
|
||||
int ioport;
|
||||
@ -240,29 +255,29 @@ static int pic32mz_cninterrupt(int irq, FAR void *context, FAR void *arg)
|
||||
base = g_gpiobase[ioport];
|
||||
DEBUGASSERT(handlers && base);
|
||||
|
||||
/* Get the control registers. It will be used to get the interrupt type. */
|
||||
|
||||
cncon = getreg32(base + PIC32MZ_IOPORT_CNCON_OFFSET);
|
||||
|
||||
if (handlers && base)
|
||||
{
|
||||
/* Mismatch mode selected? */
|
||||
|
||||
if ((cncon & IOPORT_CNCON_EDGEDETECT) == 0)
|
||||
{
|
||||
/* Get the interrupt status associated with this interrupt */
|
||||
|
||||
cnstat = getreg32(base + PIC32MZ_IOPORT_CNSTAT_OFFSET);
|
||||
cnen = getreg32(base + PIC32MZ_IOPORT_CNSTAT_OFFSET);
|
||||
cnen = getreg32(base + PIC32MZ_IOPORT_CNEN_OFFSET);
|
||||
pending = cnstat & cnen;
|
||||
|
||||
/* Hmmm.. the data sheet implies that the status will pend
|
||||
* until the corresponding PORTx registers is read? Clear
|
||||
* pending status.
|
||||
*/
|
||||
|
||||
regval = getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET);
|
||||
UNUSED(regval);
|
||||
|
||||
/* Call all attached handlers for each pending interrupt */
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
/* Is this interrupt pending */
|
||||
|
||||
if ((pending & (1 << IOPORT_CNSTAT(i))) != 0)
|
||||
if ((pending & (IOPORT_CNSTAT(i))) != 0)
|
||||
{
|
||||
/* Yes.. Has the user attached a handler? */
|
||||
|
||||
@ -284,6 +299,61 @@ static int pic32mz_cninterrupt(int irq, FAR void *context, FAR void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear pending status. */
|
||||
|
||||
regval = getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET);
|
||||
UNUSED(regval);
|
||||
}
|
||||
|
||||
/* Edge detect mode selected. */
|
||||
|
||||
else
|
||||
{
|
||||
/* Get the interrupt status associated with this interrupt.
|
||||
* The interrupt is controlled by either CNEN (positive edge)
|
||||
* or CNNE (negative edge).
|
||||
*/
|
||||
|
||||
cnen = getreg32(base + PIC32MZ_IOPORT_CNEN_OFFSET);
|
||||
cnne = getreg32(base + PIC32MZ_IOPORT_CNNE_OFFSET);
|
||||
cnf = getreg32(base + PIC32MZ_IOPORT_CNF_OFFSET);
|
||||
pending = cnf & (cnen | cnne);
|
||||
|
||||
/* Call all attached handlers for each pending interrupt */
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
/* Is this interrupt pending */
|
||||
|
||||
if ((pending & (IOPORT_CNF(i))) != 0)
|
||||
{
|
||||
/* Yes.. Has the user attached a handler? */
|
||||
|
||||
handler = handlers->handler[i].entry;
|
||||
if (handler)
|
||||
{
|
||||
/* Yes.. call the attached handler */
|
||||
|
||||
status = handler(irq, context, handlers->handler[i].arg);
|
||||
|
||||
/* Keep track of the status of the last handler that
|
||||
* failed.
|
||||
*/
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
ret = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear pending status. */
|
||||
|
||||
putreg32(pending, base + PIC32MZ_IOPORT_CNFCLR_OFFSET);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Clear the pending interrupt */
|
||||
@ -309,6 +379,7 @@ static int pic32mz_cninterrupt(int irq, FAR void *context, FAR void *arg)
|
||||
void pic32mz_gpioirqinitialize(void)
|
||||
{
|
||||
uintptr_t base;
|
||||
uint32_t regval;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@ -327,6 +398,7 @@ void pic32mz_gpioirqinitialize(void)
|
||||
/* Reset all registers and disable the CN module */
|
||||
|
||||
putreg32(IOPORT_CNEN_ALL, base + PIC32MZ_IOPORT_CNENCLR_OFFSET);
|
||||
putreg32(IOPORT_CNNE_ALL, base + PIC32MZ_IOPORT_CNNECLR_OFFSET);
|
||||
putreg32(IOPORT_CNPU_ALL, base + PIC32MZ_IOPORT_CNPUCLR_OFFSET);
|
||||
putreg32(IOPORT_CNPD_ALL, base + PIC32MZ_IOPORT_CNPDCLR_OFFSET);
|
||||
putreg32(0, base + PIC32MZ_IOPORT_CNCON_OFFSET);
|
||||
@ -350,9 +422,14 @@ void pic32mz_gpioirqinitialize(void)
|
||||
|
||||
putreg32(IOPORT_CNCON_ON, base + PIC32MZ_IOPORT_CNCON_OFFSET);
|
||||
|
||||
/* And enable the GPIO interrupt. Same assumption as above. */
|
||||
/* Read the port to clear the interrupt. */
|
||||
|
||||
up_enable_irq(PIC32MZ_IRQ_PORTA + i);
|
||||
regval = getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET);
|
||||
UNUSED(regval);
|
||||
|
||||
/* Clear the CN interrupt flag. Same assumption as above. */
|
||||
|
||||
up_clrpend_irq(PIC32MZ_IRQ_PORTA + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -382,8 +459,7 @@ void pic32mz_gpioirqinitialize(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PIC32MZ_GPIOIRQ
|
||||
int pic32mz_gpioattach(uint32_t pinset, xcpt_t handler, void *arg)
|
||||
int pic32mz_gpioattach(pinset_t pinset, xcpt_t handler, void *arg)
|
||||
{
|
||||
struct ioport_level2_s *handlers;
|
||||
irqstate_t flags;
|
||||
@ -391,8 +467,6 @@ int pic32mz_gpioattach(uint32_t pinset, xcpt_t handler, void *arg)
|
||||
int ioport;
|
||||
int pin;
|
||||
|
||||
DEBUGASSERT(pin < IOPORT_NUMCN);
|
||||
|
||||
/* First verify that the pinset is configured as an interrupting input */
|
||||
|
||||
if (pic32mz_input(pinset) && pic32mz_interrupt(pinset))
|
||||
@ -468,6 +542,7 @@ int pic32mz_gpioattach(uint32_t pinset, xcpt_t handler, void *arg)
|
||||
*/
|
||||
|
||||
putreg32(1 << pin, base + PIC32MZ_IOPORT_CNENCLR_OFFSET);
|
||||
putreg32(1 << pin, base + PIC32MZ_IOPORT_CNNECLR_OFFSET);
|
||||
|
||||
/* Set the new handler (perhaps NULLifying the current handler) */
|
||||
|
||||
@ -506,13 +581,44 @@ void pic32mz_gpioirqenable(pinset_t pinset)
|
||||
DEBUGASSERT(base);
|
||||
if (base)
|
||||
{
|
||||
/* And enable the interrupt. NOTE that we don't actually check if
|
||||
/* Enable the correct CN interrupt.
|
||||
* NOTE that we don't actually check if
|
||||
* interrupts are configured for this IO port. If not, this operation
|
||||
* should do nothing.
|
||||
*/
|
||||
|
||||
if (!pic32mz_edgedetect(pinset))
|
||||
{
|
||||
/* If Edge detect is not selected, then CNEN
|
||||
* controls the interrupt.
|
||||
*/
|
||||
|
||||
putreg32(1 << pin, base + PIC32MZ_IOPORT_CNENSET_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable edge detect. */
|
||||
|
||||
putreg32(IOPORT_CNCON_EDGEDETECT, base + PIC32MZ_IOPORT_CNCONSET_OFFSET);
|
||||
|
||||
if (pic32mz_edgemode(pinset) == GPIO_EDGE_RISING)
|
||||
{
|
||||
/* Rising edge selected. CNEN controls the interrupt. */
|
||||
|
||||
putreg32(1 << pin, base + PIC32MZ_IOPORT_CNENSET_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Falling edge selected. CNNE controls the interrupt. */
|
||||
|
||||
putreg32(1 << pin, base + PIC32MZ_IOPORT_CNNESET_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
/* And enable the interrupt. */
|
||||
|
||||
up_enable_irq(ioport + PIC32MZ_IRQ_PORTA);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -541,13 +647,40 @@ void pic32mz_gpioirqdisable(pinset_t pinset)
|
||||
DEBUGASSERT(base);
|
||||
if (base)
|
||||
{
|
||||
/* And disable the interrupt. NOTE that we don't actually check if
|
||||
/* And disable the correct interrupt.
|
||||
* NOTE that we don't actually check if
|
||||
* interrupts are configured for this IO port. If not, this operation
|
||||
* should do nothing.
|
||||
*/
|
||||
|
||||
if (!pic32mz_edgedetect(pinset))
|
||||
{
|
||||
/* If Edge detect is not selected, then CNEN
|
||||
* controls the interrupt.
|
||||
*/
|
||||
|
||||
putreg32(1 << pin, base + PIC32MZ_IOPORT_CNENCLR_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pic32mz_edgemode(pinset) == GPIO_EDGE_RISING)
|
||||
{
|
||||
/* Rising edge selected.
|
||||
* CNEN controls the interrupt.
|
||||
*/
|
||||
|
||||
putreg32(1 << pin, base + PIC32MZ_IOPORT_CNENCLR_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Falling edge selected.
|
||||
* CNNE controls the interrupt.
|
||||
*/
|
||||
|
||||
putreg32(1 << pin, base + PIC32MZ_IOPORT_CNNECLR_OFFSET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PIC32MZ_GPIOIRQ */
|
||||
|
Loading…
Reference in New Issue
Block a user