Added storage for pattern and settings
This commit is contained in:
parent
b43948ded3
commit
e3d1ff9c0d
18 changed files with 331 additions and 99 deletions
3
Makefile
3
Makefile
|
@ -5,7 +5,8 @@ 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 settings.o ui_pattern.o
|
||||
mutex.o ui_drone.o adc.o spi.o pot.o dac.o sound.o drone.o settings.o ui_pattern.o \
|
||||
flash.o
|
||||
|
||||
|
||||
UMX:=lib/unicore-mx/lib/libucmx_stm32f4.a
|
||||
|
|
28
drone.c
28
drone.c
|
@ -19,27 +19,6 @@
|
|||
|
||||
#define MUTE { 0 , 0 }
|
||||
|
||||
static struct drone_slot drone_pattern[MAX_PATTERN_LEN] = {
|
||||
{ 28, 10 }, { 28, 20}, {36,20}, {40,20},
|
||||
{ 40, 10 }, { 40, 10}, {36, 10}, {32,10},
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
MUTE, MUTE, MUTE, MUTE,
|
||||
};
|
||||
|
||||
void drone_mute(void)
|
||||
{
|
||||
|
@ -51,13 +30,17 @@ void drone_mute(void)
|
|||
|
||||
void drone_beat(int pattern_pos)
|
||||
{
|
||||
struct drone_slot *key = &drone_pattern[pattern_pos];
|
||||
static int test_lfo_step = 0;
|
||||
static int test_lfo = 0;
|
||||
int lfo_depth = 80;
|
||||
int lfo_rate = 7;
|
||||
int lfo_step = 2;
|
||||
int tgt_env;
|
||||
static struct drone_slot *pattern;
|
||||
struct drone_slot *key;
|
||||
pattern = Settings->drone[Settings->current_pattern].data;
|
||||
key = &pattern[pattern_pos];
|
||||
|
||||
if ((key->pitch == 0) && (key->env == 0)) {
|
||||
pot_set(0, 99);
|
||||
pot_set(1, 0);
|
||||
|
@ -93,7 +76,6 @@ void drone_beat(int pattern_pos)
|
|||
tgt_env = 99;
|
||||
test_lfo_step = 1;
|
||||
}
|
||||
|
||||
pot_set(0, key->pitch);
|
||||
pot_set(1, tgt_env);
|
||||
}
|
||||
|
|
6
drone.h
6
drone.h
|
@ -2,11 +2,9 @@
|
|||
#ifndef DRONE_H_INCLUDED
|
||||
#define DRONE_H_INCLUDED
|
||||
#include <stdint.h>
|
||||
#include "settings.h"
|
||||
|
||||
void drone_mute(void);
|
||||
void drone_select_pattern(struct drone_pattern *p);
|
||||
|
||||
struct __attribute__((packed)) drone_slot {
|
||||
uint8_t pitch;
|
||||
uint8_t env;
|
||||
};
|
||||
#endif
|
||||
|
|
27
drums.c
27
drums.c
|
@ -17,8 +17,7 @@
|
|||
|
||||
#define TRACKS 8
|
||||
|
||||
//static uint32_t pattern[MAX_PATTERN_LEN] = { DRUMS_KICK, DRUMS_HIHAT, DRUMS_SNARE, DRUMS_HIHAT, DRUMS_KICK, DRUMS_KICK, DRUMS_SNARE, DRUMS_HIHAT };
|
||||
static uint32_t pattern[MAX_PATTERN_LEN] = { DRUMS_KICK, DRUMS_KICK, DRUMS_CLAP, 0, 0, DRUMS_KICK, 0};
|
||||
static struct drums_pattern *pattern = NULL;
|
||||
static uint32_t pattern_len = 8;
|
||||
static uint32_t pattern_pos = 0;
|
||||
static unsigned char *dsample[TRACKS] = {};
|
||||
|
@ -26,9 +25,11 @@ static unsigned int dsample_len[TRACKS] = {};
|
|||
|
||||
static void beat_cb(uint32_t b)
|
||||
{
|
||||
uint32_t key = pattern[pattern_pos];
|
||||
int i;
|
||||
drone_beat(pattern_pos);
|
||||
uint32_t key;
|
||||
pattern = &Settings->drums[Settings->current_pattern];
|
||||
//drone_beat(pattern_pos);
|
||||
key = pattern->data[pattern_pos];
|
||||
for (i = 0; i < TRACKS; i++) {
|
||||
if ((key & (1 << i)) == (1 << i)) {
|
||||
if (dsample[i]) {
|
||||
|
@ -40,7 +41,7 @@ static void beat_cb(uint32_t b)
|
|||
}
|
||||
}
|
||||
pattern_pos++;
|
||||
if (pattern_pos >= Settings.pattern_len) {
|
||||
if (pattern_pos >= pattern->len) {
|
||||
pattern_pos = 0;
|
||||
}
|
||||
led_beat((pattern_pos % 8) + 1);
|
||||
|
@ -82,23 +83,21 @@ void drums_stop(void)
|
|||
timer_clear_beat_callback();
|
||||
}
|
||||
|
||||
void drums_set_pattern_len(int l)
|
||||
{
|
||||
Settings.pattern_len = l;
|
||||
timer_set_beat(1);
|
||||
}
|
||||
|
||||
void drums_set(uint32_t track, int pos)
|
||||
{
|
||||
pattern[pos] |= (1 << track);
|
||||
pattern = Settings->drums[Settings->current_pattern].data;
|
||||
pattern->data[pos] |= (1 << track);
|
||||
}
|
||||
|
||||
void drums_clear(uint32_t track, int pos)
|
||||
{
|
||||
pattern[pos] &= ~(1 << track);
|
||||
pattern = Settings->drums[Settings->current_pattern].data;
|
||||
pattern->data[pos] &= ~(1 << track);
|
||||
}
|
||||
|
||||
int drums_get(uint32_t track, int pos)
|
||||
{
|
||||
return (!!(pattern[pos] & (1 << track)));
|
||||
pattern = Settings->drums[Settings->current_pattern].data;
|
||||
return (!!(pattern->data[pos] & (1 << track)));
|
||||
}
|
||||
|
||||
|
|
3
drums.h
3
drums.h
|
@ -2,14 +2,15 @@
|
|||
#define DRUMS_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include "settings.h"
|
||||
void drums_init(void);
|
||||
void drums_start(void);
|
||||
void drums_stop(void);
|
||||
void drums_set_pattern_len(int l);
|
||||
int drums_get(uint32_t track, int pos);
|
||||
void drums_set(uint32_t track, int pos);
|
||||
void drums_clear(uint32_t track, int pos);
|
||||
void drums_oneshot(int track);
|
||||
void drums_select_pattern(struct drums_pattern *p);
|
||||
|
||||
#define DRUMS_KICK (1 << 0)
|
||||
#define DRUMS_HIHAT (1 << 1)
|
||||
|
|
122
flash.c
Normal file
122
flash.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* stm32f4.c
|
||||
*
|
||||
* Copyright (C) 2020 Danielinux
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "system.h"
|
||||
|
||||
/* STM32F4 FLASH Geometry */
|
||||
#define FLASH_SECTOR_0 0x0000000 /* 16 Kb */
|
||||
#define FLASH_SECTOR_1 0x0004000 /* 16 Kb */
|
||||
#define FLASH_SECTOR_2 0x0008000 /* 16 Kb */
|
||||
#define FLASH_SECTOR_3 0x000C000 /* 16 Kb */
|
||||
#define FLASH_SECTOR_4 0x0010000 /* 64 Kb */
|
||||
#define FLASH_SECTOR_5 0x0020000 /* 128 Kb */
|
||||
#define FLASH_SECTOR_6 0x0040000 /* 128 Kb */
|
||||
#define FLASH_SECTOR_7 0x0060000 /* 128 Kb */
|
||||
#define FLASH_SECTOR_8 0x0080000 /* 128 Kb */
|
||||
#define FLASH_SECTOR_9 0x00A0000 /* 128 Kb */
|
||||
#define FLASH_SECTOR_10 0x00C0000 /* 128 Kb */
|
||||
#define FLASH_SECTOR_11 0x00E0000 /* 128 Kb */
|
||||
#define FLASH_TOP 0x0100000
|
||||
|
||||
#define FLASH_SECTORS 12
|
||||
const uint32_t flash_sector[FLASH_SECTORS + 1] = {
|
||||
FLASH_SECTOR_0,
|
||||
FLASH_SECTOR_1,
|
||||
FLASH_SECTOR_2,
|
||||
FLASH_SECTOR_3,
|
||||
FLASH_SECTOR_4,
|
||||
FLASH_SECTOR_5,
|
||||
FLASH_SECTOR_6,
|
||||
FLASH_SECTOR_7,
|
||||
FLASH_SECTOR_8,
|
||||
FLASH_SECTOR_9,
|
||||
FLASH_SECTOR_10,
|
||||
FLASH_SECTOR_11,
|
||||
FLASH_TOP
|
||||
};
|
||||
|
||||
static void flash_wait_complete(void)
|
||||
{
|
||||
while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY)
|
||||
;
|
||||
}
|
||||
|
||||
static void flash_erase_sector(uint32_t sec)
|
||||
{
|
||||
uint32_t reg = FLASH_CR & (~(FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT));
|
||||
FLASH_CR = reg | (sec & FLASH_CR_SNB_MASK) << FLASH_CR_SNB_SHIFT;
|
||||
FLASH_CR |= FLASH_CR_SER;
|
||||
FLASH_CR |= FLASH_CR_STRT;
|
||||
flash_wait_complete();
|
||||
FLASH_CR &= ~FLASH_CR_SER;
|
||||
FLASH_CR &= ~(FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT);
|
||||
}
|
||||
|
||||
static void clear_errors(void)
|
||||
{
|
||||
FLASH_SR |= ( FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR | FLASH_SR_WRPERR | FLASH_SR_OPERR | FLASH_SR_EOP );
|
||||
}
|
||||
|
||||
int flash_write(uint32_t address, const uint8_t *data, int len)
|
||||
{
|
||||
int i;
|
||||
uint32_t val;
|
||||
flash_wait_complete();
|
||||
clear_errors();
|
||||
/* Set 8-bit write */
|
||||
FLASH_CR &= (~(0x03 << 8));
|
||||
for (i = 0; i < len; i++) {
|
||||
FLASH_CR |= FLASH_CR_PG;
|
||||
*((uint8_t *)(address + i)) = data[i];
|
||||
flash_wait_complete();
|
||||
FLASH_CR &= ~FLASH_CR_PG;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void flash_unlock(void)
|
||||
{
|
||||
FLASH_CR |= FLASH_CR_LOCK;
|
||||
FLASH_KEYR = FLASH_KEY1;
|
||||
FLASH_KEYR = FLASH_KEY2;
|
||||
}
|
||||
|
||||
void flash_lock(void)
|
||||
{
|
||||
FLASH_CR |= FLASH_CR_LOCK;
|
||||
}
|
||||
|
||||
|
||||
int flash_erase(uint32_t address, int len)
|
||||
{
|
||||
int start = -1, end = -1;
|
||||
uint32_t end_address;
|
||||
int i;
|
||||
if (len == 0)
|
||||
return -1;
|
||||
end_address = address + len - 1;
|
||||
|
||||
if (address < flash_sector[0] || end_address > FLASH_TOP)
|
||||
return -1;
|
||||
for (i = 0; i < FLASH_SECTORS; i++)
|
||||
{
|
||||
if ((address >= flash_sector[i]) && (address < flash_sector[i + 1])) {
|
||||
start = i;
|
||||
}
|
||||
if ((end_address >= flash_sector[i]) && (end_address < flash_sector[i + 1])) {
|
||||
end = i;
|
||||
}
|
||||
if (start > 0 && end > 0)
|
||||
break;
|
||||
}
|
||||
if (start < 0 || end < 0)
|
||||
return -1;
|
||||
for (i = start; i <= end; i++)
|
||||
flash_erase_sector(i);
|
||||
return 0;
|
||||
}
|
||||
|
10
flash.h
Normal file
10
flash.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef FLASH_H_INCLUDED
|
||||
#define FLASH_H_INCLUDED
|
||||
#include <stdint.h>
|
||||
|
||||
int flash_write(uint32_t address, const uint8_t *data, int len);
|
||||
void flash_unlock(void);
|
||||
void flash_lock(void);
|
||||
int flash_erase(uint32_t address, int len);
|
||||
#endif
|
||||
|
1
main.c
1
main.c
|
@ -34,6 +34,7 @@ static void bootlevel_0(void)
|
|||
uart2_setup(115200, 8, 0, 1);
|
||||
systick_enable();
|
||||
WFI();
|
||||
settings_load();
|
||||
printf("Console on USART2 Enabled.\r\n");
|
||||
printf("\r\n=====================\r\n");
|
||||
printf("Entering bootlevel 0.\r\n");
|
||||
|
|
4
pot.c
4
pot.c
|
@ -109,7 +109,7 @@ void pot_init(void)
|
|||
|
||||
void pot_sync(int p)
|
||||
{
|
||||
pot_set(p, Settings.levels[p]);
|
||||
pot_set(p, Settings->levels[p]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,7 +130,7 @@ void pot_set(int p, int val)
|
|||
if (val > 100)
|
||||
val = 100;
|
||||
|
||||
Settings.levels[p] = val;
|
||||
Settings->levels[p] = val;
|
||||
|
||||
off = val - old;
|
||||
if (off == 0)
|
||||
|
|
40
settings.c
40
settings.c
|
@ -1,7 +1,39 @@
|
|||
#include <string.h>
|
||||
#include "settings.h"
|
||||
#include "flash.h"
|
||||
|
||||
struct settings Settings = {
|
||||
.bpm = 125,
|
||||
.pattern_len = 16,
|
||||
|
||||
};
|
||||
#define RAM_SETTINGS (0x20012000)
|
||||
#define FLASH_SETTINGS (0x0E0000)
|
||||
#define SETTINGS_PART_SIZE (0x20000) /* 128 KB */
|
||||
|
||||
struct settings *Settings = (struct settings *)(RAM_SETTINGS);
|
||||
|
||||
|
||||
|
||||
void settings_save(void)
|
||||
{
|
||||
flash_unlock();
|
||||
flash_erase(FLASH_SETTINGS, SETTINGS_PART_SIZE);
|
||||
flash_write(FLASH_SETTINGS, (const void *)(RAM_SETTINGS), sizeof(struct settings));
|
||||
flash_lock();
|
||||
}
|
||||
|
||||
static void restore_defaults(void)
|
||||
{
|
||||
memset(Settings, 0, sizeof(struct settings));
|
||||
Settings->storage_hdr = STORAGE_HDR;
|
||||
Settings->bpm = 125;
|
||||
settings_save();
|
||||
}
|
||||
|
||||
|
||||
void settings_load(void)
|
||||
{
|
||||
struct settings *s = (struct settings *)FLASH_SETTINGS;
|
||||
if (s->storage_hdr != STORAGE_HDR) {
|
||||
restore_defaults();
|
||||
return;
|
||||
}
|
||||
memcpy((void *)RAM_SETTINGS, (const void *)FLASH_SETTINGS, sizeof(struct settings));
|
||||
}
|
||||
|
|
28
settings.h
28
settings.h
|
@ -5,14 +5,38 @@
|
|||
|
||||
#define MAX_PATTERN_LEN 64
|
||||
#define MAX_TRACKS 8
|
||||
#define MAX_PATTERNS 32
|
||||
|
||||
|
||||
#define STORAGE_HDR (0xDA1EDA1E)
|
||||
struct settings;
|
||||
extern struct settings *Settings;
|
||||
|
||||
|
||||
struct __attribute__((packed)) drone_slot {
|
||||
uint8_t pitch;
|
||||
uint8_t env;
|
||||
};
|
||||
|
||||
struct settings {
|
||||
uint32_t storage_hdr;
|
||||
int levels[NUM_POTS];
|
||||
#define master_vol levels[2]
|
||||
int bpm;
|
||||
int beatcount;
|
||||
int sequencer_on;
|
||||
int pattern_len;
|
||||
int current_pattern;
|
||||
struct drums_pattern {
|
||||
uint32_t len;
|
||||
uint32_t data[MAX_PATTERN_LEN];
|
||||
} drums[MAX_PATTERNS];
|
||||
struct drone_pattern {
|
||||
struct drone_slot data[MAX_PATTERN_LEN];
|
||||
} drone[MAX_PATTERNS];
|
||||
};
|
||||
|
||||
extern struct settings Settings;
|
||||
|
||||
void settings_load(void);
|
||||
void settings_save(void);
|
||||
|
||||
#endif
|
||||
|
|
37
system.h
37
system.h
|
@ -154,9 +154,46 @@ static inline void nvic_irq_clear(uint8_t n)
|
|||
/*** FLASH ***/
|
||||
#define FLASH_BASE (0x40023C00)
|
||||
#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00))
|
||||
#define FLASH_KEYR (*(volatile uint32_t *)(FLASH_BASE + 0x04))
|
||||
#define FLASH_SR (*(volatile uint32_t *)(FLASH_BASE + 0x0C))
|
||||
#define FLASH_CR (*(volatile uint32_t *)(FLASH_BASE + 0x10))
|
||||
#define FLASH_ACR_ENABLE_DATA_CACHE (1 << 10)
|
||||
#define FLASH_ACR_ENABLE_INST_CACHE (1 << 9)
|
||||
|
||||
/* Register values */
|
||||
#define FLASH_ACR_RESET_DATA_CACHE (1 << 12)
|
||||
#define FLASH_ACR_RESET_INST_CACHE (1 << 11)
|
||||
#define FLASH_ACR_ENABLE_DATA_CACHE (1 << 10)
|
||||
#define FLASH_ACR_ENABLE_INST_CACHE (1 << 9)
|
||||
#define FLASH_ACR_ENABLE_PRFT (1 << 8)
|
||||
|
||||
#define FLASH_SR_BSY (1 << 16)
|
||||
#define FLASH_SR_PGSERR (1 << 7)
|
||||
#define FLASH_SR_PGPERR (1 << 6)
|
||||
#define FLASH_SR_PGAERR (1 << 5)
|
||||
#define FLASH_SR_WRPERR (1 << 4)
|
||||
#define FLASH_SR_OPERR (1 << 1)
|
||||
#define FLASH_SR_EOP (1 << 0)
|
||||
|
||||
#define FLASH_CR_LOCK (1 << 31)
|
||||
#define FLASH_CR_ERRIE (1 << 25)
|
||||
#define FLASH_CR_EOPIE (1 << 24)
|
||||
#define FLASH_CR_STRT (1 << 16)
|
||||
#define FLASH_CR_MER (1 << 2)
|
||||
#define FLASH_CR_SER (1 << 1)
|
||||
#define FLASH_CR_PG (1 << 0)
|
||||
|
||||
#define FLASH_CR_SNB_SHIFT 3
|
||||
#define FLASH_CR_SNB_MASK 0x1f
|
||||
|
||||
#define FLASH_CR_PROGRAM_X8 (0 << 8)
|
||||
#define FLASH_CR_PROGRAM_X16 (1 << 8)
|
||||
#define FLASH_CR_PROGRAM_X32 (2 << 8)
|
||||
#define FLASH_CR_PROGRAM_X64 (3 << 8)
|
||||
|
||||
#define FLASH_KEY1 (0x45670123)
|
||||
#define FLASH_KEY2 (0xCDEF89AB)
|
||||
|
||||
/*** SPI ***/
|
||||
#define SPI1 (0x40013000)
|
||||
#define SPI1_CR1 (*(volatile uint32_t *)(SPI1))
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K - 0x100
|
||||
RAM (rw) : ORIGIN = 0x20001000, LENGTH = 252K
|
||||
RAM_S (rw) : ORIGIN = 0x20000000, LENGTH = 4K
|
||||
RAM (rw) : ORIGIN = 0x20001000, LENGTH = 64K
|
||||
RAM_SETTINGS (rw) : ORIGIN = 0x2012000, LENGTH = 60K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
|
@ -25,6 +26,7 @@ SECTIONS
|
|||
|
||||
_stored_data = .;
|
||||
|
||||
|
||||
.data : AT (_stored_data)
|
||||
{
|
||||
_start_data = .;
|
||||
|
@ -43,6 +45,11 @@ SECTIONS
|
|||
_end = .;
|
||||
} > RAM
|
||||
|
||||
.settings :
|
||||
{
|
||||
*(.settings*)
|
||||
} > RAM_SETTINGS
|
||||
|
||||
}
|
||||
|
||||
PROVIDE(_start_heap = _end);
|
||||
|
|
2
timer.c
2
timer.c
|
@ -27,7 +27,7 @@ int timer_set_bpm(void)
|
|||
uint32_t psc = 1;
|
||||
uint32_t err = 0;
|
||||
uint32_t reg = 0;
|
||||
uint32_t clock = (cpu_freq / (4 * Settings.bpm)) * (S_PER_MINUTE);;
|
||||
uint32_t clock = (cpu_freq / (4 * Settings->bpm)) * (S_PER_MINUTE);;
|
||||
|
||||
while (psc < 65535) {
|
||||
val = clock / psc;
|
||||
|
|
4
ui.c
4
ui.c
|
@ -84,6 +84,7 @@ void ui_menu_autoscroll(void)
|
|||
display_scroll(NULL, display_cur_v);
|
||||
}
|
||||
|
||||
extern struct display_menu MainMenu;
|
||||
static void ui_display_menu_refresh(void)
|
||||
{
|
||||
const struct display_menu *menu = CurrentMenu;
|
||||
|
@ -92,7 +93,8 @@ static void ui_display_menu_refresh(void)
|
|||
char txt[16];
|
||||
display_scroll(NULL, display_cur_v);
|
||||
display_clear(NULL);
|
||||
|
||||
if (menu->render)
|
||||
menu->render(menu);
|
||||
for (i = 0; i < menu->entry_n; i++) {
|
||||
vline = i + 4;
|
||||
if (vline > 7)
|
||||
|
|
5
ui.h
5
ui.h
|
@ -24,12 +24,9 @@ struct display_menu {
|
|||
int *var;
|
||||
const void *arg;
|
||||
} entry[MAX_ENTRY];
|
||||
|
||||
void (*render)(struct display_menu *menu);
|
||||
};
|
||||
|
||||
const struct display_menu MainMenu, MeasureMenu, SignalGenMenu,
|
||||
ExtraMenu;
|
||||
|
||||
void ui_display_menu(const struct display_menu *menu);
|
||||
void ui_button_press(uint8_t b, int hold);
|
||||
|
||||
|
|
83
ui_drone.c
83
ui_drone.c
|
@ -15,6 +15,32 @@
|
|||
#define CENTER_Y ((int)(50))
|
||||
#define NEUTRAL 2
|
||||
|
||||
static void ui_sequencer_action(struct display_menu_entry *e, uint8_t b);
|
||||
static void ui_master_action(struct display_menu_entry *e, uint8_t b);
|
||||
static void ui_bpm_action(struct display_menu_entry *e, uint8_t b);
|
||||
static void ui_pattern_save_action(struct display_menu_entry *e, uint8_t b);
|
||||
static void main_menu_prepare(struct display_menu *m);
|
||||
extern struct display_menu PatternMenu;
|
||||
|
||||
static void ui_submenu_action(struct display_menu_entry *e, uint8_t b)
|
||||
{
|
||||
ui_display_menu(e->arg);
|
||||
}
|
||||
|
||||
struct display_menu MainMenu = {
|
||||
.entry_n = 7,
|
||||
.render = main_menu_prepare,
|
||||
.entry = {
|
||||
{ ENTRY_TYPE_BOOL, "Sequencer", ui_sequencer_action, .min = 0, .max = 0, .step = 0, NULL, .arg = NULL },
|
||||
{ ENTRY_TYPE_DEC, "Volume: ", ui_master_action, 0, 100, 2, NULL, NULL },
|
||||
{ ENTRY_TYPE_DEC, "BPM: ", ui_bpm_action, 30, 300, 1, NULL, NULL },
|
||||
{ ENTRY_TYPE_DEC, "Pattern :", NULL, 0, MAX_PATTERNS, 1, NULL, NULL },
|
||||
{ ENTRY_TYPE_DEC, "Pattern Len:", NULL, 8, MAX_PATTERN_LEN, 8, NULL, NULL },
|
||||
{ ENTRY_TYPE_TEXT, "Edit Pattern", ui_submenu_action, 0, 0, 0, NULL, &PatternMenu},
|
||||
{ ENTRY_TYPE_TEXT, "Save Pattern", ui_pattern_save_action, 0, 0, 0, NULL, NULL},
|
||||
}
|
||||
};
|
||||
|
||||
struct display_menu *CurrentMenu = &MainMenu;
|
||||
|
||||
extern volatile uint32_t jiffies;
|
||||
|
@ -197,6 +223,8 @@ static void ui_bpm_input(uint8_t press, int hold)
|
|||
timer_stop();
|
||||
timer_set_bpm();
|
||||
led_beat(1);
|
||||
settings_save();
|
||||
timer_set_beat(1);
|
||||
timer_set_beat(1);
|
||||
timer_start();
|
||||
}
|
||||
|
@ -207,6 +235,7 @@ static void ui_bpm_input(uint8_t press, int hold)
|
|||
timer_stop();
|
||||
timer_set_bpm(sys_bpm - 1);
|
||||
led_beat(1);
|
||||
settings_save();
|
||||
timer_set_beat(1);
|
||||
timer_start();
|
||||
}
|
||||
|
@ -266,16 +295,6 @@ static void ui_bytebeat(const void *arg)
|
|||
set_keepalive(ui_bytebeat_keepalive);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const struct display_menu PatternMenu = {
|
||||
.entry_n = 1,
|
||||
.entry = {
|
||||
{ "TODO! ", ui_submenu, &MainMenu},
|
||||
{ "", NULL, NULL}
|
||||
}
|
||||
};
|
||||
|
||||
const struct display_menu DroneMenu = {
|
||||
.entry_n = 2,
|
||||
.entry = {
|
||||
|
@ -295,14 +314,10 @@ const struct display_menu SettingsMenu = {
|
|||
|
||||
#endif
|
||||
|
||||
static void ui_submenu_action(struct display_menu_entry *e, uint8_t b)
|
||||
{
|
||||
ui_display_menu(e->arg);
|
||||
}
|
||||
|
||||
static void ui_sequencer_action(struct display_menu_entry *e, uint8_t b)
|
||||
{
|
||||
if (Settings.sequencer_on) {
|
||||
if (Settings->sequencer_on) {
|
||||
timer_set_beat(1);
|
||||
timer_start();
|
||||
} else {
|
||||
|
@ -326,23 +341,27 @@ static void ui_bpm_action(struct display_menu_entry *e, uint8_t b)
|
|||
timer_start();
|
||||
}
|
||||
|
||||
static void ui_pattern_save_action(struct display_menu_entry *e, uint8_t b)
|
||||
{
|
||||
display_clear();
|
||||
display_scroll(NULL, 0);
|
||||
display_text(5, "Saving to FLASH");
|
||||
settings_save();
|
||||
ui_display_menu(&MainMenu);
|
||||
}
|
||||
|
||||
|
||||
static void main_menu_prepare(struct display_menu *m)
|
||||
{
|
||||
if (m != &MainMenu)
|
||||
return;
|
||||
MainMenu.entry[0].var = &Settings->sequencer_on;
|
||||
MainMenu.entry[1].var = &Settings->levels[2];
|
||||
MainMenu.entry[2].var = &Settings->bpm;
|
||||
MainMenu.entry[3].var = &Settings->current_pattern;
|
||||
MainMenu.entry[4].var = &(Settings->drums[Settings->current_pattern].len);
|
||||
}
|
||||
|
||||
|
||||
extern void ui_pattern_menu_action(struct display_menu_entry *e, uint8_t b);
|
||||
extern struct display_menu PatternMenu;
|
||||
const struct display_menu MainMenu = {
|
||||
.entry_n = 5,
|
||||
.entry = {
|
||||
/* 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 },
|
||||
{ ENTRY_TYPE_DEC, "Pattern Len:", NULL, 8, MAX_PATTERN_LEN, 8, &Settings.pattern_len, NULL },
|
||||
{ ENTRY_TYPE_TEXT, "Edit Pattern", ui_pattern_menu_action, 0, 0, 0, NULL, &PatternMenu},
|
||||
{0, "", NULL, 0,0,0,NULL,NULL}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
14
ui_pattern.c
14
ui_pattern.c
|
@ -51,6 +51,7 @@ void ui_pattern_keepalive(void)
|
|||
}
|
||||
}
|
||||
|
||||
extern struct display_menu MainMenu;
|
||||
void ui_pattern_menu_return_to_main(struct display_menu_entry *e, uint8_t b)
|
||||
{
|
||||
display_clear(NULL);
|
||||
|
@ -60,8 +61,10 @@ void ui_pattern_menu_return_to_main(struct display_menu_entry *e, uint8_t b)
|
|||
ui_display_menu(&MainMenu);
|
||||
}
|
||||
|
||||
static void pattern_menu_prepare(struct display_menu *m);
|
||||
struct display_menu PatternMenu = {
|
||||
.entry_n = 4,
|
||||
.render = pattern_menu_prepare,
|
||||
.entry = {
|
||||
/* TYPE, label, action, min, max, var, arg */
|
||||
{ ENTRY_TYPE_DEC, "Track: ", ui_pattern_refresh_action, 0, (MAX_TRACKS - 1), 1, &sel_track, NULL },
|
||||
|
@ -98,16 +101,13 @@ const char instr_txt[MAX_TRACKS][14] = {
|
|||
"",
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void ui_pattern_menu_action(struct display_menu_entry *e, uint8_t b)
|
||||
static void pattern_menu_prepare(struct display_menu *m)
|
||||
{
|
||||
PatternMenu.entry[1].max = Settings.pattern_len;
|
||||
if (m != &PatternMenu)
|
||||
return;
|
||||
PatternMenu.entry[1].max = Settings->drums[Settings->current_pattern].len;
|
||||
sel_val = drums_get(sel_track, sel_pos - 1);
|
||||
ui_display_menu(e->arg);
|
||||
set_keepalive(ui_pattern_keepalive);
|
||||
set_input_callback(ui_pattern_input);
|
||||
ui_pattern_refresh_action(e, b);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue