mirror of
				https://github.com/jhbruhn/eurorack.git
				synced 2025-11-04 13:26:02 +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_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InitSPI(void);
 | 
			
		||||
 | 
			
		||||
void Display::Init()
 | 
			
		||||
{
 | 
			
		||||
  // 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 "drivers/display.h"
 | 
			
		||||
#include "drivers/encoder.h"
 | 
			
		||||
#include "drivers/gpio.h"
 | 
			
		||||
#include "part.h"
 | 
			
		||||
#include "stmlib/system/system_clock.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -10,8 +11,9 @@ using namespace stmlib;
 | 
			
		|||
 | 
			
		||||
GPIO gpio;
 | 
			
		||||
Display display;
 | 
			
		||||
Encoder encoder;
 | 
			
		||||
 | 
			
		||||
UI ui;
 | 
			
		||||
//SystemClock system_clock;
 | 
			
		||||
Part part[PART_COUNT];
 | 
			
		||||
 | 
			
		||||
// Default interrupt handlers.
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +48,7 @@ void SysTick_Handler()
 | 
			
		|||
{
 | 
			
		||||
  IWDG_ReloadCounter();
 | 
			
		||||
  system_clock.Tick();
 | 
			
		||||
  ui.Poll();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TIM2_IRQHandler(void)
 | 
			
		||||
| 
						 | 
				
			
			@ -116,6 +119,8 @@ void Init(void)
 | 
			
		|||
  gpio.Init();
 | 
			
		||||
  // asm("bkpt #0");
 | 
			
		||||
  display.Init();
 | 
			
		||||
  encoder.Init();
 | 
			
		||||
  ui.Init();
 | 
			
		||||
  InitTimers();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +130,8 @@ int main(void)
 | 
			
		|||
  while (1) {
 | 
			
		||||
    // 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
 | 
			
		||||
    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 "drivers/display.h"
 | 
			
		||||
#include "midi2cv/drivers/encoder.h"
 | 
			
		||||
#include "part.h"
 | 
			
		||||
#include "stmlib/utils/random.h"
 | 
			
		||||
#include <u8g2.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -10,9 +11,23 @@ using namespace stmlib;
 | 
			
		|||
 | 
			
		||||
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());
 | 
			
		||||
 | 
			
		||||
  switch (current_menu) {
 | 
			
		||||
  case MENU_PART_1:
 | 
			
		||||
  case MENU_PART_2:
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +40,7 @@ void UI::Update()
 | 
			
		|||
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  display.Swap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,3 +69,43 @@ void UI::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
 | 
			
		||||
 | 
			
		||||
#include "stmlib/stmlib.h"
 | 
			
		||||
#include "stmlib/ui/event_queue.h"
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  MENU_PART_1,
 | 
			
		||||
  MENU_PART_1 = 0,
 | 
			
		||||
  MENU_PART_2,
 | 
			
		||||
  MENU_PART_3,
 | 
			
		||||
  MENU_PART_4,
 | 
			
		||||
| 
						 | 
				
			
			@ -16,15 +17,24 @@ class UI {
 | 
			
		|||
  UI() {}
 | 
			
		||||
  ~UI() {}
 | 
			
		||||
 | 
			
		||||
  void Update();
 | 
			
		||||
  void Init();
 | 
			
		||||
  void Poll();
 | 
			
		||||
  void Flush();
 | 
			
		||||
  bool DoEvents();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
  Menu_t current_menu;
 | 
			
		||||
 | 
			
		||||
  Menu_t current_menu;
 | 
			
		||||
  stmlib::EventQueue<16> input_queue;
 | 
			
		||||
 | 
			
		||||
  void Draw();
 | 
			
		||||
  void DrawHeader();
 | 
			
		||||
  void DrawPartMenu(Menu_t menu);
 | 
			
		||||
 | 
			
		||||
  void OnClick();
 | 
			
		||||
  void OnLongClick();
 | 
			
		||||
  void OnIncrement(stmlib::Event &e);
 | 
			
		||||
 | 
			
		||||
  DISALLOW_COPY_AND_ASSIGN(UI);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue