Browse Source

add turn off for gpio pulses

Thomas Buck 8 months ago
parent
commit
32117a1a73
12 changed files with 150 additions and 15 deletions
  1. 1
    0
      CMakeLists.txt
  2. 2
    2
      README.md
  3. 13
    1
      include/encoder.h
  4. 2
    0
      include/led.h
  5. 28
    0
      include/pulse.h
  6. 5
    4
      include/sequence.h
  7. 1
    1
      include/ui.h
  8. 6
    0
      src/encoder.c
  9. 0
    2
      src/led.c
  10. 2
    0
      src/main.c
  11. 78
    0
      src/pulse.c
  12. 12
    5
      src/sequence.c

+ 1
- 0
CMakeLists.txt View File

@@ -35,6 +35,7 @@ target_sources(drumkit PUBLIC
35 35
     src/lcd.c
36 36
     src/led.c
37 37
     src/main.c
38
+    src/pulse.c
38 39
     src/sequence.c
39 40
     src/ui.c
40 41
 

+ 2
- 2
README.md View File

@@ -19,7 +19,7 @@ Then you can build new binaries like this:
19 19
 
20 20
     make -Cbuild -j4
21 21
 
22
-Flash as usual using the mass storage bootloader of RP2040.
22
+Flash as usual using the mass storage bootloader (hold BOOTSEL while pluggin in the Pico).
23 23
 
24 24
 ## Hardware Connections
25 25
 
@@ -49,7 +49,7 @@ Flash as usual using the mass storage bootloader of RP2040.
49 49
 This firmware is licensed as GPLv3.
50 50
 It uses the [Pi Pico SDK](https://github.com/raspberrypi/pico-sdk), licensed as BSD 3-clause, and therefore also [TinyUSB](https://github.com/hathach/tinyusb), licensed under the MIT license.
51 51
 
52
-The code in `encoder.c` is derived from [mathertel/RotaryEncoder](https://github.com/mathertel/RotaryEncoder) and therefore licensed as BSD 3-clause.
52
+The code in `src/encoder.c` is derived from [mathertel/RotaryEncoder](https://github.com/mathertel/RotaryEncoder) and therefore licensed as BSD 3-clause.
53 53
 
54 54
     This program is free software: you can redistribute it and/or modify
55 55
     it under the terms of the GNU General Public License as published by

+ 13
- 1
include/encoder.h View File

@@ -1,7 +1,19 @@
1 1
 /*
2 2
  * encoder.h
3 3
  *
4
- * Based on https://github.com/mathertel/RotaryEncoder/blob/master/src/RotaryEncoder.cpp
4
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
5 17
  */
6 18
 
7 19
 #ifndef __ENCODER_H__

+ 2
- 0
include/led.h View File

@@ -22,6 +22,8 @@
22 22
 #include <stdint.h>
23 23
 #include <stdbool.h>
24 24
 
25
+#define LED_COUNT 4
26
+
25 27
 void led_init(void);
26 28
 void led_set(uint32_t i, bool v);
27 29
 void ch_set(uint32_t i, bool v);

+ 28
- 0
include/pulse.h View File

@@ -0,0 +1,28 @@
1
+/*
2
+ * pulse.h
3
+ *
4
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef __PULSE_H__
20
+#define __PULSE_H__
21
+
22
+#include <stdint.h>
23
+
24
+void pulse_trigger_out(uint32_t i, uint32_t t_ms);
25
+void pulse_trigger_led(uint32_t i, uint32_t t_ms);
26
+void pulse_run(void);
27
+
28
+#endif // __PULSE_H__

+ 5
- 4
include/sequence.h View File

@@ -24,17 +24,18 @@
24 24
 
25 25
 enum channels {
26 26
     CH1 = (1 << 0),
27
-    CH_KICK = CH1,
28
-
29 27
     CH2 = (1 << 1),
30
-    CH_SNARE = CH2,
31
-
32 28
     CH3 = (1 << 2),
29
+
30
+    CH_KICK = CH1,
31
+    CH_SNARE = CH2,
33 32
     CH_HIHAT = CH3,
34 33
 
35 34
     NUM_CHANNELS = 3
36 35
 };
37 36
 
37
+#define CH_GPIO_TIMINGS { 42, 42, 42 } // in milliseconds
38
+
38 39
 void sequence_init(void);
39 40
 void sequence_set_bpm(uint32_t new_bpm);
40 41
 void sequence_set_beats(uint32_t new_beats);

+ 1
- 1
include/ui.h View File

@@ -24,8 +24,8 @@
24 24
 enum ui_modes {
25 25
     UI_BPM = 0,
26 26
     UI_MODE,
27
-    UI_LENGTH,
28 27
     UI_BANK,
28
+    UI_LENGTH,
29 29
 
30 30
     UI_NUM_MODES
31 31
 };

+ 6
- 0
src/encoder.c View File

@@ -2,6 +2,12 @@
2 2
  * encoder.c
3 3
  *
4 4
  * Based on https://github.com/mathertel/RotaryEncoder/blob/master/src/RotaryEncoder.cpp
5
+ *
6
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
7
+ *
8
+ * Copyright (c) by Matthias Hertel, http://www.mathertel.de
9
+ * This work is licensed under a BSD 3-Clause style license
10
+ * https://www.mathertel.de/License.aspx.
5 11
  */
6 12
 
7 13
 #include <stdio.h>

+ 0
- 2
src/led.c View File

@@ -21,8 +21,6 @@
21 21
 #include "sequence.h"
22 22
 #include "led.h"
23 23
 
24
-#define LED_COUNT 4
25
-
26 24
 static const uint led_gpio_num[LED_COUNT] = {
27 25
     12, 13, 14, 15,
28 26
 };

+ 2
- 0
src/main.c View File

@@ -24,6 +24,7 @@
24 24
 #include "encoder.h"
25 25
 #include "lcd.h"
26 26
 #include "led.h"
27
+#include "pulse.h"
27 28
 #include "sequence.h"
28 29
 #include "ui.h"
29 30
 #include "main.h"
@@ -48,6 +49,7 @@ int main(void) {
48 49
         buttons_run();
49 50
         encoder_run();
50 51
         sequence_run();
52
+        pulse_run();
51 53
 
52 54
         int32_t epos = encoder_pos();
53 55
         if (epos != last_epos) {

+ 78
- 0
src/pulse.c View File

@@ -0,0 +1,78 @@
1
+/*
2
+ * pulse.c
3
+ *
4
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include <stdio.h>
20
+#include <inttypes.h>
21
+#include "pico/stdlib.h"
22
+
23
+#include "led.h"
24
+#include "sequence.h"
25
+#include "pulse.h"
26
+
27
+static uint32_t out_time[NUM_CHANNELS] = {0};
28
+static uint32_t led_time[LED_COUNT] = {0};
29
+
30
+static void pulse_trigger(uint32_t i, uint32_t t_ms, bool out) {
31
+    uint32_t off_t = t_ms + to_ms_since_boot(get_absolute_time());
32
+
33
+    if (out) {
34
+        ch_set(i, true);
35
+        if (out_time[i % NUM_CHANNELS] == 0) {
36
+            out_time[i % NUM_CHANNELS] = off_t;
37
+        } else {
38
+            printf("%s: skip retrigger out %"PRIu32"\n", __func__, i);
39
+        }
40
+    } else {
41
+        led_set(i, true);
42
+        if (led_time[i % LED_COUNT] == 0) {
43
+            led_time[i % LED_COUNT] = off_t;
44
+        } else {
45
+            printf("%s: skip retrigger led %"PRIu32"\n", __func__, i);
46
+        }
47
+    }
48
+}
49
+
50
+void pulse_trigger_out(uint32_t i, uint32_t t_ms) {
51
+    pulse_trigger(i, t_ms, true);
52
+}
53
+
54
+void pulse_trigger_led(uint32_t i, uint32_t t_ms) {
55
+    pulse_trigger(i, t_ms, false);
56
+}
57
+
58
+void pulse_run(void) {
59
+    uint32_t now = to_ms_since_boot(get_absolute_time());
60
+
61
+    for (uint i = 0; i < NUM_CHANNELS; i++) {
62
+        if (out_time[i] != 0) {
63
+            if (out_time[i] <= now) {
64
+                ch_set(i, false);
65
+                out_time[i] = 0;
66
+            }
67
+        }
68
+    }
69
+
70
+    for (uint i = 0; i < LED_COUNT; i++) {
71
+        if (led_time[i] != 0) {
72
+            if (led_time[i] <= now) {
73
+                led_set(i, false);
74
+                led_time[i] = 0;
75
+            }
76
+        }
77
+    }
78
+}

+ 12
- 5
src/sequence.c View File

@@ -20,9 +20,11 @@
20 20
 #include "pico/stdlib.h"
21 21
 
22 22
 #include "led.h"
23
+#include "pulse.h"
23 24
 #include "sequence.h"
24 25
 
25 26
 #define MAX_BEATS 32
27
+static const uint32_t channel_times[NUM_CHANNELS] = CH_GPIO_TIMINGS;
26 28
 
27 29
 static uint32_t ms_per_beat = 500;
28 30
 static uint32_t beats = 16;
@@ -68,17 +70,20 @@ static bool sequence_get(uint32_t beat, enum channels ch) {
68 70
 void sequence_handle_button_loopstation(enum buttons btn, bool rec) {
69 71
     switch (btn) {
70 72
         case BTN_A: {
71
-            // TODO trigger gpio impulse for output and led
73
+            pulse_trigger_out(0, channel_times[0]);
74
+            pulse_trigger_led(0, channel_times[0]);
72 75
             break;
73 76
         }
74 77
 
75 78
         case BTN_B: {
76
-            // TODO trigger gpio impulse for output and led
79
+            pulse_trigger_out(1, channel_times[1]);
80
+            pulse_trigger_led(1, channel_times[1]);
77 81
             break;
78 82
         }
79 83
 
80 84
         case BTN_C: {
81
-            // TODO trigger gpio impulse for output and led
85
+            pulse_trigger_out(2, channel_times[2]);
86
+            pulse_trigger_led(2, channel_times[2]);
82 87
             break;
83 88
         }
84 89
 
@@ -151,8 +156,10 @@ void sequence_run(void) {
151 156
         led_set(last_i, false);
152 157
         led_set(i, true);
153 158
 
154
-        if (sequence[i]) {
155
-            // TODO trigger GPIO impulse
159
+        for (uint ch = 0; ch < NUM_CHANNELS; ch++) {
160
+            if (sequence[i] & (1 << ch)) {
161
+                pulse_trigger_out(i, channel_times[ch]);
162
+            }
156 163
         }
157 164
 
158 165
         last_t = now;

Loading…
Cancel
Save