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
     src/lcd.c
35
     src/lcd.c
36
     src/led.c
36
     src/led.c
37
     src/main.c
37
     src/main.c
38
+    src/pulse.c
38
     src/sequence.c
39
     src/sequence.c
39
     src/ui.c
40
     src/ui.c
40
 
41
 

+ 2
- 2
README.md View File

19
 
19
 
20
     make -Cbuild -j4
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
 ## Hardware Connections
24
 ## Hardware Connections
25
 
25
 
49
 This firmware is licensed as GPLv3.
49
 This firmware is licensed as GPLv3.
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.
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
     This program is free software: you can redistribute it and/or modify
54
     This program is free software: you can redistribute it and/or modify
55
     it under the terms of the GNU General Public License as published by
55
     it under the terms of the GNU General Public License as published by

+ 13
- 1
include/encoder.h View File

1
 /*
1
 /*
2
  * encoder.h
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
 #ifndef __ENCODER_H__
19
 #ifndef __ENCODER_H__

+ 2
- 0
include/led.h View File

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

+ 28
- 0
include/pulse.h View File

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

+ 1
- 1
include/ui.h View File

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

+ 6
- 0
src/encoder.c View File

2
  * encoder.c
2
  * encoder.c
3
  *
3
  *
4
  * Based on https://github.com/mathertel/RotaryEncoder/blob/master/src/RotaryEncoder.cpp
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
 #include <stdio.h>
13
 #include <stdio.h>

+ 0
- 2
src/led.c View File

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

+ 2
- 0
src/main.c View File

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

+ 78
- 0
src/pulse.c View File

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
 #include "pico/stdlib.h"
20
 #include "pico/stdlib.h"
21
 
21
 
22
 #include "led.h"
22
 #include "led.h"
23
+#include "pulse.h"
23
 #include "sequence.h"
24
 #include "sequence.h"
24
 
25
 
25
 #define MAX_BEATS 32
26
 #define MAX_BEATS 32
27
+static const uint32_t channel_times[NUM_CHANNELS] = CH_GPIO_TIMINGS;
26
 
28
 
27
 static uint32_t ms_per_beat = 500;
29
 static uint32_t ms_per_beat = 500;
28
 static uint32_t beats = 16;
30
 static uint32_t beats = 16;
68
 void sequence_handle_button_loopstation(enum buttons btn, bool rec) {
70
 void sequence_handle_button_loopstation(enum buttons btn, bool rec) {
69
     switch (btn) {
71
     switch (btn) {
70
         case BTN_A: {
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
             break;
75
             break;
73
         }
76
         }
74
 
77
 
75
         case BTN_B: {
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
             break;
81
             break;
78
         }
82
         }
79
 
83
 
80
         case BTN_C: {
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
             break;
87
             break;
83
         }
88
         }
84
 
89
 
151
         led_set(last_i, false);
156
         led_set(last_i, false);
152
         led_set(i, true);
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
         last_t = now;
165
         last_t = now;

Loading…
Cancel
Save