Skip to content

Instantly share code, notes, and snippets.

@kilograham
Created May 24, 2021 17:21
Show Gist options
  • Save kilograham/0d8a996d1539958d9a93518f5e9e08ea to your computer and use it in GitHub Desktop.
Save kilograham/0d8a996d1539958d9a93518f5e9e08ea to your computer and use it in GitHub Desktop.
diff --git a/pio/CMakeLists.txt b/pio/CMakeLists.txt
index 8855161..363c2fd 100644
--- a/pio/CMakeLists.txt
+++ b/pio/CMakeLists.txt
@@ -6,6 +6,7 @@ if (NOT PICO_NO_HARDWARE)
add_subdirectory(hello_pio)
add_subdirectory(hub75)
add_subdirectory(i2c)
+ add_subdirectory(irq_test)
add_subdirectory(logic_analyser)
add_subdirectory(manchester_encoding)
add_subdirectory(pio_blink)
diff --git a/pio/irq_test/CMakeLists.txt b/pio/irq_test/CMakeLists.txt
new file mode 100644
index 0000000..ecca2d4
--- /dev/null
+++ b/pio/irq_test/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_executable(irq_test
+ irq_test.c
+ )
+
+# Pull in our pico_stdlib which aggregates commonly used features
+target_link_libraries(irq_test pico_stdlib hardware_pio)
+
+pico_generate_pio_header(irq_test ${CMAKE_CURRENT_LIST_DIR}/irq_test.pio)
+# create map/bin/hex/uf2 file etc.
+pico_add_extra_outputs(irq_test)
+
+# add url via pico_set_program_url
+example_auto_set_url(irq_test)
diff --git a/pio/irq_test/irq_test.c b/pio/irq_test/irq_test.c
new file mode 100644
index 0000000..8545b78
--- /dev/null
+++ b/pio/irq_test/irq_test.c
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include "pico/stdlib.h"
+#include <inttypes.h>
+#include "irq_test.pio.h"
+#include "hardware/pio.h"
+#include "hardware/irq.h"
+
+#define DELAY 300
+
+#define pio pio0
+#define sm 0
+#define COUNT 20
+
+volatile int remaining;
+
+enum type {
+ BLOCKING_PUSH = 0,
+ IRQ_A,
+ IRQ_B,
+ IRQ_C,
+ LAST_TYPE,
+};
+
+
+static void __not_in_flash_func(irq_handler_A)(void) {
+ int r = remaining;
+ while (r && pio->ints0 & (PIO_IRQ0_INTS_SM0_TXNFULL_BITS << sm)) {
+ pio->txf[sm] = DELAY;
+ r--;
+ }
+ if (!r) {
+ hw_clear_bits(&pio->inte0,PIO_IRQ0_INTE_SM0_TXNFULL_BITS << sm);
+ }
+ remaining = r;
+}
+
+static void __not_in_flash_func(irq_handler_B)(void) {
+ if (remaining) {
+ pio->txf[sm] = DELAY;
+ remaining--;
+ } else {
+ hw_clear_bits(&pio->inte0,PIO_IRQ0_INTE_SM0_TXNFULL_BITS << sm);
+ }
+}
+
+static void __not_in_flash_func(irq_handler_C)(void) {
+ int r = remaining;
+ while (r && !pio_sm_is_tx_fifo_full(pio, sm)) {
+ pio->txf[sm] = DELAY;
+ r--;
+ }
+ if (!r) {
+ hw_clear_bits(&pio->inte0,PIO_IRQ0_INTE_SM0_TXNFULL_BITS << sm);
+ }
+ remaining = r;
+}
+
+int __not_in_flash_func(main)() {
+ stdio_init_all();
+ uint offset = pio_add_program(pio, &irq_test_program);
+ pio_sm_config c = irq_test_program_get_default_config(offset);
+ sm_config_set_out_shift(&c, true, true, 32);
+ sm_config_set_in_shift(&c, true, true, 32);
+ for(enum type type = BLOCKING_PUSH; type < LAST_TYPE; type++) {
+#ifdef ONLY_TYPE
+ if (type != ONLY_TYPE) continue;
+#endif
+ pio_sm_init(pio, sm, offset, &c);
+ pio_sm_set_enabled(pio, sm, true);
+ remaining = COUNT;
+ switch (type) {
+ case BLOCKING_PUSH:
+ puts("Blocking push");
+ for (int i = 0; i < COUNT; i++) {
+ pio_sm_put_blocking(pio, sm, DELAY);
+ remaining--;
+ }
+ break;
+ case IRQ_A:
+ puts("IRQ with ints loop");
+ for (int i = 0; i < MIN(COUNT, 4); i++) {
+ pio_sm_put_blocking(pio, sm, DELAY);
+ remaining--;
+ }
+ pio0->inte0 |= 1u << (PIO_IRQ0_INTE_SM0_TXNFULL_LSB + sm);
+ irq_set_exclusive_handler(PIO0_IRQ_0, irq_handler_A);
+ irq_set_enabled(PIO0_IRQ_0, true);
+ break;
+ case IRQ_B:
+ puts("IRQ with single ints");
+ for (int i = 0; i < MIN(COUNT, 4); i++) {
+ pio_sm_put_blocking(pio, sm, DELAY);
+ remaining--;
+ }
+ pio0->inte0 |= 1u << (PIO_IRQ0_INTE_SM0_TXNFULL_LSB + sm);
+ irq_set_exclusive_handler(PIO0_IRQ_0, irq_handler_B);
+ irq_set_enabled(PIO0_IRQ_0, true);
+ break;
+ case IRQ_C:
+ puts("IRQ with fifo_full_check loop");
+ for (int i = 0; i < MIN(COUNT, 4); i++) {
+ pio_sm_put_blocking(pio, sm, DELAY);
+ remaining--;
+ }
+ pio0->inte0 |= 1u << (PIO_IRQ0_INTE_SM0_TXNFULL_LSB + sm);
+ irq_set_exclusive_handler(PIO0_IRQ_0, irq_handler_C);
+ irq_set_enabled(PIO0_IRQ_0, true);
+ break;
+ default:
+ panic_unsupported();
+ }
+
+ int loops = 0;
+ while (remaining) {
+ loops++; // if we are using interrupts we want to see the IRQ not active sometimes
+ }
+ // deliberately not waiting in case we fail
+ sleep_ms(500);
+
+ printf(" Loops while remaining: %d\n", loops);
+ pio_sm_exec(pio, sm, pio_encode_in(pio_x, 32));
+ printf(" Output count: %d\n", -(int32_t) pio_sm_get_blocking(pio, sm));
+ switch (type) {
+ case IRQ_A:
+ irq_remove_handler(PIO0_IRQ_0, irq_handler_A);
+ irq_set_enabled(PIO0_IRQ_0, false);
+ break;
+ case IRQ_B:
+ irq_remove_handler(PIO0_IRQ_0, irq_handler_B);
+ irq_set_enabled(PIO0_IRQ_0, false);
+ break;
+ case IRQ_C:
+ irq_remove_handler(PIO0_IRQ_0, irq_handler_C);
+ irq_set_enabled(PIO0_IRQ_0, false);
+ break;
+ default:
+ break;
+ }
+ pio_sm_set_enabled(pio, sm, false);
+ }
+ return 0;
+}
diff --git a/pio/irq_test/irq_test.pio b/pio/irq_test/irq_test.pio
new file mode 100644
index 0000000..56f0560
--- /dev/null
+++ b/pio/irq_test/irq_test.pio
@@ -0,0 +1,9 @@
+.program irq_test
+ set x, 0
+.wrap_target
+lp:
+ out y, 32
+ jmp x-- lp2
+lp2:
+ jmp y-- lp2
+.wrap
\ No newline at end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment