mirror of
https://github.com/apache/nuttx.git
synced 2026-10-10 15:50:23 +00:00
arch/mips/pic32mz: support GPIO interrupts on the PIC32MZ-W1.
The change notification code assumed the EC/EF layout: the IRQ of an I/O port was PIC32MZ_IRQ_PORTA plus the port index, and initialization reset the change notification registers of every port index. The PIC32MZ-W1 only implements PORTA, PORTB, PORTC and PORTK, its change notification vectors are PIC32MZ_IRQ_CNA/CNB/CNC/CNK, and the addresses of the missing ports D-J belong to other peripherals (I2C1 is at the PORTE address). Map the port index to its IRQ through a table on the W1, skip the unimplemented ports during initialization, and pass the port index to the common handler as its argument instead of deriving it from the IRQ number. Hide the PORTD-PORTJ interrupt options on the W1. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
This commit is contained in:
parent
b1f13e60e5
commit
ecfe2ed4d3
2 changed files with 44 additions and 10 deletions
|
|
@ -998,26 +998,32 @@ config PIC32MZ_GPIOIRQ_PORTC
|
|||
config PIC32MZ_GPIOIRQ_PORTD
|
||||
bool "I/O PORTD Interrupt Support"
|
||||
default n
|
||||
depends on !ARCH_CHIP_PIC32MZW1
|
||||
|
||||
config PIC32MZ_GPIOIRQ_PORTE
|
||||
bool "I/O PORTE Interrupt Support"
|
||||
default n
|
||||
depends on !ARCH_CHIP_PIC32MZW1
|
||||
|
||||
config PIC32MZ_GPIOIRQ_PORTF
|
||||
bool "I/O PORTF Interrupt Support"
|
||||
default n
|
||||
depends on !ARCH_CHIP_PIC32MZW1
|
||||
|
||||
config PIC32MZ_GPIOIRQ_PORTG
|
||||
bool "I/O PORTG Interrupt Support"
|
||||
default n
|
||||
depends on !ARCH_CHIP_PIC32MZW1
|
||||
|
||||
config PIC32MZ_GPIOIRQ_PORTH
|
||||
bool "I/O PORTH Interrupt Support"
|
||||
default n
|
||||
depends on !ARCH_CHIP_PIC32MZW1
|
||||
|
||||
config PIC32MZ_GPIOIRQ_PORTJ
|
||||
bool "I/O PORTJ Interrupt Support"
|
||||
default n
|
||||
depends on !ARCH_CHIP_PIC32MZW1
|
||||
|
||||
config PIC32MZ_GPIOIRQ_PORTK
|
||||
bool "I/O PORTK Interrupt Support"
|
||||
|
|
|
|||
|
|
@ -152,6 +152,27 @@ static struct ioport_level2_s * const g_level2_handlers[CHIP_NPORTS] =
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_CHIP_PIC32MZW1
|
||||
/* Look-up of port to change notification IRQ. The PIC32MZ-W1 implements
|
||||
* only PORTA, PORTB, PORTC and PORTK, so the port index cannot be added to
|
||||
* the PORTA IRQ number. Zero marks an unimplemented port.
|
||||
*/
|
||||
|
||||
static const uint8_t g_cnirq[CHIP_NPORTS] =
|
||||
{
|
||||
[PIC32MZ_IOPORTA] = PIC32MZ_IRQ_CNA,
|
||||
[PIC32MZ_IOPORTB] = PIC32MZ_IRQ_CNB,
|
||||
[PIC32MZ_IOPORTC] = PIC32MZ_IRQ_CNC,
|
||||
[PIC32MZ_IOPORTK] = PIC32MZ_IRQ_CNK,
|
||||
};
|
||||
|
||||
# define pic32mz_cnirq(ioport) ((int)g_cnirq[ioport])
|
||||
# define pic32mz_haveport(ioport) (g_cnirq[ioport] != 0)
|
||||
#else
|
||||
# define pic32mz_cnirq(ioport) (PIC32MZ_IRQ_PORTA + (ioport))
|
||||
# define pic32mz_haveport(ioport) (true)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -225,12 +246,11 @@ static int pic32mz_cninterrupt(int irq, void *context, void *arg)
|
|||
int ret = OK;
|
||||
int i;
|
||||
|
||||
/* Get the IO port index from the IRQ number. This, of course,
|
||||
* assumes that the irq numbers are consecutive beginning with
|
||||
* IOPORTA.
|
||||
/* The IO port index was provided as the argument when the handler was
|
||||
* attached.
|
||||
*/
|
||||
|
||||
ioport = irq - PIC32MZ_IRQ_PORTA;
|
||||
ioport = (int)(uintptr_t)arg;
|
||||
DEBUGASSERT(ioport >= 0 && ioport < CHIP_NPORTS);
|
||||
|
||||
/* If we got this interrupt, then there must also be an array
|
||||
|
|
@ -377,6 +397,13 @@ void pic32mz_gpioirqinitialize(void)
|
|||
|
||||
for (i = 0; i < CHIP_NPORTS; i++)
|
||||
{
|
||||
/* Skip IO ports that are not implemented on this part */
|
||||
|
||||
if (!pic32mz_haveport(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the base address of this IO port peripheral */
|
||||
|
||||
base = g_gpiobase[i];
|
||||
|
|
@ -395,11 +422,12 @@ void pic32mz_gpioirqinitialize(void)
|
|||
if (g_level2_handlers[i] != NULL)
|
||||
{
|
||||
/* Yes.. Attach the common change notice interrupt handler
|
||||
* to the IO port interrupt. Notice that this assumes that
|
||||
* each IRQ number is consecutive beginning with IOPORTA.
|
||||
* to the IO port interrupt. The IO port index is passed as the
|
||||
* argument.
|
||||
*/
|
||||
|
||||
ret = irq_attach(PIC32MZ_IRQ_PORTA + i, pic32mz_cninterrupt, NULL);
|
||||
ret = irq_attach(pic32mz_cnirq(i), pic32mz_cninterrupt,
|
||||
(void *)(uintptr_t)i);
|
||||
DEBUGASSERT(ret == OK);
|
||||
UNUSED(ret);
|
||||
|
||||
|
|
@ -414,9 +442,9 @@ void pic32mz_gpioirqinitialize(void)
|
|||
regval = getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET);
|
||||
UNUSED(regval);
|
||||
|
||||
/* Clear the CN interrupt flag. Same assumption as above. */
|
||||
/* Clear the CN interrupt flag. */
|
||||
|
||||
mips_clrpend_irq(PIC32MZ_IRQ_PORTA + i);
|
||||
mips_clrpend_irq(pic32mz_cnirq(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -605,7 +633,7 @@ void pic32mz_gpioirqenable(pinset_t pinset)
|
|||
|
||||
/* And enable the interrupt. */
|
||||
|
||||
up_enable_irq(ioport + PIC32MZ_IRQ_PORTA);
|
||||
up_enable_irq(pic32mz_cnirq(ioport));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue