268 lines
6.2 KiB
C
268 lines
6.2 KiB
C
#include <stddef.h>
|
|
#include "ui.h"
|
|
#include <string.h>
|
|
#include "adc.h"
|
|
#include "button.h"
|
|
#include "system.h"
|
|
#include "unicore-mx/stm32/gpio.h"
|
|
#include "unicore-mx/stm32/rcc.h"
|
|
#include "pot.h"
|
|
|
|
#define CENTER_X ((int)(52))
|
|
#define CENTER_Y ((int)(50))
|
|
#define NEUTRAL 2
|
|
|
|
struct display_menu *CurrentMenu = &MainMenu;
|
|
|
|
extern volatile uint32_t jiffies;
|
|
static uint32_t drone_xy_gain = 1;
|
|
|
|
static void ui_return(uint8_t press, int hold)
|
|
{
|
|
display_clear(NULL);
|
|
clear_input_callback();
|
|
ui_display_menu(&MainMenu);
|
|
}
|
|
|
|
static void ui_action_interrupt(uint8_t press, int hold)
|
|
{
|
|
if (press == '+') {
|
|
clear_keepalive();
|
|
display_clear(NULL);
|
|
display_text(5, "Interrupted!");
|
|
set_input_callback(ui_return);
|
|
}
|
|
}
|
|
|
|
static void display_drone(int line, uint16_t val)
|
|
{
|
|
char txt[] = "0000";
|
|
if (val >= 1000)
|
|
txt[0] = '0' + val / 1000;
|
|
val %= 1000;
|
|
if (val != 0)
|
|
txt[3] = '0' + val % 10;
|
|
if (val > 9)
|
|
txt[2] = '0' + ((val / 10) % 10);
|
|
if (val > 99)
|
|
txt[1] = '0' + (val / 100);
|
|
display_text(line, txt);
|
|
}
|
|
|
|
static void display_volume(void)
|
|
{
|
|
char txt[4] = "000";
|
|
int master_vol = pot_get_master();
|
|
txt[0] = '0' + master_vol / 100;
|
|
txt[1] = '0' + (master_vol % 100) / 10;
|
|
txt[2] = '0' + (master_vol % 10);
|
|
display_text(6, txt);
|
|
}
|
|
|
|
void ui_drone_xy_poll(void)
|
|
{
|
|
uint16_t x = 0, y = 0;
|
|
char TXT[]="Bender!";
|
|
static uint32_t bend_update = 0;
|
|
int X, Y;
|
|
char bgain[4] = "000";
|
|
rcc_periph_clock_enable(RCC_GPIOA);
|
|
gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1 | GPIO2);
|
|
adc_pin_val(2, &x);
|
|
adc_pin_val(1, &y);
|
|
X = (100 * x) / 4096;
|
|
Y = (100 * y) / 4096;
|
|
if (((X > CENTER_X) && ((X - CENTER_X) > NEUTRAL)) || ((X < CENTER_X) && ((CENTER_X - X) > NEUTRAL))) {
|
|
int off = X - CENTER_X;
|
|
pot_offset(0, off/10);
|
|
}
|
|
if (((Y > CENTER_Y) && ((Y - CENTER_Y) > NEUTRAL)) || ((Y < CENTER_Y) && ((CENTER_Y - Y) > NEUTRAL))) {
|
|
int off = Y - CENTER_Y;
|
|
pot_offset(1, off/10);
|
|
}
|
|
led_beat(((jiffies / 100) % 8) + 1);
|
|
display_text(4, TXT);
|
|
display_drone(5, pot_get(0));
|
|
display_drone(6, pot_get(1));
|
|
bgain[0] = '0' + drone_xy_gain / 100;
|
|
bgain[1] = '0' + (drone_xy_gain % 100) / 10;
|
|
bgain[2] = '0' + (drone_xy_gain % 10);
|
|
display_text(7, bgain);
|
|
}
|
|
|
|
void ui_bender_poll(void)
|
|
{
|
|
uint16_t x = 0, y = 0;
|
|
char TXT[]="Bender!";
|
|
static uint32_t bend_update = 0;
|
|
int X, Y;
|
|
char bgain[4] = "000";
|
|
rcc_periph_clock_enable(RCC_GPIOA);
|
|
gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1 | GPIO2);
|
|
adc_pin_val(2, &x);
|
|
adc_pin_val(1, &y);
|
|
X = (100 * x) / 4096;
|
|
Y = (100 * y) / 4096;
|
|
pot_set(0, X);
|
|
pot_set(1, Y);
|
|
led_beat(((jiffies / 100) % 8) + 1);
|
|
display_text(4, TXT);
|
|
display_drone(5, pot_get(0));
|
|
display_drone(6, pot_get(1));
|
|
bgain[0] = '0' + drone_xy_gain / 100;
|
|
bgain[1] = '0' + (drone_xy_gain % 100) / 10;
|
|
bgain[2] = '0' + (drone_xy_gain % 10);
|
|
display_text(7, bgain);
|
|
}
|
|
|
|
static void ui_gain_input(uint8_t press, int hold)
|
|
{
|
|
if (press == '+') {
|
|
display_clear(NULL);
|
|
display_text(5, "Interrupted!");
|
|
clear_keepalive();
|
|
set_input_callback(ui_return);
|
|
return;
|
|
}
|
|
if (press == 'U') {
|
|
if (drone_xy_gain < 10)
|
|
drone_xy_gain++;
|
|
}
|
|
if (press == 'D') {
|
|
if (drone_xy_gain > 0)
|
|
drone_xy_gain--;
|
|
}
|
|
ui_drone_xy_poll();
|
|
}
|
|
|
|
|
|
static void ui_drone_xy(const void *arg)
|
|
{
|
|
set_input_callback(ui_gain_input);
|
|
set_keepalive(ui_drone_xy_poll);
|
|
display_clear(NULL);
|
|
ui_drone_xy_poll();
|
|
}
|
|
|
|
static void ui_bender(const void *arg)
|
|
{
|
|
set_input_callback(ui_gain_input);
|
|
set_keepalive(ui_bender_poll);
|
|
display_clear(NULL);
|
|
ui_bender_poll();
|
|
}
|
|
|
|
|
|
static void ui_mastervol_input(uint8_t press, int hold)
|
|
{
|
|
int master_vol = pot_get_master();
|
|
if (press == 'U')
|
|
if (master_vol < 1000)
|
|
pot_set_master(master_vol + 5);
|
|
|
|
if (press == 'D') {
|
|
if (master_vol > 4)
|
|
pot_set_master(master_vol - 5);
|
|
}
|
|
if (press == '+') {
|
|
display_clear(NULL);
|
|
clear_input_callback();
|
|
ui_display_menu(&MainMenu);
|
|
return;
|
|
}
|
|
display_text(5, "Master Volume");
|
|
display_volume();
|
|
}
|
|
|
|
static void ui_mastervol(const void *arg)
|
|
{
|
|
set_input_callback(ui_mastervol_input);
|
|
display_clear(NULL);
|
|
display_text(5, "Master Volume");
|
|
display_volume();
|
|
}
|
|
|
|
|
|
static void ui_bytebeat_input(uint8_t press, int hold) {
|
|
if (press == '+') {
|
|
display_clear(NULL);
|
|
clear_input_callback();
|
|
clear_keepalive();
|
|
ui_display_menu(&MainMenu);
|
|
}
|
|
}
|
|
|
|
#define PLAY_SIZE 512
|
|
|
|
static uint8_t bb_buffer[PLAY_SIZE];
|
|
|
|
void ui_bytebeat_keepalive(void)
|
|
{
|
|
static uint32_t t = 0;
|
|
int r = 0;
|
|
if (dac_space() >= PLAY_SIZE) {
|
|
for(;;t++) {
|
|
bb_buffer[r++] = (t<<1)|(t>>4)*(((t>>12)|(t>>13)|(t>>6) | ((t>>2)|(t>>4))|(t<<1)|(t<<12)|((t<<5)&~(t>>22))));
|
|
if (r >= PLAY_SIZE) {
|
|
dac_write(bb_buffer, r);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ui_bytebeat(const void *arg)
|
|
{
|
|
set_input_callback(ui_bytebeat_input);
|
|
display_clear(NULL);
|
|
display_text(5, " Bytebeat! ");
|
|
set_keepalive(ui_bytebeat_keepalive);
|
|
}
|
|
|
|
|
|
static void ui_submenu(const void *arg)
|
|
{
|
|
ui_display_menu(arg);
|
|
}
|
|
|
|
const struct display_menu PatternMenu = {
|
|
.entry_n = 1,
|
|
.entry = {
|
|
{ "TODO! ", ui_submenu, &MainMenu},
|
|
{ "", NULL, NULL}
|
|
}
|
|
};
|
|
|
|
const struct display_menu DroneMenu = {
|
|
.entry_n = 2,
|
|
.entry = {
|
|
{ "Drone X, Y ", ui_drone_xy, NULL},
|
|
{ "Bender ", ui_bender, NULL},
|
|
{ "", NULL, NULL}
|
|
}
|
|
};
|
|
|
|
const struct display_menu SettingsMenu = {
|
|
.entry_n = 1,
|
|
.entry = {
|
|
{ "TODO", ui_submenu, &MainMenu },
|
|
{ "", NULL, NULL}
|
|
}
|
|
};
|
|
|
|
const struct display_menu MainMenu = {
|
|
.entry_n = 5,
|
|
.entry = {
|
|
{ "Master Volume ", ui_mastervol, NULL },
|
|
{ "Settings ", ui_submenu, &SettingsMenu },
|
|
{ "Pattern ", ui_submenu, &PatternMenu },
|
|
{ "Drone ", ui_submenu, &DroneMenu},
|
|
{ "Bytebeat ", ui_bytebeat },
|
|
{ "", NULL, NULL}
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
|