Skip to content

Commit

Permalink
tests/extmod_hardware: Add tests for machine.UART.IRQ_RX/RXIDLE/BREAK.
Browse files Browse the repository at this point in the history
These all require hardware connections, so live in a different directory.

Except for the IRQ_BREAK test of ESP32 devices a single UART with
loopback is sufficient.

General:
    SAMD21: Due to the limited flash size only SAMD21 devices with
    external flash support uart.irq().

IRQ_BREAK:
    ESP32 needs different UART devices for creating and sensing a break.
    Lacking a second UART the test is skipped for ESP32S2 and ESP32C3.
    RP2 does not pass the test reliable at 115200 baud, reason to be
    found. Thus the upper limit is set to 57600 Baud.

    Coverage:
        esp32  pass when different UART devices are used.
        rp2    pass up to 57600 baud

IRQ_RX:
    SAMD21: Being a slow device it needs data to be sent byte-by-byte
    at 9600 baud, since the IRQ callback is scheduled delayed and then
    the flags do not match any more. The data matches since it is queued
    in the FIFO resp. ringbuffer.

    CC3200: The test cannot be performed since no calls are accepted in
    the IRQ handler like u.read(). Skipped.

    Coverage:
        cc3200 fail due to major differences in the implementation.
        esp32  pass
        nrf    pass
        renesas-ra pass
        samd   pass see the notes.
        stm32  pass

IRQ_RXIDLE:
    STM32: With PyBoard the IRQ is called several times, but only
           once with the flag IRQ_RXIDLE set.

    Coverage:
        esp32    pass
        mimxrt   pass
        renesas-ra pass
        rp2      pass
        samd     pass for both SAMD21 and SAMD51
        stm32    fail. see notes.

Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: robert-hh <robert@hammelrath.com>
  • Loading branch information
dpgeorge authored and robert-hh committed Aug 20, 2024
1 parent c1ac036 commit 8a3ad08
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 0 deletions.
62 changes: 62 additions & 0 deletions tests/extmod_hardware/machine_uart_irq_break.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Test machine.UART.IRQ_BREAK firing after a break is received.
#
# IMPORTANT: This test requires hardware connections: the UART TX and RX
# pins must be wired together.

try:
from machine import UART

UART.IRQ_BREAK
except (ImportError, AttributeError):
print("SKIP")
raise SystemExit

import time, sys

# Configure pins based on the target.
if "esp32" in sys.platform:
if "ESP32S2" in sys.implementation._machine or "ESP32C3" in sys.implementation._machine:
print("SKIP")
raise SystemExit
# ESP32 needs separate UART instances for the test
recv_uart_id = 1
recv_tx_pin = 14
recv_rx_pin = 5
send_uart_id = 2
send_tx_pin = 4
send_rx_pin = 12
elif "rp2" in sys.platform:
recv_uart_id = 0
send_uart_id = 0
recv_tx_pin = "GPIO0"
recv_rx_pin = "GPIO1"
else:
print("Please add support for this test on this platform.")
raise SystemExit


def irq(u):
print("IRQ_BREAK:", bool(u.irq().flags() & u.IRQ_BREAK), "data:", u.read(1))


# Test that the IRQ is called for each break received.
for bits_per_s in (2400, 9600, 57600):
recv_uart = UART(recv_uart_id, bits_per_s, tx=recv_tx_pin, rx=recv_rx_pin)
if recv_uart_id != send_uart_id:
send_uart = UART(send_uart_id, bits_per_s, tx=send_tx_pin, rx=send_rx_pin)
else:
send_uart = recv_uart

recv_uart.irq(irq, recv_uart.IRQ_BREAK)

print("write", bits_per_s)
for i in range(3):
send_uart.write(str(i))
send_uart.flush()
time.sleep_ms(10)
send_uart.sendbreak()
time.sleep_ms(10)
if "esp32" in sys.platform:
# On esp32 a read is needed to read in the break byte.
recv_uart.read()
print("done")
15 changes: 15 additions & 0 deletions tests/extmod_hardware/machine_uart_irq_break.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
write 2400
IRQ_BREAK: True data: b'0'
IRQ_BREAK: True data: b'1'
IRQ_BREAK: True data: b'2'
done
write 9600
IRQ_BREAK: True data: b'0'
IRQ_BREAK: True data: b'1'
IRQ_BREAK: True data: b'2'
done
write 57600
IRQ_BREAK: True data: b'0'
IRQ_BREAK: True data: b'1'
IRQ_BREAK: True data: b'2'
done
82 changes: 82 additions & 0 deletions tests/extmod_hardware/machine_uart_irq_rx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Test machine.UART.IRQ_RX firing for each character received.
#
# IMPORTANT: This test requires hardware connections: the UART TX and RX
# pins must be wired together.

try:
from machine import UART

UART.IRQ_RX
except (ImportError, AttributeError):
print("SKIP")
raise SystemExit

import time, sys

byte_by_byte = False
# Configure pins based on the target.
if "esp32" in sys.platform:
uart_id = 1
tx_pin = 4
rx_pin = 5
elif "pyboard" in sys.platform:
uart_id = 4
tx_pin = None # PA0
rx_pin = None # PA1
elif "samd" in sys.platform and "ItsyBitsy M0" in sys.implementation._machine:
uart_id = 0
tx_pin = "D1"
rx_pin = "D0"
byte_by_byte = True
elif "samd" in sys.platform and "ItsyBitsy M4" in sys.implementation._machine:
uart_id = 3
tx_pin = "D1"
rx_pin = "D0"
elif "samd" in sys.platform and "Seeed" in sys.implementation._machine:
uart_id = 0
tx_pin = "A4_D4"
rx_pin = "A5_D5"
elif "nrf" in sys.platform:
uart_id = 0
tx_pin = None
rx_pin = None
elif "renesas-ra" in sys.platform:
uart_id = 9
tx_pin = None # P602 @ RA6M2
rx_pin = None # P601 @ RA6M2
elif "CC3200" in sys.implementation._machine:
# CC3200 doesn't work because it's too slow and has an allocation error in the handler.
print("SKIP")
raise SystemExit
else:
print("Please add support for this test on this platform.")
raise SystemExit


def irq(u):
print("IRQ_RX:", bool(u.irq().flags() & u.IRQ_RX), "data:", u.read(1))


text = "1234"

# Test that the IRQ is called for each byte received.
# Use slow baudrates so that the IRQ has time to run.
for bits_per_s in (2400, 9600):
if tx_pin is None:
uart = UART(uart_id, bits_per_s)
else:
uart = UART(uart_id, bits_per_s, tx=tx_pin, rx=rx_pin)

uart.irq(irq, uart.IRQ_RX)

print("write", bits_per_s)
if byte_by_byte:
# slow devices need data to be sent slow
for c in text:
uart.write(c)
uart.flush()
else:
uart.write(text)
uart.flush()
time.sleep_ms(100)
print("done")
12 changes: 12 additions & 0 deletions tests/extmod_hardware/machine_uart_irq_rx.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
write 2400
IRQ_RX: True data: b'1'
IRQ_RX: True data: b'2'
IRQ_RX: True data: b'3'
IRQ_RX: True data: b'4'
done
write 9600
IRQ_RX: True data: b'1'
IRQ_RX: True data: b'2'
IRQ_RX: True data: b'3'
IRQ_RX: True data: b'4'
done
70 changes: 70 additions & 0 deletions tests/extmod_hardware/machine_uart_irq_rxidle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Test machine.UART.IRQ_RXIDLE firing after a set of characters are received.
#
# IMPORTANT: This test requires hardware connections: the UART TX and RX
# pins must be wired together.

try:
from machine import UART

UART.IRQ_RXIDLE
except (ImportError, AttributeError):
print("SKIP")
raise SystemExit

import time, sys

# Configure pins based on the target.
if "esp32" in sys.platform:
uart_id = 1
tx_pin = 4
rx_pin = 5
elif "mimxrt" in sys.platform and "Teensy 4" in sys.implementation._machine:
uart_id = 1
tx_pin = None
elif "pyboard" in sys.platform:
uart_id = 4
tx_pin = None # PA0
rx_pin = None # PA1
elif "renesas-ra" in sys.platform:
uart_id = 9
tx_pin = None # P602 @ RA6M2
rx_pin = None # P601 @ RA6M2
elif "rp2" in sys.platform:
uart_id = 0
tx_pin = "GPIO0"
rx_pin = "GPIO1"
elif "samd" in sys.platform and "ItsyBitsy M0" in sys.implementation._machine:
uart_id = 0
tx_pin = "D1"
rx_pin = "D0"
byte_by_byte = True
elif "samd" in sys.platform and "ItsyBitsy M4" in sys.implementation._machine:
uart_id = 3
tx_pin = "D1"
rx_pin = "D0"
else:
print("Please add support for this test on this platform.")
raise SystemExit


def irq(u):
print("IRQ_RXIDLE:", bool(u.irq().flags() & u.IRQ_RXIDLE), "data:", u.read())


text = "12345678"

# Test that the IRQ is called for each set of byte received.
for bits_per_s in (2400, 9600, 115200):
if tx_pin is None:
uart = UART(uart_id, bits_per_s)
else:
uart = UART(uart_id, bits_per_s, tx=tx_pin, rx=rx_pin)

uart.irq(irq, uart.IRQ_RXIDLE)

print("write", bits_per_s)
uart.write(text)
uart.flush()
print("ready")
time.sleep_ms(100)
print("done")
12 changes: 12 additions & 0 deletions tests/extmod_hardware/machine_uart_irq_rxidle.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
write 2400
ready
IRQ_RXIDLE: True data: b'12345678'
done
write 9600
ready
IRQ_RXIDLE: True data: b'12345678'
done
write 115200
ready
IRQ_RXIDLE: True data: b'12345678'
done

0 comments on commit 8a3ad08

Please sign in to comment.