From 6dd4432125faf0120581fc7cc31d582b9f520950 Mon Sep 17 00:00:00 2001
From: William Grant <williamgrantuk@gmail.com>
Date: Sun, 14 May 2023 20:32:00 +0100
Subject: [PATCH] binary_buzz + random_leds

---
 CMakeLists.txt             |  3 +-
 buzz_cycle/buzz_cycle.c    | 65 +++++++++++++++++++++++++++++++++++++-
 random_leds/CMakeLists.txt |  8 +++++
 random_leds/random_leds.c  | 54 +++++++++++++++++++++++++++++++
 4 files changed, 128 insertions(+), 2 deletions(-)
 create mode 100644 random_leds/CMakeLists.txt
 create mode 100644 random_leds/random_leds.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f9cfa1b..188fbd5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,5 +12,6 @@ add_subdirectory(rios)
 add_subdirectory(morse)
 add_subdirectory(binary_buzz)
 add_subdirectory(neopixel)
-add_subdirectory(display_driver)
+add_subdirectory(buzz_cycle)
+add_subdirectory(random_leds)
 
diff --git a/buzz_cycle/buzz_cycle.c b/buzz_cycle/buzz_cycle.c
index 67f0e8f..d58b32e 100644
--- a/buzz_cycle/buzz_cycle.c
+++ b/buzz_cycle/buzz_cycle.c
@@ -1,2 +1,65 @@
-#include "buzzer.h";
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "pico/stdlib.h"
+#include "hardware/sync.h"
+#include "hardware/irq.h"
+#include "buzzer.h"
+
+static int64_t period = 1000000;
+static bool alarm_status = false;
+
+// timer callback that controls the buzzer
+static int64_t buzz_isr(alarm_id_t id, void* data) {
+    if (alarm_status) {
+        buzzer_disable();
+        alarm_status = false;
+        return period;
+    } else {
+        buzzer_enable();
+        alarm_status = true;
+        return period;
+    }
+}
+
+// initialise stdio and the buzzer
+static inline void init() {
+    stdio_init_all();
+    buzzer_init();
+    sleep_ms(1000);
+}
+
+static inline void start_timer() {
+    alarm_pool_t* alarm_pool = alarm_pool_create(2, 16);
+    irq_set_priority(2, 0xc0);
+    alarm_pool_add_alarm_in_us(alarm_pool, period, buzz_isr, NULL, false);
+}
+
+// allow the user to enter a period in microseconds
+int64_t get_period() {
+    int64_t result = 0;
+
+    printf(">> ");
+    while (true) {
+        char c = getchar();
+        if (c == EOF || c == '\r' || c == '\n') {
+            putchar('\n');
+            break;
+        } else if (c >= 48 && c <= 57) {
+            putchar(c);
+            result = (result * 10) + c - 48;
+        }
+    }
+
+    return result;
+}
+
+int main(void) {
+    init();
+    start_timer();
+
+    while (true) {
+        period = get_period();
+    }
+}
 
diff --git a/random_leds/CMakeLists.txt b/random_leds/CMakeLists.txt
new file mode 100644
index 0000000..92dc689
--- /dev/null
+++ b/random_leds/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_executable(random_leds random_leds.c)
+target_link_libraries(random_leds pico_stdlib)
+
+pico_enable_stdio_usb(random_leds 1)
+pico_enable_stdio_uart(random_leds 0)
+
+pico_add_extra_outputs(random_leds)
+
diff --git a/random_leds/random_leds.c b/random_leds/random_leds.c
new file mode 100644
index 0000000..2b9d4e7
--- /dev/null
+++ b/random_leds/random_leds.c
@@ -0,0 +1,54 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "pico/stdlib.h"
+
+static const unsigned int pins[] = {0u, 1u, 2u, 3u, PICO_DEFAULT_LED_PIN};
+static const size_t pin_count = 5u;
+
+static const int64_t min_delay = 0u;
+static const int64_t max_delay = 10000000u;
+
+static inline int64_t get_delay() {
+    return rand() % (max_delay + 1 - min_delay) + min_delay;
+}
+
+static int64_t led_isr(alarm_id_t id, void* data) {
+    unsigned int pin = *(unsigned int*)data;
+    printf("toggling pin %zu, ", pin);
+
+    // toggle the gpio pin
+    gpio_put(pin, !gpio_get_out_level(pin));
+    printf("new value is %d\n", gpio_get_out_level(pin));
+
+    // wait a random amount of time before continuing
+    return get_delay();
+}
+
+int main(void) {
+    stdio_init_all();  // initialise I/O
+    sleep_ms(1000);
+
+    time_t t = time(0);
+    printf("time: %x", t);
+    srand(t);  // seed the random number generator
+
+    //set up the timer
+    alarm_pool_t* alarm_pool = alarm_pool_create(2, 16);
+    irq_set_priority(2, 0xc0);
+
+    printf("setup complete\n");
+
+    // start the leds
+    for (size_t i = 0u; i < pin_count; ++i) {
+        gpio_init(pins[i]);
+        gpio_set_dir(pins[i], GPIO_OUT);
+        alarm_pool_add_alarm_in_us(alarm_pool, get_delay(), led_isr, pins + i, true);
+    }
+    printf("timers started\n");
+
+    while (true) {}
+}
+
-- 
GitLab