瀏覽代碼

wip lars v2 fw

Thomas Buck 7 月之前
父節點
當前提交
60bd075452
共有 9 個檔案被更改,包括 187 行新增39 行删除
  1. 8
    0
      include/buttons.h
  2. 4
    0
      include/led.h
  3. 6
    0
      include/main.h
  4. 70
    19
      src/buttons.c
  5. 27
    6
      src/encoder.c
  6. 28
    11
      src/lcd.c
  7. 6
    0
      src/led.c
  8. 26
    3
      src/main.c
  9. 12
    0
      src/ui.c

+ 8
- 0
include/buttons.h 查看文件

@@ -25,6 +25,14 @@ enum buttons {
25 25
     BTN_A = 0,
26 26
     BTN_B,
27 27
     BTN_C,
28
+
29
+    // only on LARS V2
30
+    BTN_D,
31
+    BTN_E,
32
+    BTN_F,
33
+    BTN_G,
34
+    BTN_H,
35
+
28 36
     BTN_REC,
29 37
     BTN_CLICK,
30 38
     NUM_BTNS // count

+ 4
- 0
include/led.h 查看文件

@@ -22,7 +22,11 @@
22 22
 #include <stdint.h>
23 23
 #include <stdbool.h>
24 24
 
25
+#if 0
25 26
 #define LED_COUNT 4
27
+#else
28
+#define LED_COUNT 8
29
+#endif
26 30
 
27 31
 void led_init(void);
28 32
 void led_set(uint32_t i, bool v);

+ 6
- 0
include/main.h 查看文件

@@ -19,6 +19,12 @@
19 19
 #ifndef __MAIN_H__
20 20
 #define __MAIN_H__
21 21
 
22
+enum hw_versions {
23
+    HW_UNKNOWN = 0,
24
+    HW_PROTOTYPE,
25
+    HW_V2,
26
+};
22 27
 
28
+extern enum hw_versions hw_type;
23 29
 
24 30
 #endif // __MAIN_H__

+ 70
- 19
src/buttons.c 查看文件

@@ -19,18 +19,40 @@
19 19
 #include <stdio.h>
20 20
 #include "pico/stdlib.h"
21 21
 
22
+#include "main.h"
22 23
 #include "buttons.h"
23 24
 
24 25
 #define DEBOUNCE_DELAY_MS 50
25 26
 
26
-static const uint gpio_num[NUM_BTNS] = {
27
+static const uint gpio_num_proto[NUM_BTNS] = {
27 28
     8, // BTN_A
28 29
     9, // BTN_B
29 30
     12, // BTN_C
31
+
32
+    // not existing on prototype
33
+    0xFF, // BTN_D
34
+    0xFF, // BTN_E
35
+    0xFF, // BTN_F
36
+    0xFF, // BTN_G
37
+    0xFF, // BTN_H
38
+
30 39
     14, // BTN_REC
31 40
     16, // BTN_CLICK
32 41
 };
33 42
 
43
+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
50
+    0xFF, // BTN_G
51
+    0xFF, // BTN_H
52
+    0xFF, // BTN_REC
53
+    20, // BTN_CLICK
54
+};
55
+
34 56
 struct button_state {
35 57
     uint32_t last_time;
36 58
     bool current_state, last_state;
@@ -41,9 +63,20 @@ static void (*callback)(enum buttons, bool) = NULL;
41 63
 
42 64
 void buttons_init(void) {
43 65
     for (uint i = 0; i < NUM_BTNS; i++) {
44
-        gpio_init(gpio_num[i]);
45
-        gpio_set_dir(gpio_num[i], GPIO_IN);
46
-        gpio_pull_up(gpio_num[i]);
66
+        uint n = 0xFF;
67
+        if (hw_type == HW_PROTOTYPE) {
68
+            n = gpio_num_proto[i];
69
+        } else if (hw_type == HW_V2) {
70
+            n = gpio_num_v2[i];
71
+        }
72
+
73
+        if (n >= 0xFF) {
74
+            continue;
75
+        }
76
+
77
+        gpio_init(n);
78
+        gpio_set_dir(n, GPIO_IN);
79
+        gpio_pull_up(n);
47 80
 
48 81
         buttons[i].last_time = 0;
49 82
         buttons[i].current_state = false;
@@ -55,26 +88,44 @@ void buttons_callback(void (*fp)(enum buttons, bool)) {
55 88
     callback = fp;
56 89
 }
57 90
 
58
-void buttons_run(void) {
59
-    for (uint i = 0; i < NUM_BTNS; i++) {
60
-        bool state = !gpio_get(gpio_num[i]);
61
-        uint32_t now = to_ms_since_boot(get_absolute_time());
91
+static void button_run_single(bool state, uint i) {
92
+    uint32_t now = to_ms_since_boot(get_absolute_time());
62 93
 
63
-        if (state != buttons[i].last_state) {
64
-            buttons[i].last_time = now;
65
-        }
94
+    if (state != buttons[i].last_state) {
95
+        buttons[i].last_time = now;
96
+    }
66 97
 
67
-        if ((now - buttons[i].last_time) > DEBOUNCE_DELAY_MS) {
68
-            if (state != buttons[i].current_state) {
69
-                //printf("btn %d now %s\n", i, state ? "pressed" : "released");
98
+    if ((now - buttons[i].last_time) > DEBOUNCE_DELAY_MS) {
99
+        if (state != buttons[i].current_state) {
100
+            printf("btn %d now %s\n", i, state ? "pressed" : "released");
70 101
 
71
-                buttons[i].current_state = state;
72
-                if (callback) {
73
-                    callback(i, state);
74
-                }
102
+            buttons[i].current_state = state;
103
+            if (callback) {
104
+                callback(i, state);
75 105
             }
76 106
         }
107
+    }
108
+
109
+    buttons[i].last_state = state;
110
+}
111
+
112
+static void buttons_run_proto(void) {
113
+    for (uint i = 0; i < NUM_BTNS; i++) {
114
+        if (gpio_num_proto[i] >= 0xFF) {
115
+            continue;
116
+        }
117
+
118
+        bool state = !gpio_get(gpio_num_proto[i]);
119
+        button_run_single(state, i);
120
+    }
121
+}
122
+
123
+void buttons_run(void) {
124
+    if (hw_type == HW_PROTOTYPE) {
125
+        buttons_run_proto();
126
+    } else if (hw_type == HW_V2) {
127
+        // TODO read matrix
77 128
 
78
-        buttons[i].last_state = state;
129
+        button_run_single(!gpio_get(gpio_num_v2[BTN_CLICK]), BTN_CLICK);
79 130
     }
80 131
 }

+ 27
- 6
src/encoder.c 查看文件

@@ -13,6 +13,7 @@
13 13
 #include <stdio.h>
14 14
 #include "pico/stdlib.h"
15 15
 
16
+#include "main.h"
16 17
 #include "encoder.h"
17 18
 
18 19
 #define LATCH0 0
@@ -24,10 +25,14 @@
24 25
 
25 26
 #define ENCODER_MODE FOUR3
26 27
 
27
-static const uint gpio_num[2] = {
28
+static const uint gpio_num_proto[2] = {
28 29
     17, 18
29 30
 };
30 31
 
32
+static const uint gpio_num_v2[2] = {
33
+    19, 18
34
+};
35
+
31 36
 static const int8_t KNOBDIR[] = {
32 37
     0, -1, 1, 0,
33 38
     1, 0, 0, -1,
@@ -42,12 +47,23 @@ static int32_t positionExtPrev;
42 47
 
43 48
 void encoder_init(void) {
44 49
     for (uint i = 0; i < 2; i++) {
45
-        gpio_init(gpio_num[i]);
46
-        gpio_set_dir(gpio_num[i], GPIO_IN);
47
-        gpio_pull_up(gpio_num[i]);
50
+        if (hw_type == HW_PROTOTYPE) {
51
+            gpio_init(gpio_num_proto[i]);
52
+            gpio_set_dir(gpio_num_proto[i], GPIO_IN);
53
+            gpio_pull_up(gpio_num_proto[i]);
54
+        } else if (hw_type == HW_V2) {
55
+            gpio_init(gpio_num_v2[i]);
56
+            gpio_set_dir(gpio_num_v2[i], GPIO_IN);
57
+            gpio_pull_up(gpio_num_v2[i]);
58
+        }
59
+    }
60
+
61
+    if (hw_type == HW_PROTOTYPE) {
62
+        oldState = gpio_get(gpio_num_proto[0]) | (gpio_get(gpio_num_proto[1]) << 1);
63
+    } else if (hw_type == HW_V2) {
64
+        oldState = gpio_get(gpio_num_v2[0]) | (gpio_get(gpio_num_v2[1]) << 1);
48 65
     }
49 66
 
50
-    oldState = gpio_get(gpio_num[0]) | (gpio_get(gpio_num[1]) << 1);
51 67
     position = 0;
52 68
     positionExt = 0;
53 69
     positionExtPrev = 0;
@@ -59,7 +75,12 @@ int32_t encoder_pos(void)
59 75
 }
60 76
 
61 77
 void encoder_run(void) {
62
-    int8_t thisState = gpio_get(gpio_num[0]) | (gpio_get(gpio_num[1]) << 1);
78
+    int8_t thisState = 0;
79
+    if (hw_type == HW_PROTOTYPE) {
80
+        thisState = gpio_get(gpio_num_proto[0]) | (gpio_get(gpio_num_proto[1]) << 1);
81
+    } else if (hw_type == HW_V2) {
82
+        thisState = gpio_get(gpio_num_v2[0]) | (gpio_get(gpio_num_v2[1]) << 1);
83
+    }
63 84
 
64 85
     if (oldState != thisState) {
65 86
         position += KNOBDIR[thisState | (oldState << 2)];

+ 28
- 11
src/lcd.c 查看文件

@@ -24,29 +24,46 @@
24 24
 
25 25
 #include "ssd1306.h"
26 26
 #include "logo.h"
27
+#include "main.h"
27 28
 #include "lcd.h"
28 29
 
29
-#define LCD_I2C i2c0
30
-static const uint gpio_num[2] = { 0, 1 };
30
+static i2c_inst_t *gpio_i2c_proto = i2c0;
31
+static const uint gpio_num_proto[2] = { 0, 1 };
32
+
33
+static i2c_inst_t *gpio_i2c_v2 = i2c0;
34
+static const uint gpio_num_v2[2] = { 16, 17 };
35
+
31 36
 #define LCD_ADDR 0x3C
32 37
 
33 38
 static ssd1306_t disp;
34 39
 
35 40
 void lcd_init(void) {
36
-    i2c_init(LCD_I2C, 1000 * 1000);
37
-    for (uint i = 0; i < sizeof(gpio_num) / sizeof(gpio_num[0]); i++) {
38
-        gpio_set_function(gpio_num[i], GPIO_FUNC_I2C);
39
-        gpio_pull_up(gpio_num[i]);
40
-    }
41
+    if (hw_type == HW_PROTOTYPE) {
42
+        i2c_init(gpio_i2c_proto, 1000 * 1000);
43
+        for (uint i = 0; i < sizeof(gpio_num_proto) / sizeof(gpio_num_proto[0]); i++) {
44
+            gpio_set_function(gpio_num_proto[i], GPIO_FUNC_I2C);
45
+            gpio_pull_up(gpio_num_proto[i]);
46
+        }
41 47
 
42
-    disp.external_vcc = false;
43
-    ssd1306_init(&disp, LCD_WIDTH, LCD_HEIGHT, LCD_ADDR, LCD_I2C);
48
+        disp.external_vcc = false;
49
+        ssd1306_init(&disp, LCD_WIDTH, LCD_HEIGHT, LCD_ADDR, gpio_i2c_proto);
50
+    } else if (hw_type == HW_V2) {
51
+        i2c_init(gpio_i2c_v2, 1000 * 1000);
52
+        for (uint i = 0; i < sizeof(gpio_num_v2) / sizeof(gpio_num_v2[0]); i++) {
53
+            gpio_set_function(gpio_num_v2[i], GPIO_FUNC_I2C);
54
+            gpio_pull_up(gpio_num_v2[i]);
55
+        }
56
+
57
+        disp.external_vcc = false;
58
+        ssd1306_init(&disp, LCD_WIDTH, LCD_HEIGHT, LCD_ADDR, gpio_i2c_v2);
59
+    }
44 60
 
45 61
     ssd1306_clear(&disp);
46 62
     for (uint y = 0; y < LOGO_HEIGHT; y++) {
47 63
         for (uint x = 0; x < LOGO_WIDTH; x++) {
48
-            uint pos = y * LOGO_WIDTH + x;
49
-            if (logo_data[pos / 8] & (1 << (pos % 8))) {
64
+            const uint pos = y * LOGO_WIDTH + x;
65
+            const uint bit = 7 - (pos % 8);
66
+            if (logo_data[pos / 8] & (1 << bit)) {
50 67
                 ssd1306_draw_pixel(&disp, x, y);
51 68
             }
52 69
         }

+ 6
- 0
src/led.c 查看文件

@@ -23,9 +23,15 @@
23 23
 #include "sequence.h"
24 24
 #include "led.h"
25 25
 
26
+#if 0
26 27
 static const uint led_gpio_num[LED_COUNT] = {
27 28
     10, 11, 13, 15,
28 29
 };
30
+#else
31
+static const uint led_gpio_num[LED_COUNT] = {
32
+    6, 7, 8, 9, 10, 11, 12, 13,
33
+};
34
+#endif
29 35
 
30 36
 static const uint ch_gpio_num[NUM_CHANNELS] = {
31 37
     22, 26, 27,

+ 26
- 3
src/main.c 查看文件

@@ -32,6 +32,10 @@
32 32
 #include "main.h"
33 33
 
34 34
 #define WATCHDOG_PERIOD_MS 100
35
+#define LOGO_INIT_MS 1500
36
+
37
+static const uint gpio_hw_detect = 21;
38
+enum hw_versions hw_type = HW_UNKNOWN;
35 39
 
36 40
 static void reset_to_bootloader(void) {
37 41
 #ifdef PICO_DEFAULT_LED_PIN
@@ -42,20 +46,39 @@ static void reset_to_bootloader(void) {
42 46
 }
43 47
 
44 48
 int main(void) {
45
-    //watchdog_enable(WATCHDOG_PERIOD_MS, 1);
46 49
     stdio_init_all();
50
+
51
+    gpio_init(gpio_hw_detect);
52
+    gpio_set_dir(gpio_hw_detect, GPIO_IN);
53
+    gpio_pull_up(gpio_hw_detect);
54
+    if (gpio_get(gpio_hw_detect)) {
55
+        hw_type = HW_PROTOTYPE;
56
+    } else {
57
+        hw_type = HW_V2;
58
+    }
59
+
47 60
     bat_init();
48 61
     buttons_init();
49 62
     encoder_init();
50 63
     lcd_init();
51 64
     led_init();
52 65
 
53
-    // show splash for a bit
54
-    sleep_ms(500);
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);
70
+    }
71
+
72
+    // turn off LEDs at end of init
73
+    for (uint i = 0; i < LED_COUNT; i++) {
74
+        led_set(i, false);
75
+    }
55 76
 
56 77
     sequence_init();
57 78
     ui_init();
79
+
58 80
     printf("init done\n");
81
+    watchdog_enable(WATCHDOG_PERIOD_MS, 1);
59 82
 
60 83
     int32_t last_epos = 0;
61 84
 

+ 12
- 0
src/ui.c 查看文件

@@ -143,10 +143,22 @@ static void ui_buttons_drummachine(enum buttons btn, bool val) {
143 143
     }
144 144
 }
145 145
 
146
+
147
+#include "pulse.h"
148
+
149
+
146 150
 static void ui_buttons(enum buttons btn, bool val) {
147 151
     switch (btn) {
148 152
         case BTN_CLICK: {
149 153
             if (val) {
154
+
155
+
156
+
157
+                pulse_trigger_out(0, 42);
158
+                pulse_trigger_led(0, 42);
159
+
160
+
161
+
150 162
                 ui_mode = (ui_mode + 1) % UI_NUM_MODES;
151 163
 
152 164
                 // allow other ui mdoes only in drumkit mode

Loading…
取消
儲存