139 lines
3.8 KiB
C
139 lines
3.8 KiB
C
/*******************************************************************
|
|
File: gui.c
|
|
Date: 29-September-2025
|
|
Author: Peter Spindler
|
|
Description: Functions to create a simple grafical user interface (gui)
|
|
********************************************************************/
|
|
|
|
#include "stm32f7xx_hal.h"
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "queue.h"
|
|
|
|
#include <string.h>
|
|
#include "display.h"
|
|
#include "touch.h"
|
|
|
|
TaskHandle_t GUITaskHandle = NULL;
|
|
|
|
QueueHandle_t GUIQueue;
|
|
|
|
#define BUTTON_MARGIN_X 20
|
|
#define BUTTON_MARGIN_Y 22
|
|
#define GUI_BUTTONSIZE 16
|
|
|
|
typedef struct {
|
|
uint16_t xPos;
|
|
uint16_t yPos;
|
|
uint16_t Width;
|
|
uint16_t Height;
|
|
char Text[16];
|
|
uint8_t Msg;
|
|
} GUI_BUTTON_TypeDef;
|
|
|
|
static uint8_t GUI_ButtonCnt = 0;
|
|
static GUI_BUTTON_TypeDef GUI_Button[GUI_BUTTONSIZE];
|
|
|
|
uint8_t GUI_IsPressed( void )
|
|
{
|
|
if( HAL_GPIO_ReadPin( GPIOC,GPIO_PIN_13 ) == 0 ) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void GUI_AddButton( uint16_t xPos, uint16_t yPos, char *Text, uint8_t Msg )
|
|
{
|
|
uint8_t i;
|
|
i = GUI_ButtonCnt;
|
|
if( i < GUI_BUTTONSIZE ) {
|
|
GUI_Button[i].xPos = xPos;
|
|
GUI_Button[i].yPos = yPos;
|
|
memset(GUI_Button[i].Text, 0, sizeof(GUI_Button[i].Text) );
|
|
strncpy(GUI_Button[i].Text, Text, sizeof(GUI_Button[i].Text) );
|
|
GUI_Button[i].Msg = Msg;
|
|
GUI_Button[i].Width = Display_GetStringWidth(&FontBig,Text)+2*BUTTON_MARGIN_X;
|
|
GUI_Button[i].Height = Display_GetFontCharHeight(&FontBig)+2*BUTTON_MARGIN_Y;
|
|
GUI_ButtonCnt ++;
|
|
}
|
|
}
|
|
|
|
static void GUI_DisplayButton( uint8_t Index, uint8_t State )
|
|
{
|
|
GUI_BUTTON_TypeDef *Button = &GUI_Button[Index];
|
|
uint16_t ColorBack;
|
|
|
|
if( State == 0 ) {
|
|
ColorBack = LCD_COLOR_BLACK;
|
|
} else {
|
|
ColorBack = LCD_COLOR_BLUE;
|
|
}
|
|
|
|
Display_FillRect( Button->xPos,Button->yPos, Button->Width,Button->Height, ColorBack );
|
|
Display_DrawRect(Button->xPos,Button->yPos, Button->Width,Button->Height, LCD_COLOR_WHITE );
|
|
Display_PrintString( Button->xPos+BUTTON_MARGIN_X, Button->yPos+BUTTON_MARGIN_Y, LCD_COLOR_WHITE,ColorBack, &FontBig, Button->Text);
|
|
}
|
|
|
|
static void GUI_Task( void *arguments ) {
|
|
uint8_t TouchState = 0;
|
|
uint16_t xTouch, yTouch;
|
|
uint8_t i;
|
|
uint8_t ButtonPressedIndex=0;
|
|
uint8_t Msg;
|
|
uint32_t EventTime;
|
|
|
|
for(i=0;i<GUI_ButtonCnt;i++) {
|
|
GUI_DisplayButton(i,0);
|
|
}
|
|
|
|
while( 1 ) {
|
|
vTaskDelay(20);
|
|
if( TouchState == 0 && Touch_IsPressed() ) {
|
|
if( Touch_ReadPos( &xTouch, &yTouch ) ) {
|
|
|
|
ButtonPressedIndex = 0xff;
|
|
for(i=0;i<GUI_ButtonCnt;i++) {
|
|
if( xTouch >= GUI_Button[i].xPos &&
|
|
xTouch <= GUI_Button[i].xPos + GUI_Button[i].Width &&
|
|
yTouch >= GUI_Button[i].yPos &&
|
|
yTouch <= GUI_Button[i].yPos + GUI_Button[i].Height ) {
|
|
ButtonPressedIndex = i;
|
|
}
|
|
}
|
|
if( ButtonPressedIndex != 0xff ) {
|
|
GUI_DisplayButton(ButtonPressedIndex,1);
|
|
xQueueSendToBack( GUIQueue, ( void * ) &GUI_Button[ButtonPressedIndex].Msg, ( portTickType ) 0 );
|
|
TouchState = 1;
|
|
EventTime = HAL_GetTick() + 500;
|
|
}
|
|
}
|
|
|
|
} else if( TouchState == 1 ) {
|
|
if( !Touch_IsPressed() ) {
|
|
if( ButtonPressedIndex != 0xff ) {
|
|
GUI_DisplayButton(ButtonPressedIndex,0);
|
|
}
|
|
TouchState = 0;
|
|
} else if( HAL_GetTick() > EventTime ) {
|
|
if( ButtonPressedIndex != 0xff ) {
|
|
Msg = GUI_Button[ButtonPressedIndex].Msg; // | 0x80;
|
|
xQueueSendToBack( GUIQueue, ( void * ) &Msg, ( portTickType ) 0 );
|
|
}
|
|
EventTime = HAL_GetTick() + 50;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void GUI_Init( void ) {
|
|
portENABLE_INTERRUPTS(); // Workaround to re-enable interrupts after FreeRTOS functions
|
|
Touch_Init();
|
|
|
|
GUIQueue = xQueueCreate( 10, sizeof( uint8_t) );
|
|
xTaskCreate(GUI_Task,"GUI", configMINIMAL_STACK_SIZE,NULL,0,&GUITaskHandle);
|
|
|
|
portENABLE_INTERRUPTS(); // Workaround to re-enable interrupts after FreeRTOS functions
|
|
}
|