Thomas Buck 8 месяцев назад
Родитель
Сommit
5ccc841b80
8 измененных файлов: 147 добавлений и 39 удалений
  1. 19
    0
      README.md
  2. 1
    0
      include/led.h
  3. 2
    0
      include/sequence.h
  4. 3
    0
      include/ui.h
  5. 17
    3
      src/led.c
  6. 11
    0
      src/main.c
  7. 55
    36
      src/sequence.c
  8. 39
    0
      src/ui.c

+ 19
- 0
README.md Просмотреть файл

@@ -43,3 +43,22 @@ Flash as usual using the mass storage bootloader of RP2040.
43 43
     Pin 17   GP13   LED 2
44 44
     Pin 19   GP14   LED 3
45 45
     Pin 20   GP15   LED 4
46
+
47
+## License
48
+
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.
51
+
52
+The code in `encoder.c` is derived from [mathertel/RotaryEncoder](https://github.com/mathertel/RotaryEncoder) and therefore licensed as BSD 3-clause.
53
+
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
56
+    the Free Software Foundation, either version 3 of the License, or
57
+    (at your option) any later version.
58
+
59
+    This program is distributed in the hope that it will be useful,
60
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
61
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
62
+    GNU General Public License for more details.
63
+
64
+    See <http://www.gnu.org/licenses/>.

+ 1
- 0
include/led.h Просмотреть файл

@@ -24,5 +24,6 @@
24 24
 
25 25
 void led_init(void);
26 26
 void led_set(uint32_t i, bool v);
27
+void ch_set(uint32_t i, bool v);
27 28
 
28 29
 #endif // __LED_H__

+ 2
- 0
include/sequence.h Просмотреть файл

@@ -31,6 +31,8 @@ enum channels {
31 31
 
32 32
     CH3 = (1 << 2),
33 33
     CH_HIHAT = CH3,
34
+
35
+    NUM_CHANNELS = 3
34 36
 };
35 37
 
36 38
 void sequence_init(void);

+ 3
- 0
include/ui.h Просмотреть файл

@@ -19,6 +19,8 @@
19 19
 #ifndef __UI_H__
20 20
 #define __UI_H__
21 21
 
22
+#include <stdint.h>
23
+
22 24
 enum ui_modes {
23 25
     UI_BPM = 0,
24 26
     UI_MODE,
@@ -36,5 +38,6 @@ enum machine_modes {
36 38
 };
37 39
 
38 40
 void ui_init(void);
41
+void ui_encoder(int32_t val);
39 42
 
40 43
 #endif // __UI_H__

+ 17
- 3
src/led.c Просмотреть файл

@@ -18,18 +18,27 @@
18 18
 
19 19
 #include "pico/stdlib.h"
20 20
 
21
+#include "sequence.h"
21 22
 #include "led.h"
22 23
 
23 24
 #define LED_COUNT 4
24 25
 
25
-static const uint gpio_num[LED_COUNT] = {
26
+static const uint led_gpio_num[LED_COUNT] = {
26 27
     12, 13, 14, 15,
27 28
 };
28 29
 
30
+static const uint ch_gpio_num[NUM_CHANNELS] = {
31
+    2, 3, 4,
32
+};
33
+
29 34
 void led_init(void) {
30 35
     for (uint i = 0; i < LED_COUNT; i++) {
31
-        gpio_init(gpio_num[i]);
32
-        gpio_set_dir(gpio_num[i], GPIO_IN);
36
+        gpio_init(led_gpio_num[i]);
37
+        gpio_set_dir(led_gpio_num[i], GPIO_OUT);
38
+    }
39
+    for (uint i = 0; i < NUM_CHANNELS; i++) {
40
+        gpio_init(ch_gpio_num[i]);
41
+        gpio_set_dir(ch_gpio_num[i], GPIO_OUT);
33 42
     }
34 43
 }
35 44
 
@@ -37,3 +46,8 @@ void led_set(uint32_t i, bool v) {
37 46
     i %= LED_COUNT;
38 47
     gpio_put(i, v);
39 48
 }
49
+
50
+void ch_set(uint32_t i, bool v) {
51
+    i %= NUM_CHANNELS;
52
+    gpio_put(i, v);
53
+}

+ 11
- 0
src/main.c Просмотреть файл

@@ -23,6 +23,7 @@
23 23
 #include "buttons.h"
24 24
 #include "encoder.h"
25 25
 #include "lcd.h"
26
+#include "led.h"
26 27
 #include "sequence.h"
27 28
 #include "ui.h"
28 29
 #include "main.h"
@@ -33,16 +34,26 @@ int main(void) {
33 34
     watchdog_enable(WATCHDOG_PERIOD_MS, 1);
34 35
     stdio_init_all();
35 36
     buttons_init();
37
+    encoder_init();
36 38
     lcd_init();
39
+    led_init();
37 40
     sequence_init();
38 41
     ui_init();
39 42
     printf("init done\n");
40 43
 
44
+    int32_t last_epos = 0;
45
+
41 46
     while (1) {
42 47
         watchdog_update();
43 48
         buttons_run();
44 49
         encoder_run();
45 50
         sequence_run();
51
+
52
+        int32_t epos = encoder_pos();
53
+        if (epos != last_epos) {
54
+            ui_encoder(epos - last_epos);
55
+            last_epos = epos;
56
+        }
46 57
     }
47 58
 
48 59
     return 0;

+ 55
- 36
src/sequence.c Просмотреть файл

@@ -34,6 +34,10 @@ static enum channels sequence[MAX_BEATS] = {0};
34 34
 void sequence_init(void) {
35 35
     last_t = to_ms_since_boot(get_absolute_time());
36 36
     last_i = 0;
37
+
38
+    for (uint i = 0; i < MAX_BEATS; i++) {
39
+        sequence[i] = 0;
40
+    }
37 41
 }
38 42
 
39 43
 void sequence_set_bpm(uint32_t new_bpm) {
@@ -63,40 +67,48 @@ static bool sequence_get(uint32_t beat, enum channels ch) {
63 67
 
64 68
 void sequence_handle_button_loopstation(enum buttons btn, bool rec) {
65 69
     switch (btn) {
66
-    case BTN_A:
67
-        // TODO trigger gpio impulse
68
-        break;
70
+        case BTN_A: {
71
+            // TODO trigger gpio impulse for output and led
72
+            break;
73
+        }
69 74
 
70
-    case BTN_B:
71
-        // TODO trigger gpio impulse
72
-        break;
75
+        case BTN_B: {
76
+            // TODO trigger gpio impulse for output and led
77
+            break;
78
+        }
73 79
 
74
-    case BTN_C:
75
-        // TODO trigger gpio impulse
76
-        break;
80
+        case BTN_C: {
81
+            // TODO trigger gpio impulse for output and led
82
+            break;
83
+        }
77 84
 
78
-    default:
79
-        break;
85
+        default: {
86
+            break;
87
+        }
80 88
     }
81 89
 
82 90
     if (rec) {
83 91
         uint32_t beat = 42; // TODO!!
84 92
 
85 93
         switch (btn) {
86
-        case BTN_A:
87
-            sequence_set(beat, CH_KICK, true);
88
-            break;
89
-
90
-        case BTN_B:
91
-            sequence_set(beat, CH_SNARE, true);
92
-            break;
93
-
94
-        case BTN_C:
95
-            sequence_set(beat, CH_HIHAT, true);
96
-            break;
97
-
98
-        default:
99
-            break;
94
+            case BTN_A: {
95
+                sequence_set(beat, CH_KICK, true);
96
+                break;
97
+            }
98
+
99
+            case BTN_B: {
100
+                sequence_set(beat, CH_SNARE, true);
101
+                break;
102
+            }
103
+
104
+            case BTN_C: {
105
+                sequence_set(beat, CH_HIHAT, true);
106
+                break;
107
+            }
108
+
109
+            default: {
110
+                break;
111
+            }
100 112
         }
101 113
     }
102 114
 }
@@ -105,20 +117,27 @@ void sequence_handle_button_drummachine(enum buttons btn) {
105 117
     uint32_t beat = 42; // TODO!!
106 118
 
107 119
     switch (btn) {
108
-    case BTN_A:
109
-        sequence_set(beat, CH_KICK, !sequence_get(beat, CH_KICK));
110
-        break;
120
+        case BTN_A: {
121
+            bool val = !sequence_get(beat, CH_KICK);
122
+            sequence_set(beat, CH_KICK, val);
123
+            break;
124
+        }
111 125
 
112
-    case BTN_B:
113
-        sequence_set(beat, CH_SNARE, !sequence_get(beat, CH_SNARE));
114
-        break;
126
+        case BTN_B: {
127
+            bool val = !sequence_get(beat, CH_SNARE);
128
+            sequence_set(beat, CH_SNARE, val);
129
+            break;
130
+        }
115 131
 
116
-    case BTN_C:
117
-        sequence_set(beat, CH_HIHAT, !sequence_get(beat, CH_HIHAT));
118
-        break;
132
+        case BTN_C: {
133
+            bool val = !sequence_get(beat, CH_HIHAT);
134
+            sequence_set(beat, CH_HIHAT, val);
135
+            break;
136
+        }
119 137
 
120
-    default:
121
-        break;
138
+        default: {
139
+            break;
140
+        }
122 141
     }
123 142
 }
124 143
 

+ 39
- 0
src/ui.c Просмотреть файл

@@ -30,18 +30,22 @@ static enum machine_modes machine_mode = 0;
30 30
 static void ui_redraw(void) {
31 31
     switch (ui_mode) {
32 32
         case UI_BPM: {
33
+            // TODO
33 34
             break;
34 35
         }
35 36
 
36 37
         case UI_MODE: {
38
+            // TODO
37 39
             break;
38 40
         }
39 41
 
40 42
         case UI_LENGTH: {
43
+            // TODO
41 44
             break;
42 45
         }
43 46
 
44 47
         case UI_BANK: {
48
+            // TODO
45 49
             break;
46 50
         }
47 51
 
@@ -128,6 +132,41 @@ static void ui_buttons(enum buttons btn, bool val) {
128 132
     }
129 133
 }
130 134
 
135
+void ui_encoder(int32_t val) {
136
+    if (val == 0) {
137
+        return;
138
+    }
139
+
140
+    switch (ui_mode) {
141
+        case UI_BPM: {
142
+            // TODO
143
+            break;
144
+        }
145
+
146
+        case UI_MODE: {
147
+            // TODO
148
+            break;
149
+        }
150
+
151
+        case UI_LENGTH: {
152
+            // TODO
153
+            break;
154
+        }
155
+
156
+        case UI_BANK: {
157
+            // TODO
158
+            break;
159
+        }
160
+
161
+        default: {
162
+            printf("%s: invalid mode: %d\n", __func__, ui_mode);
163
+            ui_mode = 0;
164
+            ui_encoder(val);
165
+            break;
166
+        }
167
+    }
168
+}
169
+
131 170
 void ui_init(void) {
132 171
     buttons_callback(ui_buttons);
133 172
     ui_redraw();

Загрузка…
Отмена
Сохранить