Browse Source

implement button matrix reading

Thomas Buck 1 month ago
parent
commit
7269be8b92
10 changed files with 194 additions and 47 deletions
  1. 1
    0
      docs/src/pcb1.md
  2. 1
    0
      docs/src/pcb2.md
  3. 2
    0
      include/buttons.h
  4. 3
    0
      include/lcd.h
  5. 2
    0
      include/main.h
  6. 52
    12
      src/buttons.c
  7. 44
    0
      src/lcd.c
  8. 36
    10
      src/main.c
  9. 15
    6
      src/sequence.c
  10. 38
    19
      src/ui.c

+ 1
- 0
docs/src/pcb1.md View File

20
 | U3, U5, U7 | Step-Up Converter Module | [Amazon.de](https://www.amazon.de/Converter-Spannungswandler-LAOMAO-Netzteil-Kompatibel/dp/B0B932BR7V) |
20
 | U3, U5, U7 | Step-Up Converter Module | [Amazon.de](https://www.amazon.de/Converter-Spannungswandler-LAOMAO-Netzteil-Kompatibel/dp/B0B932BR7V) |
21
 | J2 | SSD1306 128x64 0.96" Display | [Amazon.de](https://www.amazon.de/AZDelivery-Display-Arduino-Raspberry-gratis/dp/B01L9GC470) |
21
 | J2 | SSD1306 128x64 0.96" Display | [Amazon.de](https://www.amazon.de/AZDelivery-Display-Arduino-Raspberry-gratis/dp/B01L9GC470) |
22
 | S1 | ALPS EC12E24244 | [Reichelt.de](https://www.reichelt.de/drehimpulsegeber-24-impulse-24-rastungen-vertikal-stec12e08-p73923.html?&nbc=1) |
22
 | S1 | ALPS EC12E24244 | [Reichelt.de](https://www.reichelt.de/drehimpulsegeber-24-impulse-24-rastungen-vertikal-stec12e08-p73923.html?&nbc=1) |
23
+| - | Cap for encoder knob | [Reichelt.de](https://www.reichelt.de/potentiometerknopf-fuer-achse-6-4-5-mm-schwarz-knopf-10-150e-p73960.html) |
23
 | D1 - D4 | LED 5mm | [Reichelt.de](https://www.reichelt.de/led-5mm-bedrahtet-rot-450-mcd-90--5603r1c-khb-a-p361958.html?&nbc=1) |
24
 | D1 - D4 | LED 5mm | [Reichelt.de](https://www.reichelt.de/led-5mm-bedrahtet-rot-450-mcd-90--5603r1c-khb-a-p361958.html?&nbc=1) |
24
 | D5 - D8 | 1N5819 Schottky Diode | [Reichelt.de](https://www.reichelt.de/schottkydiode-40-v-1-a-do-41-1n-5819-p41850.html?&nbc=1) |
25
 | D5 - D8 | 1N5819 Schottky Diode | [Reichelt.de](https://www.reichelt.de/schottkydiode-40-v-1-a-do-41-1n-5819-p41850.html?&nbc=1) |
25
 | R1 - R4 | Resistor 1k Ohm | [Reichelt.de](https://www.reichelt.de/widerstand-metallschicht-1-00-kohm-0207-0-6-w-1--metall-1-00k-p11403.html?&nbc=1) |
26
 | R1 - R4 | Resistor 1k Ohm | [Reichelt.de](https://www.reichelt.de/widerstand-metallschicht-1-00-kohm-0207-0-6-w-1--metall-1-00k-p11403.html?&nbc=1) |

+ 1
- 0
docs/src/pcb2.md View File

22
 | BT1 | Keystone 1042 | [Reichelt.de](https://www.reichelt.de/batteriehalter-fuer-1-18650-keystone-1042-p213369.html?&nbc=1) |
22
 | BT1 | Keystone 1042 | [Reichelt.de](https://www.reichelt.de/batteriehalter-fuer-1-18650-keystone-1042-p213369.html?&nbc=1) |
23
 | S1 | APEM 5236AB | [Reichelt.de](https://www.reichelt.de/kippschalter-1a-250vac-1x-ein-ein-printanschluss-as-500apc-p4396.html?&nbc=1) |
23
 | S1 | APEM 5236AB | [Reichelt.de](https://www.reichelt.de/kippschalter-1a-250vac-1x-ein-ein-printanschluss-as-500apc-p4396.html?&nbc=1) |
24
 | SW1 | ALPS EC12E24244 | [Reichelt.de](https://www.reichelt.de/drehimpulsegeber-24-impulse-24-rastungen-vertikal-stec12e08-p73923.html?&nbc=1) |
24
 | SW1 | ALPS EC12E24244 | [Reichelt.de](https://www.reichelt.de/drehimpulsegeber-24-impulse-24-rastungen-vertikal-stec12e08-p73923.html?&nbc=1) |
25
+| - | Cap for encoder knob | [Reichelt.de](https://www.reichelt.de/potentiometerknopf-fuer-achse-6-4-5-mm-schwarz-knopf-10-150e-p73960.html) |
25
 | SW2 - SW10 | DIP 6x6mm push button | [Reichelt.de](https://www.reichelt.de/kurzhubtaster-printmontage-1-schliesser-6-x-6-x-5-mm-dip-dts-62k-v-p360043.html?&nbc=1) |
26
 | SW2 - SW10 | DIP 6x6mm push button | [Reichelt.de](https://www.reichelt.de/kurzhubtaster-printmontage-1-schliesser-6-x-6-x-5-mm-dip-dts-62k-v-p360043.html?&nbc=1) |
26
 | D1 - D4 | 1N5819 Schottky Diode | [Reichelt.de](https://www.reichelt.de/schottkydiode-40-v-1-a-do-41-1n-5819-p41850.html?&nbc=1) |
27
 | D1 - D4 | 1N5819 Schottky Diode | [Reichelt.de](https://www.reichelt.de/schottkydiode-40-v-1-a-do-41-1n-5819-p41850.html?&nbc=1) |
27
 | D5 - D12 | LED 5mm | [Reichelt.de](https://www.reichelt.de/led-5mm-bedrahtet-rot-450-mcd-90--5603r1c-khb-a-p361958.html?&nbc=1) |
28
 | D5 - D12 | LED 5mm | [Reichelt.de](https://www.reichelt.de/led-5mm-bedrahtet-rot-450-mcd-90--5603r1c-khb-a-p361958.html?&nbc=1) |

+ 2
- 0
include/buttons.h View File

21
 
21
 
22
 #include <stdbool.h>
22
 #include <stdbool.h>
23
 
23
 
24
+#define DEBOUNCE_DELAY_MS 50
25
+
24
 enum buttons {
26
 enum buttons {
25
     BTN_A = 0,
27
     BTN_A = 0,
26
     BTN_B,
28
     BTN_B,

+ 3
- 0
include/lcd.h View File

24
 
24
 
25
 void lcd_init(void);
25
 void lcd_init(void);
26
 void lcd_draw(const char *mode, const char *val, const char *bat);
26
 void lcd_draw(const char *mode, const char *val, const char *bat);
27
+void lcd_draw_bye(void);
28
+
29
+void lcd_debug_buttons(void);
27
 
30
 
28
 #endif // __LCD_H__
31
 #endif // __LCD_H__

+ 2
- 0
include/main.h View File

27
 
27
 
28
 extern enum hw_versions hw_type;
28
 extern enum hw_versions hw_type;
29
 
29
 
30
+void handle_serial_input(void);
31
+
30
 #endif // __MAIN_H__
32
 #endif // __MAIN_H__

+ 52
- 12
src/buttons.c View File

22
 #include "main.h"
22
 #include "main.h"
23
 #include "buttons.h"
23
 #include "buttons.h"
24
 
24
 
25
-#define DEBOUNCE_DELAY_MS 50
26
-
27
 static const uint gpio_num_proto[NUM_BTNS] = {
25
 static const uint gpio_num_proto[NUM_BTNS] = {
28
     8, // BTN_A
26
     8, // BTN_A
29
     9, // BTN_B
27
     9, // BTN_B
40
     16, // BTN_CLICK
38
     16, // BTN_CLICK
41
 };
39
 };
42
 
40
 
41
+#define NUM_ROWS 3
42
+#define NUM_COLS 3
43
+
43
 static const uint gpio_num_v2[NUM_BTNS] = {
44
 static const uint gpio_num_v2[NUM_BTNS] = {
44
-    1, // BTN_A / COL 0
45
-    4, // BTN_B / COL 1
46
-    5, // BTN_C / COL 2
47
-    0, // BTN_D / ROW 0
48
-    2, // BTN_E / ROW 1
49
-    3, // BTN_F / ROW 2
45
+    // handled as matrix
46
+    0xFF, // BTN_A
47
+    0xFF, // BTN_B
48
+    0xFF, // BTN_C
49
+    0xFF, // BTN_D
50
+    0xFF, // BTN_E
51
+    0xFF, // BTN_F
50
     0xFF, // BTN_G
52
     0xFF, // BTN_G
51
     0xFF, // BTN_H
53
     0xFF, // BTN_H
52
     0xFF, // BTN_REC
54
     0xFF, // BTN_REC
55
+
53
     20, // BTN_CLICK
56
     20, // BTN_CLICK
54
 };
57
 };
55
 
58
 
59
+static const uint gpio_rows[NUM_ROWS] = {
60
+    0, 2, 3
61
+};
62
+
63
+static const uint gpio_cols[NUM_COLS] = {
64
+    1, 4, 5
65
+};
66
+
56
 struct button_state {
67
 struct button_state {
57
     uint32_t last_time;
68
     uint32_t last_time;
58
     bool current_state, last_state;
69
     bool current_state, last_state;
60
 
71
 
61
 static struct button_state buttons[NUM_BTNS];
72
 static struct button_state buttons[NUM_BTNS];
62
 static void (*callback)(enum buttons, bool) = NULL;
73
 static void (*callback)(enum buttons, bool) = NULL;
74
+static int last_col = 0;
63
 
75
 
64
 void buttons_init(void) {
76
 void buttons_init(void) {
65
     for (uint i = 0; i < NUM_BTNS; i++) {
77
     for (uint i = 0; i < NUM_BTNS; i++) {
82
         buttons[i].current_state = false;
94
         buttons[i].current_state = false;
83
         buttons[i].last_state = false;
95
         buttons[i].last_state = false;
84
     }
96
     }
97
+
98
+    if (hw_type != HW_V2) {
99
+        return;
100
+    }
101
+
102
+    for (uint i = 0; i < NUM_ROWS; i++) {
103
+        uint n = gpio_rows[i];
104
+        gpio_init(n);
105
+        gpio_set_dir(n, GPIO_IN);
106
+        gpio_pull_up(n);
107
+    }
108
+
109
+    for (uint i = 0; i < NUM_COLS; i++) {
110
+        uint n = gpio_cols[i];
111
+        gpio_init(n);
112
+        gpio_set_dir(n, GPIO_IN);
113
+        gpio_disable_pulls(n);
114
+    }
85
 }
115
 }
86
 
116
 
87
 void buttons_callback(void (*fp)(enum buttons, bool)) {
117
 void buttons_callback(void (*fp)(enum buttons, bool)) {
109
     buttons[i].last_state = state;
139
     buttons[i].last_state = state;
110
 }
140
 }
111
 
141
 
112
-static void buttons_run_proto(void) {
142
+static void button_run_proto(void) {
113
     for (uint i = 0; i < NUM_BTNS; i++) {
143
     for (uint i = 0; i < NUM_BTNS; i++) {
114
         if (gpio_num_proto[i] >= 0xFF) {
144
         if (gpio_num_proto[i] >= 0xFF) {
115
             continue;
145
             continue;
120
     }
150
     }
121
 }
151
 }
122
 
152
 
153
+static void button_run_matrix(void) {
154
+    gpio_set_dir(gpio_cols[last_col], GPIO_IN);
155
+    last_col = (last_col + 1) % NUM_COLS;
156
+    gpio_set_dir(gpio_cols[last_col], GPIO_OUT);
157
+    gpio_put(gpio_cols[last_col], false);
158
+    sleep_us(2);
159
+    for (uint i = 0; i < NUM_ROWS; i++) {
160
+        button_run_single(!gpio_get(gpio_rows[i]), last_col * NUM_ROWS + i);
161
+    }
162
+}
163
+
123
 void buttons_run(void) {
164
 void buttons_run(void) {
124
     if (hw_type == HW_PROTOTYPE) {
165
     if (hw_type == HW_PROTOTYPE) {
125
-        buttons_run_proto();
166
+        button_run_proto();
126
     } else if (hw_type == HW_V2) {
167
     } else if (hw_type == HW_V2) {
127
-        // TODO read matrix
128
-
168
+        button_run_matrix();
129
         button_run_single(!gpio_get(gpio_num_v2[BTN_CLICK]), BTN_CLICK);
169
         button_run_single(!gpio_get(gpio_num_v2[BTN_CLICK]), BTN_CLICK);
130
     }
170
     }
131
 }
171
 }

+ 44
- 0
src/lcd.c View File

23
 #include "hardware/i2c.h"
23
 #include "hardware/i2c.h"
24
 
24
 
25
 #include "ssd1306.h"
25
 #include "ssd1306.h"
26
+
27
+#include "buttons.h"
26
 #include "logo.h"
28
 #include "logo.h"
27
 #include "main.h"
29
 #include "main.h"
28
 #include "lcd.h"
30
 #include "lcd.h"
36
 #define LCD_ADDR 0x3C
38
 #define LCD_ADDR 0x3C
37
 
39
 
38
 static ssd1306_t disp;
40
 static ssd1306_t disp;
41
+static bool buttons[NUM_BTNS] = {0};
42
+static bool changed = true;
43
+
44
+static void lcd_debug_buttons_callback(enum buttons btn, bool v) {
45
+    buttons[btn] = v;
46
+    changed = true;
47
+}
48
+
49
+void lcd_debug_buttons(void) {
50
+    buttons_callback(lcd_debug_buttons_callback);
51
+    while (1) {
52
+        buttons_run();
53
+        handle_serial_input();
54
+        if (changed) {
55
+            changed = false;
56
+            ssd1306_clear(&disp);
57
+            ssd1306_draw_string(&disp, 0, 0, 3, "Buttons");
58
+            for (uint i = 0; i < NUM_BTNS; i++) {
59
+                ssd1306_draw_char(&disp,
60
+                                    i * 12, LCD_HEIGHT - 20 - 16 - 1,
61
+                                    2, '0' + i);
62
+                if (buttons[i]) {
63
+                    ssd1306_draw_square(&disp,
64
+                                        i * 12, LCD_HEIGHT - 20 - 1,
65
+                                        10, 20);
66
+                } else {
67
+                    ssd1306_draw_empty_square(&disp,
68
+                                                i * 12, LCD_HEIGHT - 20 - 1,
69
+                                                10, 20);
70
+                }
71
+            }
72
+            ssd1306_show(&disp);
73
+        }
74
+    }
75
+}
39
 
76
 
40
 void lcd_init(void) {
77
 void lcd_init(void) {
41
     if (hw_type == HW_PROTOTYPE) {
78
     if (hw_type == HW_PROTOTYPE) {
58
         ssd1306_init(&disp, LCD_WIDTH, LCD_HEIGHT, LCD_ADDR, gpio_i2c_v2);
95
         ssd1306_init(&disp, LCD_WIDTH, LCD_HEIGHT, LCD_ADDR, gpio_i2c_v2);
59
     }
96
     }
60
 
97
 
98
+    // show logo
61
     ssd1306_clear(&disp);
99
     ssd1306_clear(&disp);
62
     for (uint y = 0; y < LOGO_HEIGHT; y++) {
100
     for (uint y = 0; y < LOGO_HEIGHT; y++) {
63
         for (uint x = 0; x < LOGO_WIDTH; x++) {
101
         for (uint x = 0; x < LOGO_WIDTH; x++) {
76
     ssd1306_draw_string(&disp, 0, 0, 2, mode);
114
     ssd1306_draw_string(&disp, 0, 0, 2, mode);
77
     ssd1306_draw_string(&disp, 0, 20, 4, val);
115
     ssd1306_draw_string(&disp, 0, 20, 4, val);
78
     ssd1306_draw_string(&disp, 0, LCD_HEIGHT - 1 - 10, 1, bat);
116
     ssd1306_draw_string(&disp, 0, LCD_HEIGHT - 1 - 10, 1, bat);
117
+    ssd1306_show(&disp);
118
+}
79
 
119
 
120
+void lcd_draw_bye(void) {
121
+    ssd1306_clear(&disp);
122
+    ssd1306_draw_string(&disp, 0, 0, 3, "Boot");
123
+    ssd1306_draw_string(&disp, 0, LCD_HEIGHT / 2, 3, "loader");
80
     ssd1306_show(&disp);
124
     ssd1306_show(&disp);
81
 }
125
 }

+ 36
- 10
src/main.c View File

35
 #define LOGO_INIT_MS 1500
35
 #define LOGO_INIT_MS 1500
36
 
36
 
37
 static const uint gpio_hw_detect = 21;
37
 static const uint gpio_hw_detect = 21;
38
+
38
 enum hw_versions hw_type = HW_UNKNOWN;
39
 enum hw_versions hw_type = HW_UNKNOWN;
39
 
40
 
41
+static bool debug_buttons[NUM_BTNS] = {0};
42
+
43
+static void debug_buttons_callback(enum buttons btn, bool v) {
44
+    debug_buttons[btn] = v;
45
+}
46
+
40
 static void reset_to_bootloader(void) {
47
 static void reset_to_bootloader(void) {
48
+    lcd_draw_bye();
49
+
41
 #ifdef PICO_DEFAULT_LED_PIN
50
 #ifdef PICO_DEFAULT_LED_PIN
42
     reset_usb_boot(1 << PICO_DEFAULT_LED_PIN, 0);
51
     reset_usb_boot(1 << PICO_DEFAULT_LED_PIN, 0);
43
 #else // ! PICO_DEFAULT_LED_PIN
52
 #else // ! PICO_DEFAULT_LED_PIN
45
 #endif // PICO_DEFAULT_LED_PIN
54
 #endif // PICO_DEFAULT_LED_PIN
46
 }
55
 }
47
 
56
 
57
+void handle_serial_input(void) {
58
+    int c = getchar_timeout_us(0);
59
+    if (c == 0x18) {
60
+        reset_to_bootloader();
61
+    } else if (c != PICO_ERROR_TIMEOUT) {
62
+        printf("%c", c);
63
+    }
64
+}
65
+
48
 int main(void) {
66
 int main(void) {
49
     stdio_init_all();
67
     stdio_init_all();
50
 
68
 
63
     lcd_init();
81
     lcd_init();
64
     led_init();
82
     led_init();
65
 
83
 
66
-    // show splash for a bit and animate LEDs
67
-    for (uint i = 0; i < LED_COUNT; i++) {
68
-        led_set(i, true);
69
-        sleep_ms(LOGO_INIT_MS / LED_COUNT);
84
+    // read out button state for debug options
85
+    buttons_callback(debug_buttons_callback);
86
+    for (uint i = 0; i < (DEBOUNCE_DELAY_MS + 5); i++) {
87
+        buttons_run();
88
+        handle_serial_input();
89
+        sleep_ms(1);
90
+    }
91
+
92
+    if (debug_buttons[BTN_REC]) {
93
+        lcd_debug_buttons();
94
+    } else if (!debug_buttons[BTN_H]) {
95
+        // show splash for a bit and animate LEDs
96
+        for (uint i = 0; i < LED_COUNT; i++) {
97
+            handle_serial_input();
98
+            led_set(i, true);
99
+            sleep_ms(LOGO_INIT_MS / LED_COUNT);
100
+        }
70
     }
101
     }
71
 
102
 
72
     // turn off LEDs at end of init
103
     // turn off LEDs at end of init
96
             last_epos = epos;
127
             last_epos = epos;
97
         }
128
         }
98
 
129
 
99
-        int c = getchar_timeout_us(0);
100
-        if (c == 0x18) {
101
-            reset_to_bootloader();
102
-        } else if (c != PICO_ERROR_TIMEOUT) {
103
-            printf("%c", c);
104
-        }
130
+        handle_serial_input();
105
     }
131
     }
106
 
132
 
107
     return 0;
133
     return 0;

+ 15
- 6
src/sequence.c View File

101
 
101
 
102
 void sequence_handle_button_loopstation(enum buttons btn, bool rec) {
102
 void sequence_handle_button_loopstation(enum buttons btn, bool rec) {
103
     switch (btn) {
103
     switch (btn) {
104
-        case BTN_A: {
104
+        case BTN_A:
105
+        case BTN_E: {
105
             pulse_trigger_out(0, channel_times[0]);
106
             pulse_trigger_out(0, channel_times[0]);
106
             pulse_trigger_led(0, channel_times[0]);
107
             pulse_trigger_led(0, channel_times[0]);
108
+            pulse_trigger_led(4, channel_times[0]);
107
             break;
109
             break;
108
         }
110
         }
109
 
111
 
110
-        case BTN_B: {
112
+        case BTN_B:
113
+        case BTN_F: {
111
             pulse_trigger_out(1, channel_times[1]);
114
             pulse_trigger_out(1, channel_times[1]);
112
             pulse_trigger_led(1, channel_times[1]);
115
             pulse_trigger_led(1, channel_times[1]);
116
+            pulse_trigger_led(5, channel_times[1]);
113
             break;
117
             break;
114
         }
118
         }
115
 
119
 
116
-        case BTN_C: {
120
+        case BTN_C:
121
+        case BTN_G: {
117
             pulse_trigger_out(2, channel_times[2]);
122
             pulse_trigger_out(2, channel_times[2]);
118
             pulse_trigger_led(2, channel_times[2]);
123
             pulse_trigger_led(2, channel_times[2]);
124
+            pulse_trigger_led(6, channel_times[2]);
119
             break;
125
             break;
120
         }
126
         }
121
 
127
 
126
 
132
 
127
     if (rec) {
133
     if (rec) {
128
         switch (btn) {
134
         switch (btn) {
129
-            case BTN_A: {
135
+            case BTN_A:
136
+            case BTN_E: {
130
                 sequence_set(last_i, CH_KICK, true);
137
                 sequence_set(last_i, CH_KICK, true);
131
                 break;
138
                 break;
132
             }
139
             }
133
 
140
 
134
-            case BTN_B: {
141
+            case BTN_B:
142
+            case BTN_F: {
135
                 sequence_set(last_i, CH_SNARE, true);
143
                 sequence_set(last_i, CH_SNARE, true);
136
                 break;
144
                 break;
137
             }
145
             }
138
 
146
 
139
-            case BTN_C: {
147
+            case BTN_C:
148
+            case BTN_G: {
140
                 sequence_set(last_i, CH_HIHAT, true);
149
                 sequence_set(last_i, CH_HIHAT, true);
141
                 break;
150
                 break;
142
             }
151
             }

+ 38
- 19
src/ui.c View File

23
 #include "adc.h"
23
 #include "adc.h"
24
 #include "buttons.h"
24
 #include "buttons.h"
25
 #include "lcd.h"
25
 #include "lcd.h"
26
+#include "led.h"
26
 #include "sequence.h"
27
 #include "sequence.h"
27
 #include "ui.h"
28
 #include "ui.h"
28
 
29
 
104
     switch (btn) {
105
     switch (btn) {
105
         case BTN_A:
106
         case BTN_A:
106
         case BTN_B:
107
         case BTN_B:
107
-        case BTN_C: {
108
+        case BTN_C:
109
+        case BTN_E:
110
+        case BTN_F:
111
+        case BTN_G: {
108
             if (val) {
112
             if (val) {
109
                 sequence_handle_button_loopstation(btn, rec_held_down);
113
                 sequence_handle_button_loopstation(btn, rec_held_down);
110
             }
114
             }
111
             break;
115
             break;
112
         }
116
         }
113
 
117
 
114
-        case BTN_REC: {
118
+        case BTN_REC:
119
+        case BTN_D:
120
+        case BTN_H: {
115
             rec_held_down = val;
121
             rec_held_down = val;
116
             sequence_looptime(!val);
122
             sequence_looptime(!val);
117
             break;
123
             break;
129
         case BTN_A:
135
         case BTN_A:
130
         case BTN_B:
136
         case BTN_B:
131
         case BTN_C:
137
         case BTN_C:
138
+        case BTN_D:
139
+        case BTN_E:
140
+        case BTN_F:
141
+        case BTN_G:
142
+        case BTN_H:
132
         case BTN_REC: {
143
         case BTN_REC: {
133
             if (val) {
144
             if (val) {
134
                 sequence_handle_button_drummachine(btn);
145
                 sequence_handle_button_drummachine(btn);
143
     }
154
     }
144
 }
155
 }
145
 
156
 
146
-
147
-#include "pulse.h"
148
-
149
-
150
 static void ui_buttons(enum buttons btn, bool val) {
157
 static void ui_buttons(enum buttons btn, bool val) {
151
     switch (btn) {
158
     switch (btn) {
152
         case BTN_CLICK: {
159
         case BTN_CLICK: {
153
             if (val) {
160
             if (val) {
154
-
155
-
156
-
157
-                pulse_trigger_out(0, 42);
158
-                pulse_trigger_led(0, 42);
159
-
160
-
161
-
162
                 ui_mode = (ui_mode + 1) % UI_NUM_MODES;
161
                 ui_mode = (ui_mode + 1) % UI_NUM_MODES;
163
 
162
 
164
-                // allow other ui mdoes only in drumkit mode
165
-                if (machine_mode == MODE_LOOPSTATION)
166
-                {
163
+                // allow other ui modes only in drumkit mode
164
+                if (machine_mode == MODE_LOOPSTATION) {
167
                     ui_mode = 0;
165
                     ui_mode = 0;
168
                 }
166
                 }
169
 
167
 
215
             while (tmp >= MACHINE_NUM_MODES) {
213
             while (tmp >= MACHINE_NUM_MODES) {
216
                 tmp -= MACHINE_NUM_MODES;
214
                 tmp -= MACHINE_NUM_MODES;
217
             }
215
             }
216
+
217
+            enum machine_modes prev_mode = machine_mode;
218
             machine_mode = tmp;
218
             machine_mode = tmp;
219
 
219
 
220
             printf("mode add %"PRIi32" now %d\n", val, machine_mode);
220
             printf("mode add %"PRIi32" now %d\n", val, machine_mode);
221
 
221
 
222
-            // reset sequence
223
-            sequence_init();
222
+            if (prev_mode != machine_mode) {
223
+                // reset sequence
224
+                sequence_init();
225
+
226
+                // turn off all LEDs
227
+                for (uint i = 0; i < LED_COUNT; i++) {
228
+                    led_set(i, false);
229
+                }
230
+
231
+                // enable static LEDs in loopstation mode
232
+                if (machine_mode == MODE_LOOPSTATION) {
233
+                    led_set(NUM_CHANNELS, true);
234
+                    led_set(NUM_CHANNELS + 4, true);
235
+                }
236
+            }
224
             break;
237
             break;
225
         }
238
         }
226
 
239
 
247
 
260
 
248
 void ui_init(void) {
261
 void ui_init(void) {
249
     buttons_callback(ui_buttons);
262
     buttons_callback(ui_buttons);
263
+
264
+    // enable static LEDs in loopstation mode
265
+    machine_mode = MODE_LOOPSTATION;
266
+    led_set(NUM_CHANNELS, true);
267
+    led_set(NUM_CHANNELS + 4, true);
268
+
250
     ui_redraw();
269
     ui_redraw();
251
 }
270
 }
252
 
271
 

Loading…
Cancel
Save