2025-12-15 18:37:39 +01:00

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
}