diff --git a/midi2cv/drivers/display.cc b/midi2cv/drivers/display.cc index fd38d75..8004062 100644 --- a/midi2cv/drivers/display.cc +++ b/midi2cv/drivers/display.cc @@ -1,10 +1,10 @@ #include "display.h" #include "gpio.h" +#include "spi_mode.h" #include "stmlib/system/system_clock.h" #include "stmlib/utils/random.h" #include #include -#include "spi_mode.h" using namespace stmlib; @@ -19,119 +19,118 @@ uint8_t* output_buf; u8g2_t* Display::u8g2() { - return &u8g2_; + return &u8g2_; } void InitSPI(void); void Display::Init() { - // init SS/CS/RST GPIO - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); + // init SS/CS/RST GPIO + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); - GPIO_InitTypeDef gpio_init; - gpio_init.GPIO_Mode = GPIO_Mode_OUT; - gpio_init.GPIO_OType = GPIO_OType_PP; - gpio_init.GPIO_Speed = GPIO_Speed_50MHz; - gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; - gpio_init.GPIO_Pin = kPinEnable | kPinReset | kPinDataCommand; - GPIO_Init(GPIOB, &gpio_init); + GPIO_InitTypeDef gpio_init; + gpio_init.GPIO_Mode = GPIO_Mode_OUT; + gpio_init.GPIO_OType = GPIO_OType_PP; + gpio_init.GPIO_Speed = GPIO_Speed_50MHz; + gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; + gpio_init.GPIO_Pin = kPinEnable | kPinReset | kPinDataCommand; + GPIO_Init(GPIOB, &gpio_init); - GPIO_WriteBit(GPIOB, kPinEnable, Bit_SET); + GPIO_WriteBit(GPIOB, kPinEnable, Bit_SET); - // init AF GPIO - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); + // init AF GPIO + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); - gpio_init.GPIO_Mode = GPIO_Mode_AF; - gpio_init.GPIO_OType = GPIO_OType_PP; - gpio_init.GPIO_Speed = GPIO_Speed_50MHz; - gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; - gpio_init.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_15; - GPIO_Init(GPIOB, &gpio_init); - GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_5); - GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5); - GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5); + gpio_init.GPIO_Mode = GPIO_Mode_AF; + gpio_init.GPIO_OType = GPIO_OType_PP; + gpio_init.GPIO_Speed = GPIO_Speed_50MHz; + gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; + gpio_init.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_15; + GPIO_Init(GPIOB, &gpio_init); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_5); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5); - // init SPI - RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); - SPI_I2S_DeInit(SPI2); - // Initialize SPI - InitSPI(SPI_MODE_DISPLAY); - GPIO_WriteBit(GPIOB, kPinReset, Bit_RESET); - asm("nop"); + // init SPI + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); + SPI_I2S_DeInit(SPI2); + // Initialize SPI + InitSPI(SPI_MODE_DISPLAY); + GPIO_WriteBit(GPIOB, kPinReset, Bit_RESET); + asm("nop"); - GPIO_WriteBit(GPIOB, kPinReset, Bit_SET); - InitGLib(); + GPIO_WriteBit(GPIOB, kPinReset, Bit_SET); + InitGLib(); } - uint8_t u8x8_stm32_gpio_and_delay(U8X8_UNUSED u8x8_t* u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void* arg_ptr) { - return 1; + return 1; } uint8_t u8x8_byte_4wire_hw_spi(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { - uint8_t* data; - switch (msg) { - case U8X8_MSG_BYTE_SEND: - data = (uint8_t*)arg_ptr; - while (arg_int > 0) { - while (!(SPI2->SR & SPI_SR_TXE)) { - } - SPI_SendData8(SPI2, (uint8_t)*data); - arg_int--; - data++; - } - break; - case U8X8_MSG_BYTE_INIT: - break; - case U8X8_MSG_BYTE_SET_DC: - if (arg_int) - GPIO_WriteBit(GPIOB, kPinDataCommand, Bit_SET); - else - GPIO_WriteBit(GPIOB, kPinDataCommand, Bit_RESET); - break; - case U8X8_MSG_BYTE_START_TRANSFER: - InitSPI(SPI_MODE_DISPLAY); - GPIO_WriteBit(GPIOB, kPinEnable, Bit_RESET); - break; - case U8X8_MSG_BYTE_END_TRANSFER: - GPIO_WriteBit(GPIOB, kPinEnable, Bit_SET); - break; - default: - return 0; + uint8_t* data; + switch (msg) { + case U8X8_MSG_BYTE_SEND: + data = (uint8_t*)arg_ptr; + while (arg_int > 0) { + while (!(SPI2->SR & SPI_SR_TXE)) { + } + SPI_SendData8(SPI2, (uint8_t)*data); + arg_int--; + data++; } - return 1; + break; + case U8X8_MSG_BYTE_INIT: + break; + case U8X8_MSG_BYTE_SET_DC: + if (arg_int) + GPIO_WriteBit(GPIOB, kPinDataCommand, Bit_SET); + else + GPIO_WriteBit(GPIOB, kPinDataCommand, Bit_RESET); + break; + case U8X8_MSG_BYTE_START_TRANSFER: + InitSPI(SPI_MODE_DISPLAY); + GPIO_WriteBit(GPIOB, kPinEnable, Bit_RESET); + break; + case U8X8_MSG_BYTE_END_TRANSFER: + GPIO_WriteBit(GPIOB, kPinEnable, Bit_SET); + break; + default: + return 0; + } + return 1; } void Display::InitGLib() { - u8g2_Setup_sh1106_128x64_noname_f(&u8g2_, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay); - output_buf = default_buf = u8g2_.tile_buf_ptr; - u8g2_InitDisplay(&u8g2_); - u8g2_SetContrast(&u8g2_, 255); - u8g2_SetPowerSave(&u8g2_, 0); + u8g2_Setup_sh1106_128x64_noname_f(&u8g2_, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay); + output_buf = default_buf = u8g2_.tile_buf_ptr; + u8g2_InitDisplay(&u8g2_); + u8g2_SetContrast(&u8g2_, 255); + u8g2_SetPowerSave(&u8g2_, 0); - Random::Seed(42); + Random::Seed(42); } void Display::Flush() { - uint8_t* cache = u8g2_.tile_buf_ptr; - u8g2_.tile_buf_ptr = output_buf; - u8g2_SendBuffer(&u8g2_); - u8g2_.tile_buf_ptr = cache; + uint8_t* cache = u8g2_.tile_buf_ptr; + u8g2_.tile_buf_ptr = output_buf; + u8g2_SendBuffer(&u8g2_); + u8g2_.tile_buf_ptr = cache; } void Display::Swap() { - output_buf = u8g2_.tile_buf_ptr; - if (output_buf == default_buf) - u8g2_.tile_buf_ptr = second_buf; - else - u8g2_.tile_buf_ptr = default_buf; + output_buf = u8g2_.tile_buf_ptr; + if (output_buf == default_buf) + u8g2_.tile_buf_ptr = second_buf; + else + u8g2_.tile_buf_ptr = default_buf; } diff --git a/midi2cv/midi2cv.cc b/midi2cv/midi2cv.cc index aedca29..428e8e4 100644 --- a/midi2cv/midi2cv.cc +++ b/midi2cv/midi2cv.cc @@ -56,12 +56,12 @@ void TIM2_IRQHandler(void) TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // this will get called with 192 kHz (foof) - // we want to reduce the amount of times the ui gets polled to 1kHz + // we want to reduce the amount of times the ui gets polled to 500 Hz // which still is a lot (60fps would be enough tbh) static uint8_t count = 0; count++; - if (count % 192 == 0) { + if (count % (192 * 2) == 0) { ui.Flush(); count = 0; } diff --git a/midi2cv/ui.cc b/midi2cv/ui.cc index 8c6d9f8..04c8e40 100644 --- a/midi2cv/ui.cc +++ b/midi2cv/ui.cc @@ -12,7 +12,7 @@ const char part_names[4][2] = { "A", "B", "C", "D" }; void UI::Update() { - + u8g2_ClearBuffer(display.u8g2()); switch (current_menu) { case MENU_PART_1: case MENU_PART_2: @@ -25,20 +25,22 @@ void UI::Update() break; } + display.Swap(); } void UI::DrawHeader() { + u8g2_SetFont(display.u8g2(), u8g2_font_6x12_tf); for (int i = 0; i < PART_COUNT; i++) { u8g2_SetFontMode(display.u8g2(), 1); u8g2_SetDrawColor(display.u8g2(), 1); if (current_menu == i) - u8g2_DrawBox(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT), 0, (DISPLAY_WIDTH / PART_COUNT), HEADER_HEIGHT); + u8g2_DrawBox(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT), 0, (DISPLAY_WIDTH / PART_COUNT) - 1, HEADER_HEIGHT); else - u8g2_DrawFrame(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT), 0, (DISPLAY_WIDTH / PART_COUNT), HEADER_HEIGHT); + u8g2_DrawFrame(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT), 0, (DISPLAY_WIDTH / PART_COUNT) - 1, HEADER_HEIGHT); u8g2_SetDrawColor(display.u8g2(), 2); - u8g2_DrawStr(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT) + 2, 2, part_names[i]); + u8g2_DrawStr(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT) + 5, 2 + 10, part_names[i]); u8g2_SetDrawColor(display.u8g2(), 1); } }