Skip to content

alif: Add support for machine_pin IRQ. #17511

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

iabdalkader
Copy link
Contributor

@iabdalkader iabdalkader commented Jun 17, 2025

Summary

Adds support for machine.Pin.IRQ().

Testing

Rising/falling edge seems to work fine. Also made sure IRQs are disabled on soft-reset.

Trade-offs and Alternatives

I think mpirq.c needs a finaliser, this way we won't need machine_pin_irq_deinit();: when the object is collected, it could just disable the IRQ by calling trigger(0). Also, it would be nice if mp_irq_obj_t could just add the flags and trigger as they seem to be used by all ports, and all ports use this weird object to wrap mp_irq_obj_t to add the fields.

Finally, CYW43 should use the Python API to create a pin and register an IRQ, and set it to reserved. For now I just avoided redefining the IRQ handler so it builds.

@iabdalkader iabdalkader force-pushed the alif_machine_pin_irq branch 2 times, most recently from d39eb29 to b1a07fd Compare June 17, 2025 17:05
@dpgeorge dpgeorge self-assigned this Jun 19, 2025
@dpgeorge
Copy link
Member

Can you please show your testing code? I tried this on ALIF_ENSEMBLE with the following code:

from machine import Pin
p = Pin("JOY_LEFT", Pin.IN, Pin.PULL_UP)
p.irq(lambda x: print(x), Pin.IRQ_RISING | Pin.IRQ_FALLING)

It didn't do anything, it didn't run the IRQ lambda.

@iabdalkader
Copy link
Contributor Author

iabdalkader commented Jun 26, 2025

Can you please show your testing code? I tried this on ALIF_ENSEMBLE with the following code:

This is my test script, maybe you need to set the trigger with the keyboard? Should I try it again maybe it's broken?

from machine import Pin
import time


int_pin = Pin("P9", Pin.IN, Pin.PULL_UP)
def int_callback(line):
    print("callback")

int_pin.irq(handler=int_callback, trigger=Pin.IRQ_FALLING, hard=False)

while True:
    time.sleep_ms(1000)

I think LPGPIO is not working for some reason.

@dpgeorge
Copy link
Member

OK, so it works on P1_3, but not on P15_0.

@iabdalkader
Copy link
Contributor Author

OK, so it works on P1_3, but not on P15_0.

Yes, I think I see the issue.

@iabdalkader iabdalkader force-pushed the alif_machine_pin_irq branch from b1a07fd to 83ad725 Compare June 26, 2025 07:38
@iabdalkader
Copy link
Contributor Author

iabdalkader commented Jun 26, 2025

Should be fixed now. You could just use int_pin = Pin("USR_SW", Pin.IN, Pin.PULL_UP)

@iabdalkader iabdalkader force-pushed the alif_machine_pin_irq branch from 83ad725 to 693cbe2 Compare June 26, 2025 11:49
@dpgeorge
Copy link
Member

I've tested this again but it's still not working properly:

  • now only P15_0 works, and P1_3 doesn't
  • it always triggers on rising and falling edges, regardless of the trigger value

Here's my test:

import time
from machine import Pin


def callback(pin):
    print("[irq", pin, pin.irq().flags(), "]")


p_out = Pin("P0_0", Pin.OUT, value=0)
p_in = Pin("P15_0", Pin.IN, Pin.PULL_UP)

for hard in (False, True):
    for trigger in (0, Pin.IRQ_FALLING, Pin.IRQ_RISING, Pin.IRQ_FALLING | Pin.IRQ_RISING):
        print(f"TEST {hard=} {trigger=}")
        p_in.irq(callback, trigger=trigger, hard=hard)
        for _ in range(4):
            p_out(0)
            print(f"out={p_out()} in={p_in()}")
            time.sleep_ms(10)
            p_out(1)
            print(f"out={p_out()} in={p_in()}")
            time.sleep_ms(10)

P0_0 is the output pin that toggles. P15_0 is the input pin and you must connect them together with a wire. The output I see is:

TEST hard=False trigger=0
out=0 in=0
out=1 in=1
out=0 in=0
out=1 in=1
out=0 in=0
out=1 in=1
out=0 in=0
out=1 in=1
TEST hard=False trigger=1
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
TEST hard=False trigger=2
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
TEST hard=False trigger=3
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=0 in=0[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=1 in=1[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
TEST hard=True trigger=0
out=0 in=0
out=1 in=1
out=0 in=0
out=1 in=1
out=0 in=0
out=1 in=1
out=0 in=0
out=1 in=1
TEST hard=True trigger=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 1 ]
out=1 in=1
TEST hard=True trigger=2
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 2 ]
out=1 in=1
TEST hard=True trigger=3
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=1 in=1
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=0 in=0
[irq Pin(P15_0, mode=IN, pull=PULL_UP) 3 ]
out=1 in=1

You can see that it always triggers on both edges.

If P15_0 is replaced with P1_3 (and P1_3 is wired to P0_0) then the callback is never called.

I'm testing on an Alif dev kit with MCU revision B4.

Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
@iabdalkader iabdalkader force-pushed the alif_machine_pin_irq branch from 693cbe2 to 1e780db Compare June 27, 2025 10:54
@iabdalkader
Copy link
Contributor Author

I've tested this again but it's still not working properly:

Yes I see it too, but I can't fix that. It seems that regardless of the edge you configure, BOTH is stuck (see GPIO_CONFIG_REG1 bit 21):

$4 = {
  GPIO_SWPORTA_DR = 0,
  GPIO_SWPORTA_DDR = 1,
  GPIO_SWPORTA_CTL = 0,
  RESERVED = {0, 0, 0, 0, 0, 0, 0, 0, 0},
  GPIO_INTEN = 8,
  GPIO_INTMASK = 0,
  GPIO_INTTYPE_LEVEL = 8,
  GPIO_INT_POLARITY = 0,
  GPIO_INTSTATUS = 0,
  GPIO_RAW_INTSTATUS = 0,
  GPIO_DEBOUNCE = 8,
  GPIO_PORTA_EOI = 0,
  GPIO_EXT_PORTA = 0,
  RESERVED1 = {0, 0, 0},
  GPIO_LS_SYNC = 0,
  RESERVED2 = 0,
  GPIO_INT_BOTHEDGE = 0,
  GPIO_VER_ID_CODE = 842085162,
  GPIO_CONFIG_REG2 = 236775,
  GPIO_CONFIG_REG1 = 4157682
}

@dpgeorge
Copy link
Member

It looks like you fixed this? The test I wrote above is now working.

@iabdalkader
Copy link
Contributor Author

It looks like you fixed this? The test I wrote above is now working.

Some bits get stuck and should be cleared before reconfiguring the trigger, so I cleared them, but GPIO_CONFIG_REG1 is still wrong and I don't get any IRQs when using P1 and P2.

@iabdalkader
Copy link
Contributor Author

The wire I used to short the pins for testing didn't make good contact. Never mind it's working now.

@dpgeorge
Copy link
Member

Testing again with my test above, it works fine with P15_0 as the input (P0_0 is output), but does not work at all if P1_3 is the input. I can see that the logic value read on input pin P1_3 is the same as what P0_0 is outputting, but there's no IRQ occurring.

@iabdalkader
Copy link
Contributor Author

but does not work at all if P1_3 is the input

Is it used for something else on the devkit? Note that some pins were 1.8v on our board. Anyway, I don't have access to that pin, maybe @kwagyeman can test.

@dpgeorge
Copy link
Member

I tested P1_2 and P0_5 as inputs as well, and neither of them work.

@kwagyeman
Copy link
Contributor

P1_3 is P9 on the AE3. This definitely works with commits to our micropython fork. Tested with the OLED shield:

openmv@f71dd03

@dpgeorge
Copy link
Member

Testing this PR on OPENMV_AE3 with the following pairs of pins connected:

  • P8/P9 = P1_2/P1_3
  • P6/P7 = P7_2/P7_3

Neither pair works (in either order, eg P8 being input or P9).

@iabdalkader
Copy link
Contributor Author

Testing this PR on OPENMV_AE3 with the following pairs of pins connected:

Does it work without debounce? That's one of the changes added to this PR. Note that I'm waiting for this to fix and sync machine_pin.c in our fork, it's actually outdated and broken.

@dpgeorge
Copy link
Member

dpgeorge commented Jul 1, 2025

Does it work without debounce?

No, still doesn't work on OPENMV_AE3 with pins P6/P7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants