Browse Source

New ui, global settings.

Daniele Lacamera 4 years ago
parent
commit
d4749d2fe9
15 changed files with 253 additions and 82 deletions
  1. 1 1
      Makefile
  2. 1 1
      button.c
  3. 6 0
      drone.c
  4. 2 0
      drone.h
  5. 3 2
      led.c
  6. 8 4
      main.c
  7. 25 15
      pot.c
  8. 1 0
      pot.h
  9. 6 0
      settings.c
  10. 14 0
      settings.h
  11. 7 15
      timer.c
  12. 2 3
      timer.h
  13. 119 32
      ui.c
  14. 15 3
      ui.h
  15. 43 6
      ui_drone.c

+ 1 - 1
Makefile

@@ -5,7 +5,7 @@ VERSION?=1
 
 OBJS:=startup.o main.o system.o  mem.o led.o \
 	i2c.o display.o font_twisted.o button.o systick.o newlib.o uart.o ui.o timer.o\
-	mutex.o ui_drone.o adc.o spi.o pot.o dac.o sound.o drone.o
+	mutex.o ui_drone.o adc.o spi.o pot.o dac.o sound.o drone.o settings.o
 
 
 UMX:=lib/unicore-mx/lib/libucmx_stm32f4.a

+ 1 - 1
button.c

@@ -39,7 +39,7 @@ enum button_state {
 #endif
 
 #define BUTTON_DEBOUNCE_TIME 50
-#define BUTTON_HOLD_TIME 1500
+#define BUTTON_HOLD_TIME 200
 
 
 

+ 6 - 0
drone.c

@@ -19,6 +19,12 @@ static struct drone_slot drone_pattern[MAX_PATTERN_LEN] = {
     { 40, 10 }, { 40, 10}, {36, 10}, {32,10}
 };
 
+void drone_mute(void)
+{
+    pot_set(0, 0xFF);
+    pot_set(1, 0x0);
+}
+
 void drone_beat(int pattern_pos)
 {
     struct drone_slot *key = &drone_pattern[pattern_pos];

+ 2 - 0
drone.h

@@ -3,6 +3,8 @@
 #define DRONE_H_INCLUDED
 #include <stdint.h>
 
+void drone_mute(void);
+
 struct __attribute__((packed)) drone_slot {
     uint8_t pitch;
     uint8_t env;

+ 3 - 2
led.c

@@ -84,10 +84,11 @@ void led_toggle(int led)
 
 void led_beat(int b)
 {
-    if (b < 1 || b > 8)
+    if (b < 0 || b > 8)
         return;
     gpio_clear(GPIOB, BANK_B_LD);
     gpio_clear(GPIOE, BANK_E_LD);
-    led_on(b);
+    if (b != 0)
+        led_on(b);
 }
 

+ 8 - 4
main.c

@@ -15,6 +15,12 @@
 #include "ui.h"
 #include "button.h"
 #include "adc.h"
+#include "pot.h"
+#include "settings.h"
+#include "drums.h"
+#include "drone.h"
+#include "uart.h"
+#include "timer.h"
 extern uint32_t cpu_freq;
 
 #define BLINK_INTERVAL 500
@@ -39,9 +45,6 @@ static void bootlevel_0(void)
     printf("Buttons initialized.\r\n");
 }
 
-extern int timer_init(uint32_t bpm);
-extern int timer_start();
-extern int timer_stop();
 
 static void bootlevel_1(void)
 {
@@ -66,7 +69,7 @@ static void bootlevel_1(void)
     printf("Displaying splash screen...\r\n");
     ui_init();
     printf("UI initialized.\r\n");
-    timer_init(140);
+    timer_init();
     drums_init();
     drums_start();
 
@@ -106,6 +109,7 @@ void process_button(uint8_t press, int hold)
         process_input_callback(press, hold);
     else
         ui_button_press(press, hold);
+
 }
 
 extern void gettime(uint32_t *s, uint32_t *us);

+ 25 - 15
pot.c

@@ -4,10 +4,11 @@
 #include "system.h"
 #include "led.h"
 #include "pinout.h"
+#include "settings.h"
+#include "pot.h"
 
 extern volatile uint32_t jiffies;
 
-uint32_t p1_lvl, p0_lvl, master_lvl;
 
 
 static int pot_cs[3] = { 8, 7, 6 }; // PC6, PC7, PC8
@@ -18,13 +19,11 @@ static int pot_cs[3] = { 8, 7, 6 }; // PC6, PC7, PC8
 #define POTINC GPIO14 // D14
 #define POTUD  GPIO15 // D15
 
-#define NUM_POTS 3
 #define POT_CS_PINS (POT0 | POT1 | POTM)
 #define POT_CTRL_PINS (POTINC | POTUD)
 
-
+static int HWLevel[3] = {0, 0, 0};
 static uint32_t Pots[NUM_POTS] = { POT0, POT1, POTM };
-static int Levels[NUM_POTS] = { 0, 0, 0 };
 
 
 static void p_offset(int p, int offset)
@@ -64,21 +63,21 @@ static void p_offset(int p, int offset)
             ;;
     }
 
-    Levels[p] += offset;
-    if (Levels[p] > 100)
-        Levels[p] = 100;
-    if (Levels[p] < 0)
-        Levels[p] = 0;
+    HWLevel[p] += offset;
+    if (HWLevel[p] > 100)
+        HWLevel[p] = 100;
+    if (HWLevel[p] < 0)
+        HWLevel[p] = 0;
 }
 
 void pot_offset(int p, int offset)
 {
-    if ((Levels[p] + offset) > 100) {
-        offset = 100 - Levels[p];
+    if ((HWLevel[p] + offset) > 100) {
+        offset = 100 - HWLevel[p];
     }
 
-    if ((Levels[p] + offset) < 0) {
-        offset = 0 - Levels[p];
+    if ((HWLevel[p] + offset) < 0) {
+        offset = 0 - HWLevel[p];
     }
     
     if (offset == 0)
@@ -108,20 +107,31 @@ void pot_init(void)
 
 }
 
+void pot_sync(int p)
+{
+    pot_set(p, Settings.levels[p]);
+}
+
 
 int pot_get(int p)
 {
-    return Levels[p];
+    return HWLevel[p];
 }
 
 void pot_set(int p, int val)
 {
-    int old = Levels[p];
+    int old = HWLevel[p];
+    int new = val;
     int off;
+
+
     if (val < 0)
         val = 0;
     if (val > 100)
         val = 100;
+
+    Settings.levels[p] = val;
+
     off = val - old;
     if (off == 0)
         return;

+ 1 - 0
pot.h

@@ -11,5 +11,6 @@ void pot_offset(int p, int offset);
 
 #define pot_get_master() pot_get(2)
 #define pot_set_master(x) pot_set(2,x)
+#define NUM_POTS 3
 
 #endif

+ 6 - 0
settings.c

@@ -0,0 +1,6 @@
+#include "settings.h"
+
+struct settings Settings = {
+    .bpm = 125,   
+    
+};

+ 14 - 0
settings.h

@@ -0,0 +1,14 @@
+#ifndef SETTINGS_H_INCLUDED
+#define SETTINGS_H_INCLUDED
+#include <stdint.h>
+#include "pot.h"
+
+struct settings {
+    int levels[NUM_POTS];
+#define master_vol levels[2]
+    int bpm;
+    int sequencer_on;
+};
+
+extern struct settings Settings;
+#endif

+ 7 - 15
timer.c

@@ -3,11 +3,11 @@
 #include "led.h"
 #include "timer.h"
 #include <stdlib.h>
+#include "settings.h"
 
 #define S_PER_MINUTE (60)
 
 extern uint32_t cpu_freq;
-static uint32_t sys_bpm = 75;
 
 void (*beat_callback)(uint32_t b) = NULL;
 
@@ -21,19 +21,13 @@ void timer_clear_beat_callback(void)
     timer_set_beat_callback(NULL);
 } 
 
-
-uint32_t timer_get_bpm(void)
-{
-    return sys_bpm;
-}
-
-int timer_set_bpm(uint32_t bpm)
+int timer_set_bpm(void)
 {
     uint32_t val = 0;
     uint32_t psc = 1;
     uint32_t err = 0;
     uint32_t reg = 0;
-    uint32_t clock = (cpu_freq / (4 * bpm)) * (S_PER_MINUTE);;
+    uint32_t clock = (cpu_freq / (4 * Settings.bpm)) * (S_PER_MINUTE);;
 
     while (psc < 65535) {
         val = clock / psc;
@@ -52,7 +46,6 @@ int timer_set_bpm(uint32_t bpm)
     TIM4_PSC    = psc;
     TIM4_ARR    = val;
     TIM4_CNT    = val - 1;
-    sys_bpm = bpm;
     return 0;
 }
 
@@ -64,8 +57,8 @@ int timer_start(void)
 
 int timer_stop(void)
 {
-    TIM4_CR1    |= TIM_CR1_CLOCK_ENABLE;
-    TIM4_DIER   |= TIM_DIER_UIE;
+    TIM4_CR1    &= ~TIM_CR1_CLOCK_ENABLE;
+    TIM4_DIER   &= ~TIM_DIER_UIE;
 }
 
 static void timer_irq_setup(void)
@@ -79,12 +72,11 @@ static void timer_irq_setup(void)
 }
 
 
-int timer_init(uint32_t bpm)
+int timer_init(void)
 {
     timer_stop();
     timer_irq_setup();
-    timer_set_bpm(bpm);
-    timer_start();
+    timer_set_bpm();
     return 0;
 }
 

+ 2 - 3
timer.h

@@ -1,11 +1,10 @@
 #ifndef TIMER_H_INCLUDED
 #define TIMER_H_INCLUDED
 
-uint32_t timer_get_bpm(void);
-int timer_set_bpm(uint32_t bpm);
+int timer_set_bpm(void);
 int timer_start(void);
 int timer_stop(void);
-int timer_init(uint32_t bpm);
+int timer_init(void);
 void timer_set_beat_callback(void (*b_cb)(uint32_t));
 void timer_clear_beat_callback(void);
 

+ 119 - 32
ui.c

@@ -22,8 +22,9 @@
 //#define DEVICE_INITIALIZATION
 
 static const char welcome_message0[]= "  Waveblender  ";
-static const char welcome_message1[]= "   (c) 2020    ";
-static const char welcome_message2[]= "  danielinux   ";
+static const char welcome_message1[]= "(c) danielinux ";
+static const char welcome_message2[]= "    GPL v.2    ";
+static const char welcome_message3[]= "src: wb.vado.li";
 
 static uint32_t last_action = 0;
 static uint32_t offset = 0;
@@ -88,6 +89,7 @@ static void ui_display_menu_refresh(void)
     const struct display_menu *menu = CurrentMenu;
     uint8_t vline;
     int i;
+    char txt[16];
     display_scroll(NULL, display_cur_v);
     display_clear(NULL);
 
@@ -95,10 +97,74 @@ static void ui_display_menu_refresh(void)
         vline = i + 4;
         if (vline > 7)
             vline -= 8;
+        switch (menu->entry[i].type) {
+            case ENTRY_TYPE_TEXT:
+                strncpy(txt, menu->entry[i].label, 15);
+                break;
+            case ENTRY_TYPE_HEX:
+                {
+                    int x = *menu->entry[i].var ;
+                    int j;
+                    strncpy(txt, menu->entry[i].label, 11);
+                    for (j = strlen(menu->entry[i].label); j < 12; j++)
+                        txt[j] = ' ';
+                    if (x > 0xFF) {
+                        if (((x >> 8) & 0x0F) > 9)
+                            txt[12] = (((x >> 8) & 0x0F) - 10) + 'A';
+                        else
+                            txt[12] = ((x >> 8) & 0x0F) + '0';
+                    } else
+                        txt[12] = ' ';
+                    if (x > 0x0F) {
+                        if (((x >> 4) & 0x0F) > 9)
+                            txt[13] = (((x >> 4) & 0x0F) - 10) + 'A';
+                        else
+                            txt[13] = ((x >> 4) & 0x0F) + '0';
+                    } else
+                        txt[13] = ' ';
+                    if ((x & 0x0F) > 9)
+                        txt[14] = ((x & 0x0F) - 10) + 'A';
+                    else
+                        txt[14] = (x & 0x0F) + '0';
+                }
+                
+                break;
+            case ENTRY_TYPE_BOOL:
+                {
+                    int x = *menu->entry[i].var ;
+                    int j;
+                    strncpy(txt, menu->entry[i].label, 10);
+                    for (j = strlen(menu->entry[i].label); j < 12; j++)
+                        txt[j] = ' ';
+                    if (x)
+                        strcpy(txt + 10, "[ ON]");
+                    else
+                        strcpy(txt + 10, "[OFF]");
+                }
+                break;
+            case ENTRY_TYPE_DEC:
+                {
+                    int x = *menu->entry[i].var ;
+                    int j;
+                    strncpy(txt, menu->entry[i].label, 11);
+                    for (j = strlen(menu->entry[i].label); j < 12; j++)
+                        txt[j] = ' ';
+                    if (x > 99) {
+                        txt[12] = (x / 100) + '0';
+                    } else
+                        txt[12] = ' ';
+                    if (x > 9) {
+                        txt[13] = ((x % 100)/10) + '0';
+                    } else
+                        txt[13] = ' ';
+                    txt[14] = (x % 10) + '0';
+                }
+                break;
+        }
         if (i == menu_selection)
-            display_text_inverse(vline, menu->entry[i].title);
+            display_text_inverse(vline, txt);
         else
-            display_text(vline, menu->entry[i].title);
+            display_text(vline, txt);
     }
     WFI();
 }
@@ -115,32 +181,52 @@ void ui_display_menu(const struct display_menu *menu)
 
 void ui_button_press(uint8_t b, int hold)
 {
-    if (b == '+') {
-        int n = menu_selection;
-        menu_selection = 0;
-        if (CurrentMenu->entry[n].action) {
-            display_cur_v = 0;
-            display_clear(NULL);
-            display_scroll(NULL, display_cur_v);
-            CurrentMenu->entry[n].action(
-                    CurrentMenu->entry[n].arg);
-            
-        }
-        return;
-    }
-    if (b == 'U') {
-        if (menu_selection > 0) {
-            menu_selection--;
-            ui_menu_autoscroll();
-            ui_display_menu_refresh();
-        }
-    }
-    if (b == 'D') {
-        if (menu_selection < CurrentMenu->entry_n - 1) {
-            menu_selection++;
-            ui_menu_autoscroll();
-            ui_display_menu_refresh();
-        }
+    int n = menu_selection;
+    struct display_menu_entry e; 
+    switch (b) {
+        case 'U':
+            if (menu_selection > 0) {
+                menu_selection--;
+                ui_menu_autoscroll();
+                ui_display_menu_refresh();
+            }
+            break;
+        case 'D':
+            if (menu_selection < CurrentMenu->entry_n - 1) {
+                menu_selection++;
+                ui_menu_autoscroll();
+                ui_display_menu_refresh();
+            }
+            break;
+        default:
+            e = CurrentMenu->entry[n];
+            int changed = 0;
+            /* Default actions for '-', '+', '*' */
+            if (e.var && (e.type == ENTRY_TYPE_BOOL)) {
+                if ((*e.var) && ((b == '-') || (b == '*'))) {
+                    *e.var = 0;
+                    changed = 1;
+                } else if ((!(*e.var)) && ((b == '+') || (b == '*'))) {
+                    *e.var = 1;
+                    changed = 1;
+                }
+            } else if ((e.min != e.max) && e.var && ((e.type == ENTRY_TYPE_DEC) || (e.type == ENTRY_TYPE_DEC))) {
+                if ((*e.var > e.min) && (b == '-')) {
+                    *e.var -= e.step;
+                    changed = 1;
+                } else if ((*e.var < e.max) && (b == '+')) {
+                    *e.var += e.step;
+                    changed = 1;
+                }
+            }
+            /* Custom actions for '-', '+', '*' (after changes are applied) */
+            if (b != 0 && e.action) {
+                e.action(&e, b);
+                changed = 1;
+            }
+            if (changed) {
+                ui_display_menu_refresh();
+            }
     }
 }
 
@@ -152,16 +238,17 @@ void ui_init(void)
     display_text(0, welcome_message0);
     display_text(1, welcome_message1);
     display_text(2, welcome_message2);
+    display_text(3, welcome_message3);
     now = jiffies;
     for (i = 0x3f; i >= 0x20; i--) {
         display_scroll(NULL, i);
-        while ((jiffies - now) < 30)
+        while ((jiffies - now) < 20)
             WFI();
         now = jiffies;
     }
     for (i = display_getcontrast(NULL); i >= 0; i--) {
         display_setcontrast(NULL, i);
-        while ((jiffies - now) < 10)
+        while ((jiffies - now) < 16)
             WFI();
         now = jiffies;
     }

+ 15 - 3
ui.h

@@ -4,14 +4,26 @@
 
 void ui_init(void);
 
+#define ENTRY_TYPE_TEXT 0
+#define ENTRY_TYPE_BOOL 1
+#define ENTRY_TYPE_DEC  2
+#define ENTRY_TYPE_HEX  3
+
+#define MAX_ENTRY 8
+
+
+
 struct display_menu {
     struct display_menu *next;
     int entry_n;
     struct display_menu_entry {
-        char title[16];
-        void (*action)(const void *arg);
+        int type;
+        char label[16];
+        void (*action)(struct display_menu_entry *item, uint8_t button);
+        int min, max, step;
+        int *var;
         const void *arg;
-    } entry[8];
+    } entry[MAX_ENTRY];
 
 };
 

+ 43 - 6
ui_drone.c

@@ -7,6 +7,9 @@
 #include "unicore-mx/stm32/gpio.h"
 #include "unicore-mx/stm32/rcc.h"
 #include "pot.h"
+#include "dac.h"
+#include "settings.h"
+#include "timer.h"
 
 #define CENTER_X ((int)(52))
 #define CENTER_Y ((int)(50))
@@ -16,7 +19,7 @@ struct display_menu *CurrentMenu = &MainMenu;
 
 extern volatile uint32_t jiffies;
 static uint32_t drone_xy_gain = 1;
-
+#if 0
 static void ui_return(uint8_t press, int hold)
 {
     display_clear(NULL);
@@ -192,7 +195,7 @@ static void ui_bpm_input(uint8_t press, int hold)
     if (press == 'U') {
         if (sys_bpm < 300) {
             timer_stop();
-            timer_set_bpm(sys_bpm + 1);
+            timer_set_bpm();
             led_beat(1);
             timer_set_beat(1);
             timer_start();
@@ -208,7 +211,7 @@ static void ui_bpm_input(uint8_t press, int hold)
             timer_start();
         }
     }
-    if (press == '+') {
+    if (press == '*') {
         display_clear(NULL);
         clear_input_callback();
         ui_display_menu(&MainMenu);
@@ -294,15 +297,49 @@ const struct display_menu SettingsMenu = {
     }
 };
 
+#endif
+
+static void ui_sequencer_action(struct display_menu_entry *e, uint8_t b)
+{
+    if (Settings.sequencer_on) {
+        timer_set_beat(1);
+        timer_start();
+    } else {
+        led_beat(0);
+        drone_mute();
+        timer_stop();
+    }
+}
+
+static void ui_master_action(struct display_menu_entry *e, uint8_t b)
+{
+    pot_sync(2);
+}
+
+static void ui_bpm_action(struct display_menu_entry *e, uint8_t b)
+{
+    timer_stop();
+    timer_set_bpm();
+    led_beat(1);
+    timer_set_beat(1);
+    timer_start();
+}
+
+
 const struct display_menu MainMenu = {
-    .entry_n = 5,
+    .entry_n = 3,
     .entry = {
-        { "Master Volume  ", ui_mastervol, NULL },
+        /* TYPE, label, action, min, max, var, arg */
+        { ENTRY_TYPE_BOOL, "Sequencer", ui_sequencer_action, 0, 0, 0, &Settings.sequencer_on, NULL },
+        { ENTRY_TYPE_DEC, "Volume: ", ui_master_action, 0, 100, 2, &Settings.levels[2], NULL },
+        { ENTRY_TYPE_DEC, "BPM: ", ui_bpm_action, 30, 300, 1,  &Settings.bpm, NULL },
+        /*
         { "BPM"          , ui_bpm, NULL},
         { "Pattern        ", ui_submenu, &PatternMenu },
         { "Drone          ", ui_submenu, &DroneMenu},
         { "Bytebeat       ", ui_bytebeat },
-        { "", NULL, NULL}
+       */
+        {0, "", NULL, 0,0,0,NULL,NULL}
     }
 };