aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2011-08-03 17:07:53 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2011-08-03 17:07:53 -0400
commit8d02e8e9fd7341dc54684b45125b0cfc8e5a98f3 (patch)
tree796b673d2d39db6ac2e7780f96e37f486f0a103f /examples
parent722b31d62740de47b417708a7428673faf3d4cab (diff)
downloadlibrambutan-8d02e8e9fd7341dc54684b45125b0cfc8e5a98f3.tar.gz
librambutan-8d02e8e9fd7341dc54684b45125b0cfc8e5a98f3.zip
Add examples/mini-exti-test.cpp.
Nonportable (Maple Mini only) test of external interrupt functionality. When wired properly, this triggers various EXTI lines simultaneously, keeping track of the number of times each handler is invoked.
Diffstat (limited to 'examples')
-rw-r--r--examples/mini-exti-test.cpp251
1 files changed, 251 insertions, 0 deletions
diff --git a/examples/mini-exti-test.cpp b/examples/mini-exti-test.cpp
new file mode 100644
index 0000000..e65c610
--- /dev/null
+++ b/examples/mini-exti-test.cpp
@@ -0,0 +1,251 @@
+/*
+ * EXTI test (Maple Mini only).
+ *
+ * Setup: For i from 1 to N_EXTI (see below), connect exti_i_pin to
+ * src_i_pin. Connect via SerialUSB and press a key to perform a test
+ * run. In the printed results For each EXTI within a test run, the
+ * number triggered should match the number handled.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "wirish.h"
+
+// test routines
+void run_exti_test(void);
+void print_test_results(void);
+
+// -- State -------------------------------------------------------------------
+
+// Test using EXTI lines 0 -- (N_EXTI - 1).
+#define N_EXTI 6
+
+// src_pins[i] determines the line level for EXTI i. these *must* be
+// in GPIOA. if you want to change them, make sure they don't
+// conflict with exti_pins[].
+//
+// src_pins[0] = D5 = PA6
+// src_pins[1] = D4 = PA7
+// src_pins[2] = D27 = PA8
+// src_pins[3] = D26 = PA9
+// src_pins[4] = D25 = PA10
+// src_pins[5] = D22 = PA13
+#define SRC0 5
+#define SRC0_BIT BIT(6)
+#define SRC1 4
+#define SRC1_BIT BIT(7)
+#define SRC2 27
+#define SRC2_BIT BIT(8)
+#define SRC3 26
+#define SRC3_BIT BIT(9)
+#define SRC4 25
+#define SRC4_BIT BIT(10)
+#define SRC5 22
+#define SRC5_BIT BIT(13)
+// Setting a bit in GPIOA_SRC_MSK means that the given src pin will
+// actually trigger interrupts. Useful for experimenting.
+#define GPIOA_SRC_MSK \
+ (SRC0_BIT | SRC1_BIT | SRC2_BIT | SRC3_BIT | SRC4_BIT | SRC5_BIT)
+const int src_pins[N_EXTI] = {
+ SRC0,
+ SRC1,
+ SRC2,
+ SRC3,
+ SRC4,
+ SRC5,
+};
+const int src_gpioa_msks[N_EXTI] = {
+ SRC0_BIT,
+ SRC1_BIT,
+ SRC2_BIT,
+ SRC3_BIT,
+ SRC4_BIT,
+ SRC5_BIT,
+};
+
+// exti_pins[i] <-> EXTI line i. make sure these don't conflict with
+// src_pins.
+const int exti_pins[N_EXTI] = {
+ D3, // PB0
+ D10, // PA1
+ D2, // PB2
+ D19, // PB3
+ D7, // PA4
+ D6, // PA5
+};
+
+// EXTI handlers
+void exti_0_handler(void);
+void exti_1_handler(void);
+void exti_2_handler(void);
+void exti_3_handler(void);
+void exti_4_handler(void);
+void exti_5_handler(void);
+voidFuncPtr exti_handlers[N_EXTI] = {
+ exti_0_handler,
+ exti_1_handler,
+ exti_2_handler,
+ exti_3_handler,
+ exti_4_handler,
+ exti_5_handler,
+};
+
+// index i = number of times we've triggered EXTI line n
+static uint32 n_triggered[N_EXTI];
+
+// index i = number of times we've handled EXTI line n
+volatile static uint32 n_handled[N_EXTI];
+
+// -- setup() -----------------------------------------------------------------
+
+void setup(void) {
+ // Set up pin modes and get line levels stable
+ for (int i = 0; i < N_EXTI; i++) {
+ pinMode(src_pins[i], OUTPUT);
+ digitalWrite(src_pins[i], LOW);
+ pinMode(exti_pins[i], INPUT);
+ }
+
+ // Delay to ensure src_pins are all LOW before proceeding
+ delay(1);
+
+ // Attach interrupts
+ for (int i = 0; i < N_EXTI; i++) {
+ attachInterrupt(exti_pins[i], exti_handlers[i], RISING);
+ }
+}
+
+// -- loop() ------------------------------------------------------------------
+
+void loop(void) {
+ // Wait for user to send a byte before starting
+ while (!SerialUSB.available())
+ ;
+ while (SerialUSB.available()) {
+ SerialUSB.read();
+ }
+
+ // Run the test, print the results
+ run_exti_test();
+ print_test_results();
+
+ // Clear out the triggered/handled state
+ for (int i = 0; i < N_EXTI; i++) {
+ n_triggered[i] = 0;
+ n_handled[i] = 0;
+ }
+
+ SerialUSB.println();
+ SerialUSB.println();
+ SerialUSB.println();
+}
+
+// -- Test routines -----------------------------------------------------------
+
+#define N_RUNS 100
+void run_exti_test(void) {
+ for (int run = 0; run < N_RUNS; run++) {
+ // Trigger EXTIs simultaneously
+ GPIOA_BASE->BSRR = GPIOA_SRC_MSK;
+
+ // Reset line levels
+ GPIOA_BASE->BSRR = GPIOA_SRC_MSK << 16;
+
+ // Update number of times triggered
+ for (int i = 0; i < N_EXTI; i++) {
+ if (GPIOA_SRC_MSK & src_gpioa_msks[i]) {
+ n_triggered[i]++;
+ }
+ }
+ }
+}
+
+// string handling boilerplate
+void resetl(void);
+void appendl(const char str[]);
+void appendl(uint32 n);
+void printl(void);
+
+void print_test_results(void) {
+ SerialUSB.println("Results:");
+
+ resetl();
+ appendl("EXTI");
+ appendl("# Triggered");
+ appendl("# Handled");
+ printl();
+ resetl();
+
+ for (uint32 i = 0; i < N_EXTI; i++) {
+ appendl(i);
+ appendl(n_triggered[i]);
+ appendl(n_handled[i]);
+ printl();
+ resetl();
+ }
+}
+
+// -- EXTI handlers -----------------------------------------------------------
+
+void exti_0_handler(void) {
+ n_handled[0]++;
+}
+
+void exti_1_handler(void) {
+ n_handled[1]++;
+}
+
+void exti_2_handler(void) {
+ n_handled[2]++;
+}
+
+void exti_3_handler(void) {
+ n_handled[3]++;
+}
+
+void exti_4_handler(void) {
+ n_handled[4]++;
+}
+
+void exti_5_handler(void) {
+ n_handled[5]++;
+}
+
+// -- String handling ---------------------------------------------------------
+
+#define C_SIZ 20
+#define LIN_SIZ 80
+char l[LIN_SIZ + 1];
+char tmp[C_SIZ + 1];
+
+void resetl(void) {
+ l[0] = '\0';
+}
+
+void appendl(const char str[]) {
+ snprintf(tmp, C_SIZ, "%-*s", C_SIZ, str);
+ strncat(l, tmp, LIN_SIZ - strlen(tmp));
+}
+
+void appendl(uint32 n) {
+ snprintf(tmp, C_SIZ, "%-*u", C_SIZ, n);
+ strncat(l, tmp, LIN_SIZ - strlen(tmp));
+}
+
+void printl(void) {
+ SerialUSB.println(l);
+}
+
+// -- init()/main() -----------------------------------------------------------
+
+__attribute__((constructor)) void premain() { init(); }
+
+int main(void) {
+ setup();
+
+ while (true)
+ loop();
+
+ return 0;
+}