Created
May 24, 2021 17:21
-
-
Save kilograham/0d8a996d1539958d9a93518f5e9e08ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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