Fix UI Drawing

This commit is contained in:
Jan-Henrik 2019-10-22 21:54:33 +02:00
parent 91fd3e4302
commit 77d8c2d97e
3 changed files with 86 additions and 85 deletions

View file

@ -1,10 +1,10 @@
#include "display.h" #include "display.h"
#include "gpio.h" #include "gpio.h"
#include "spi_mode.h"
#include "stmlib/system/system_clock.h" #include "stmlib/system/system_clock.h"
#include "stmlib/utils/random.h" #include "stmlib/utils/random.h"
#include <stm32f37x_conf.h> #include <stm32f37x_conf.h>
#include <u8g2.h> #include <u8g2.h>
#include "spi_mode.h"
using namespace stmlib; using namespace stmlib;
@ -19,119 +19,118 @@ uint8_t* output_buf;
u8g2_t* Display::u8g2() u8g2_t* Display::u8g2()
{ {
return &u8g2_; return &u8g2_;
} }
void InitSPI(void); void InitSPI(void);
void Display::Init() void Display::Init()
{ {
// init SS/CS/RST GPIO // init SS/CS/RST GPIO
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitTypeDef gpio_init; GPIO_InitTypeDef gpio_init;
gpio_init.GPIO_Mode = GPIO_Mode_OUT; gpio_init.GPIO_Mode = GPIO_Mode_OUT;
gpio_init.GPIO_OType = GPIO_OType_PP; gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_Speed = GPIO_Speed_50MHz; gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio_init.GPIO_Pin = kPinEnable | kPinReset | kPinDataCommand; gpio_init.GPIO_Pin = kPinEnable | kPinReset | kPinDataCommand;
GPIO_Init(GPIOB, &gpio_init); GPIO_Init(GPIOB, &gpio_init);
GPIO_WriteBit(GPIOB, kPinEnable, Bit_SET); GPIO_WriteBit(GPIOB, kPinEnable, Bit_SET);
// init AF GPIO // init AF GPIO
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
gpio_init.GPIO_Mode = GPIO_Mode_AF; gpio_init.GPIO_Mode = GPIO_Mode_AF;
gpio_init.GPIO_OType = GPIO_OType_PP; gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_Speed = GPIO_Speed_50MHz; gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL; gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio_init.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_15; gpio_init.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &gpio_init); GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_5); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5); GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5); GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5);
// init SPI // init SPI
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_I2S_DeInit(SPI2); SPI_I2S_DeInit(SPI2);
// Initialize SPI // Initialize SPI
InitSPI(SPI_MODE_DISPLAY); InitSPI(SPI_MODE_DISPLAY);
GPIO_WriteBit(GPIOB, kPinReset, Bit_RESET); GPIO_WriteBit(GPIOB, kPinReset, Bit_RESET);
asm("nop"); asm("nop");
GPIO_WriteBit(GPIOB, kPinReset, Bit_SET); GPIO_WriteBit(GPIOB, kPinReset, Bit_SET);
InitGLib(); InitGLib();
} }
uint8_t u8x8_stm32_gpio_and_delay(U8X8_UNUSED u8x8_t* u8x8, 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 uint8_t msg, U8X8_UNUSED uint8_t arg_int,
U8X8_UNUSED void* arg_ptr) 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, uint8_t u8x8_byte_4wire_hw_spi(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int,
void* arg_ptr) void* arg_ptr)
{ {
uint8_t* data; uint8_t* data;
switch (msg) { switch (msg) {
case U8X8_MSG_BYTE_SEND: case U8X8_MSG_BYTE_SEND:
data = (uint8_t*)arg_ptr; data = (uint8_t*)arg_ptr;
while (arg_int > 0) { while (arg_int > 0) {
while (!(SPI2->SR & SPI_SR_TXE)) { while (!(SPI2->SR & SPI_SR_TXE)) {
} }
SPI_SendData8(SPI2, (uint8_t)*data); SPI_SendData8(SPI2, (uint8_t)*data);
arg_int--; arg_int--;
data++; 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;
} }
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() void Display::InitGLib()
{ {
u8g2_Setup_sh1106_128x64_noname_f(&u8g2_, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay); 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; output_buf = default_buf = u8g2_.tile_buf_ptr;
u8g2_InitDisplay(&u8g2_); u8g2_InitDisplay(&u8g2_);
u8g2_SetContrast(&u8g2_, 255); u8g2_SetContrast(&u8g2_, 255);
u8g2_SetPowerSave(&u8g2_, 0); u8g2_SetPowerSave(&u8g2_, 0);
Random::Seed(42); Random::Seed(42);
} }
void Display::Flush() void Display::Flush()
{ {
uint8_t* cache = u8g2_.tile_buf_ptr; uint8_t* cache = u8g2_.tile_buf_ptr;
u8g2_.tile_buf_ptr = output_buf; u8g2_.tile_buf_ptr = output_buf;
u8g2_SendBuffer(&u8g2_); u8g2_SendBuffer(&u8g2_);
u8g2_.tile_buf_ptr = cache; u8g2_.tile_buf_ptr = cache;
} }
void Display::Swap() void Display::Swap()
{ {
output_buf = u8g2_.tile_buf_ptr; output_buf = u8g2_.tile_buf_ptr;
if (output_buf == default_buf) if (output_buf == default_buf)
u8g2_.tile_buf_ptr = second_buf; u8g2_.tile_buf_ptr = second_buf;
else else
u8g2_.tile_buf_ptr = default_buf; u8g2_.tile_buf_ptr = default_buf;
} }

View file

@ -56,12 +56,12 @@ void TIM2_IRQHandler(void)
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// this will get called with 192 kHz (foof) // 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) // which still is a lot (60fps would be enough tbh)
static uint8_t count = 0; static uint8_t count = 0;
count++; count++;
if (count % 192 == 0) { if (count % (192 * 2) == 0) {
ui.Flush(); ui.Flush();
count = 0; count = 0;
} }

View file

@ -12,7 +12,7 @@ const char part_names[4][2] = { "A", "B", "C", "D" };
void UI::Update() void UI::Update()
{ {
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,20 +25,22 @@ void UI::Update()
break; break;
} }
display.Swap();
} }
void UI::DrawHeader() void UI::DrawHeader()
{ {
u8g2_SetFont(display.u8g2(), u8g2_font_6x12_tf);
for (int i = 0; i < PART_COUNT; i++) { for (int i = 0; i < PART_COUNT; i++) {
u8g2_SetFontMode(display.u8g2(), 1); u8g2_SetFontMode(display.u8g2(), 1);
u8g2_SetDrawColor(display.u8g2(), 1); u8g2_SetDrawColor(display.u8g2(), 1);
if (current_menu == i) 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 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_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); u8g2_SetDrawColor(display.u8g2(), 1);
} }
} }