]> git.scottworley.com Git - tattlekey/commitdiff
client: Respond to button press
authorScott Worley <scottworley@scottworley.com>
Sun, 8 Oct 2023 06:29:49 +0000 (23:29 -0700)
committerScott Worley <scottworley@scottworley.com>
Wed, 11 Oct 2023 01:48:13 +0000 (18:48 -0700)
client/CMakeLists.txt
client/button.c [new file with mode: 0644]
client/button.h [new file with mode: 0644]
client/config.c
client/config.h
client/tattlekey.c

index ae972002a7de59e0c826e2fae33ebe1e510c2068..7714c1e43dedaf618e6066c4d15cecec4b60ad33 100644 (file)
@@ -9,6 +9,7 @@ pico_sdk_init()
 
 add_executable(tattlekey
   blink.c
+  button.c
   config.c
   net.c
   tattlekey.c
diff --git a/client/button.c b/client/button.c
new file mode 100644 (file)
index 0000000..4df8d66
--- /dev/null
@@ -0,0 +1,30 @@
+#include "button.h"
+#include "config.h"
+
+#include "hardware/gpio.h"
+
+#include "pico/stdlib.h"
+
+static callback_t button_callback = NULL;
+
+static void respond_to_gpio_interrupt(uint gpio, uint32_t event_mask) {
+  if (gpio == button_pin && event_mask & GPIO_IRQ_EDGE_FALL &&
+      button_callback) {
+    button_callback();
+  }
+}
+
+void begin_listening_for_button_press(callback_t callback) {
+  button_callback = callback;
+
+  gpio_set_pulls(button_pin, 1, 0);
+
+  /* Allow some time for the pull-up to take effect.
+   * I'm not sure if this is necessary.
+   * https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf says
+   * the internal GPIO pull-up resistors are 50k. */
+  sleep_ms(100);
+
+  gpio_set_irq_enabled_with_callback(button_pin, GPIO_IRQ_EDGE_FALL, 1,
+                                     respond_to_gpio_interrupt);
+}
diff --git a/client/button.h b/client/button.h
new file mode 100644 (file)
index 0000000..9f82e15
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef BUTTON_H
+#define BUTTON_H
+
+typedef void (*callback_t)();
+
+void begin_listening_for_button_press(callback_t callback);
+
+#endif
index d2be496c95dd8f631ceb4a3969c197156f8ec846..a8e58440dff1b24d52829f6f8989d9afc0b332ac 100644 (file)
@@ -10,3 +10,10 @@ u16_t tattle_port = 29803; // 'tk'
 
 /* For distinguishing reports from multiple tattlekey devices. */
 u16_t this_tattler_identity = 1;
+
+/* Which GPIO pin is the button connected to?
+ * The button should span this pin and ground, connecting this pin to ground
+ * when pressed.
+ * https://projects.raspberrypi.org/en/projects/introduction-to-the-pico/10
+ * recommends pins 18, 22, or 28. */
+uint button_pin = 18;
index 97e2f8cfb3be723b1a86808dc26f553f9d83e9d7..95c5651b27ec5881b3d5ebaedd2e0181359f6fb6 100644 (file)
@@ -14,4 +14,11 @@ extern u16_t tattle_port;
 /* For distinguishing reports from multiple tattlekey devices. */
 extern u16_t this_tattler_identity;
 
+/* Which GPIO pin is the button connected to?
+ * The button should span this pin and ground, connecting this pin to ground
+ * when pressed.
+ * https://projects.raspberrypi.org/en/projects/introduction-to-the-pico/10
+ * recommends pins 18, 22, or 28. */
+extern uint button_pin;
+
 #endif
index ec7710789fbf6efcc65e8cc7b085fe3f597a8f8a..30f92a4d4e3cb804a86af133a4c058a3908acfd7 100644 (file)
@@ -2,9 +2,34 @@
 #include "pico/stdlib.h"
 
 #include "blink.h"
+#include "button.h"
 #include "config.h"
 #include "net.h"
 
+static u16_t seq = 0;
+
+static void button_pressed() {
+  /* TODO: This is interrupt context.  We need to get out of interrupt context
+   * quickly; we should not be doing significant work here, & definitely
+   * shouldn't be sleeping here.  We signal errors with blinking the LED, which
+   * involves sleeping, so this all has to move. */
+  send_report(seq++, 0);
+  signal(4, 200);
+}
+
+static void wait_forever() {
+  /* pico-examples/gpio/hello_gpio_irq/hello_gpio_irq.c implements wait-forever
+   * as "while (1);", but
+   * https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#gaf469c6d691230e9d1008
+   * says sleeping uses less power, so we sleep.  */
+  while (1) {
+    /* https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#rpip7ce2cdc1662dce59296b
+     * says the maximum sleep is 2^32 - 1 microseconds (~71.58 minutes), so we
+     * sleep in chunks. */
+    sleep_ms(1 << 31); /* 35.79 minutes */
+  }
+}
+
 int main() {
   stdio_init_all();
   if (cyw43_arch_init_with_country(CYW43_COUNTRY_USA))
@@ -16,9 +41,7 @@ int main() {
                                          CYW43_AUTH_WPA2_AES_PSK, 10000))
     signal_error_by_blinking();
   signal(3, 200);
+  begin_listening_for_button_press(button_pressed);
 
-  for (int i = 0;; i++) {
-    send_report(i, 0);
-    signal(4, 200);
-  }
+  wait_forever();
 }