mirror of
https://github.com/jhbruhn/eurorack.git
synced 2025-03-15 02:55:49 +00:00
Implement ui stuff
This commit is contained in:
parent
77d8c2d97e
commit
e9368dd5a5
7 changed files with 223 additions and 8 deletions
6
midi2cv/.lvimrc
Normal file
6
midi2cv/.lvimrc
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
:packadd termdebug
|
||||||
|
|
||||||
|
let termdebugger = "/usr/bin/arm-none-eabi-gdb"
|
||||||
|
:map <c-d> :Termdebug /home/jhbruhn/eurorack/eurorack-dev-environment/eurorack-modules/build/midi2cv/midi2cv.elf --eval-command='target remote localhost:3333'
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ u8g2_t* Display::u8g2()
|
||||||
return &u8g2_;
|
return &u8g2_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitSPI(void);
|
|
||||||
|
|
||||||
void Display::Init()
|
void Display::Init()
|
||||||
{
|
{
|
||||||
// init SS/CS/RST GPIO
|
// init SS/CS/RST GPIO
|
||||||
|
|
56
midi2cv/drivers/encoder.cc
Normal file
56
midi2cv/drivers/encoder.cc
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2013 Emilie Gillet.
|
||||||
|
//
|
||||||
|
// Author: Emilie Gillet (emilie.o.gillet@gmail.com)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// See http://creativecommons.org/licenses/MIT/ for more information.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Driver for rotary encoder.
|
||||||
|
|
||||||
|
#include "midi2cv/drivers/encoder.h"
|
||||||
|
|
||||||
|
|
||||||
|
void Encoder::Init() {
|
||||||
|
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
|
||||||
|
|
||||||
|
|
||||||
|
GPIO_InitTypeDef gpio_init;
|
||||||
|
|
||||||
|
gpio_init.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
|
||||||
|
gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
|
||||||
|
gpio_init.GPIO_Mode = GPIO_Mode_IN;
|
||||||
|
gpio_init.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOC, &gpio_init);
|
||||||
|
|
||||||
|
switch_state_ = 0xff;
|
||||||
|
quadrature_decoding_state_[0] = quadrature_decoding_state_[1] = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Encoder::Debounce() {
|
||||||
|
switch_state_ = (switch_state_ << 1) | \
|
||||||
|
GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15);
|
||||||
|
quadrature_decoding_state_[0] = (quadrature_decoding_state_[0] << 1) | \
|
||||||
|
GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13);
|
||||||
|
quadrature_decoding_state_[1] = (quadrature_decoding_state_[1] << 1) | \
|
||||||
|
GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_14);
|
||||||
|
}
|
||||||
|
|
82
midi2cv/drivers/encoder.h
Normal file
82
midi2cv/drivers/encoder.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright 2013 Emilie Gillet.
|
||||||
|
//
|
||||||
|
// Author: Emilie Gillet (emilie.o.gillet@gmail.com)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// See http://creativecommons.org/licenses/MIT/ for more information.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Driver for rotary encoder.
|
||||||
|
|
||||||
|
#ifndef YARNS_DRIVERS_ENCODER_H_
|
||||||
|
#define YARNS_DRIVERS_ENCODER_H_
|
||||||
|
|
||||||
|
#include <stm32f37x_conf.h>
|
||||||
|
#include "stmlib/stmlib.h"
|
||||||
|
|
||||||
|
class Encoder {
|
||||||
|
public:
|
||||||
|
Encoder() { }
|
||||||
|
~Encoder() { }
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Debounce();
|
||||||
|
|
||||||
|
inline bool released() const {
|
||||||
|
return switch_state_ == 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool just_pressed() const {
|
||||||
|
return switch_state_ == 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool pressed() const {
|
||||||
|
return switch_state_ == 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool pressed_immediate() const {
|
||||||
|
return !GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t increment() const {
|
||||||
|
int32_t increment = 0;
|
||||||
|
uint8_t a = quadrature_decoding_state_[0];
|
||||||
|
uint8_t b = quadrature_decoding_state_[1];
|
||||||
|
if ((a & 0x03) == 0x02 && (b & 0x03) == 0x00) {
|
||||||
|
increment = -1;
|
||||||
|
} else {
|
||||||
|
if ((b & 0x03) == 0x02 && (a & 0x03) == 0x00) {
|
||||||
|
increment = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t switch_state_;
|
||||||
|
uint8_t quadrature_decoding_state_[2];
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Encoder);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Encoder encoder;
|
||||||
|
|
||||||
|
#endif // YARNS_DRIVERS_ENCODER_H_
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stm32f37x_conf.h>
|
#include <stm32f37x_conf.h>
|
||||||
|
|
||||||
#include "drivers/display.h"
|
#include "drivers/display.h"
|
||||||
|
#include "drivers/encoder.h"
|
||||||
#include "drivers/gpio.h"
|
#include "drivers/gpio.h"
|
||||||
#include "part.h"
|
#include "part.h"
|
||||||
#include "stmlib/system/system_clock.h"
|
#include "stmlib/system/system_clock.h"
|
||||||
|
@ -10,8 +11,9 @@ using namespace stmlib;
|
||||||
|
|
||||||
GPIO gpio;
|
GPIO gpio;
|
||||||
Display display;
|
Display display;
|
||||||
|
Encoder encoder;
|
||||||
|
|
||||||
UI ui;
|
UI ui;
|
||||||
//SystemClock system_clock;
|
|
||||||
Part part[PART_COUNT];
|
Part part[PART_COUNT];
|
||||||
|
|
||||||
// Default interrupt handlers.
|
// Default interrupt handlers.
|
||||||
|
@ -46,6 +48,7 @@ void SysTick_Handler()
|
||||||
{
|
{
|
||||||
IWDG_ReloadCounter();
|
IWDG_ReloadCounter();
|
||||||
system_clock.Tick();
|
system_clock.Tick();
|
||||||
|
ui.Poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIM2_IRQHandler(void)
|
void TIM2_IRQHandler(void)
|
||||||
|
@ -116,6 +119,8 @@ void Init(void)
|
||||||
gpio.Init();
|
gpio.Init();
|
||||||
// asm("bkpt #0");
|
// asm("bkpt #0");
|
||||||
display.Init();
|
display.Init();
|
||||||
|
encoder.Init();
|
||||||
|
ui.Init();
|
||||||
InitTimers();
|
InitTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +130,8 @@ int main(void)
|
||||||
while (1) {
|
while (1) {
|
||||||
// In this loop we do things that dont depend on any timing, but that have to be done.
|
// In this loop we do things that dont depend on any timing, but that have to be done.
|
||||||
// you should not write on spi here because that should happen in the TIM2 interrupt
|
// you should not write on spi here because that should happen in the TIM2 interrupt
|
||||||
ui.Update();
|
// do we want to call the watchdog here? it's the only part thats getting interrupted after all
|
||||||
|
// (next to the interrupts themselves potentially interrupting each other)
|
||||||
|
ui.DoEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "drivers/display.h"
|
#include "drivers/display.h"
|
||||||
|
#include "midi2cv/drivers/encoder.h"
|
||||||
#include "part.h"
|
#include "part.h"
|
||||||
#include "stmlib/utils/random.h"
|
#include "stmlib/utils/random.h"
|
||||||
#include <u8g2.h>
|
#include <u8g2.h>
|
||||||
|
@ -10,9 +11,23 @@ using namespace stmlib;
|
||||||
|
|
||||||
const char part_names[4][2] = { "A", "B", "C", "D" };
|
const char part_names[4][2] = { "A", "B", "C", "D" };
|
||||||
|
|
||||||
void UI::Update()
|
void UI::Init()
|
||||||
{
|
{
|
||||||
|
input_queue.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UI::Poll()
|
||||||
|
{
|
||||||
|
encoder.Debounce();
|
||||||
|
int32_t increment = encoder.increment();
|
||||||
|
if (increment != 0) {
|
||||||
|
input_queue.AddEvent(CONTROL_ENCODER, 0, increment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UI::Draw() {
|
||||||
u8g2_ClearBuffer(display.u8g2());
|
u8g2_ClearBuffer(display.u8g2());
|
||||||
|
|
||||||
switch (current_menu) {
|
switch (current_menu) {
|
||||||
case MENU_PART_1:
|
case MENU_PART_1:
|
||||||
case MENU_PART_2:
|
case MENU_PART_2:
|
||||||
|
@ -25,6 +40,7 @@ void UI::Update()
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
display.Swap();
|
display.Swap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,3 +69,43 @@ void UI::Flush()
|
||||||
{
|
{
|
||||||
display.Flush();
|
display.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UI::DoEvents()
|
||||||
|
{
|
||||||
|
bool refresh_display = false;
|
||||||
|
while (input_queue.available()) {
|
||||||
|
Event e = input_queue.PullEvent();
|
||||||
|
if (e.control_type == CONTROL_ENCODER_CLICK) {
|
||||||
|
OnClick();
|
||||||
|
} else if (e.control_type == CONTROL_ENCODER_LONG_CLICK) {
|
||||||
|
OnLongClick();
|
||||||
|
} else if (e.control_type == CONTROL_ENCODER) {
|
||||||
|
OnIncrement(e);
|
||||||
|
}
|
||||||
|
refresh_display = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input_queue.idle_time() > 1000) {
|
||||||
|
refresh_display = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(refresh_display) {
|
||||||
|
input_queue.Touch();
|
||||||
|
Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
return refresh_display;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UI::OnClick()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UI::OnLongClick()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UI::OnIncrement(Event& e)
|
||||||
|
{
|
||||||
|
current_menu = (Menu_t) (((uint32_t)current_menu + e.data) % MENU_COUNT);
|
||||||
|
}
|
||||||
|
|
16
midi2cv/ui.h
16
midi2cv/ui.h
|
@ -2,9 +2,10 @@
|
||||||
#define MIDI2CV_UI_H
|
#define MIDI2CV_UI_H
|
||||||
|
|
||||||
#include "stmlib/stmlib.h"
|
#include "stmlib/stmlib.h"
|
||||||
|
#include "stmlib/ui/event_queue.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MENU_PART_1,
|
MENU_PART_1 = 0,
|
||||||
MENU_PART_2,
|
MENU_PART_2,
|
||||||
MENU_PART_3,
|
MENU_PART_3,
|
||||||
MENU_PART_4,
|
MENU_PART_4,
|
||||||
|
@ -16,15 +17,24 @@ class UI {
|
||||||
UI() {}
|
UI() {}
|
||||||
~UI() {}
|
~UI() {}
|
||||||
|
|
||||||
void Update();
|
void Init();
|
||||||
|
void Poll();
|
||||||
void Flush();
|
void Flush();
|
||||||
|
bool DoEvents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Menu_t current_menu;
|
|
||||||
|
|
||||||
|
Menu_t current_menu;
|
||||||
|
stmlib::EventQueue<16> input_queue;
|
||||||
|
|
||||||
|
void Draw();
|
||||||
void DrawHeader();
|
void DrawHeader();
|
||||||
void DrawPartMenu(Menu_t menu);
|
void DrawPartMenu(Menu_t menu);
|
||||||
|
|
||||||
|
void OnClick();
|
||||||
|
void OnLongClick();
|
||||||
|
void OnIncrement(stmlib::Event &e);
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(UI);
|
DISALLOW_COPY_AND_ASSIGN(UI);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue