This commit is contained in:
2025-05-09 21:26:59 +03:00
commit 5e1364447e
2936 changed files with 2471676 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
#include "i2c_lcd.h"
extern unsigned tim1_cnt;
//extern struct var_result VAR_RESULT;
//LCD Delays (Delay1 - )
/**
* @brief Initialization of LCD.
* @note This called from main
*/
void LCD_Init(LCDI2C_HandleTypeDef *hlcd)
{
for (hlcd->Address = 0; hlcd->Address < 128; hlcd->Address++)
{
if(HAL_I2C_IsDeviceReady(hlcd->hi2c, hlcd->Address << 1, 1, HAL_MAX_DELAY)==HAL_OK) break; // scan i2c adresses
}
if (hlcd->Address >= 128)
return;
hlcd->Address = hlcd->Address << 1;
osDelay(500);
LCD_Send_CMD(hlcd, 0x30);
osDelay(5);
LCD_Send_CMD(hlcd, 0x30);
osDelay(1);
LCD_Send_CMD(hlcd, 0x30);
osDelay(10);
LCD_Send_CMD(hlcd, 0x20); // 4bit mode
osDelay(10);
//dislay initialisation
LCD_Send_CMD(hlcd, 0x28); // display off
osDelay(1);
LCD_Send_CMD(hlcd, 0x08); // display off
osDelay(50);
LCD_Send_CMD(hlcd, 0x01); // clear display
osDelay(10);
osDelay(10);
LCD_Send_CMD(hlcd, 0x06); // direction of cursor
osDelay(1);
LCD_Send_CMD(hlcd, 0x0C); // display on / cursor off
}
void LCD_Reinit(LCDI2C_HandleTypeDef *hlcd)
{
osDelay(1000);
LCD_Init(hlcd);
hlcd->LCD_REINIT=0;
}
void LCD_Check(LCDI2C_HandleTypeDef *hlcd)
{
if(hlcd->LCD_REINIT) LCD_Reinit(hlcd);
}
void LCD_Send_CMD (LCDI2C_HandleTypeDef *hlcd, char cmd)
{
char data_up, data_low;
uint8_t data_t[4];
data_up = (cmd&0xf0);
data_low=((cmd<<4)&0xf0);
data_t[0]=data_up|0x0C; //en=1, rs=0
data_t[1]=data_up|0x08; //en=0, rs=0
data_t[2]=data_low|0x0C; //en=1, rs=0
data_t[3]=data_low|0x08; //en=0, rs=0
HAL_I2C_Master_Transmit(hlcd->hi2c, hlcd->Address, (uint8_t *)data_t, 4, HAL_MAX_DELAY);
}
void LCD_Send_DATA (LCDI2C_HandleTypeDef *hlcd, char data)
{
char data_up, data_low;
uint8_t data_t[4];
data_up = (data&0xf0);
data_low=((data<<4)&0xf0);
data_t[0]=data_up|0x0D; //en=1, rs=1
data_t[1]=data_up|0x09; //en=0, rs=1
data_t[2]=data_low|0x0D; //en=1, rs=1
data_t[3]=data_low|0x09; //en=0, rs=1
HAL_I2C_Master_Transmit(hlcd->hi2c, hlcd->Address, (uint8_t *)data_t, 4, HAL_MAX_DELAY);
}
void LCD_Send_STRING(LCDI2C_HandleTypeDef *hlcd, char *str)
{
while (*str)
{
LCD_Send_DATA (hlcd, *str++);
osDelay(1);
}
}
void LCD_Send_INT(LCDI2C_HandleTypeDef *hlcd, int int_to_string, uint8_t size)
{
char string_from_int[10];
if(size)
sprintf(string_from_int, "%0*d", size, int_to_string);
else
sprintf(string_from_int, "%d", int_to_string);
LCD_Send_STRING(hlcd, string_from_int);
}
void LCD_Send_NUMB(LCDI2C_HandleTypeDef *hlcd, float numb_to_string, uint8_t size)
{
char string_from_numb[size];
snprintf(string_from_numb, size+1, "%.2f", numb_to_string);
LCD_Send_STRING(hlcd, string_from_numb);
}

View File

@@ -0,0 +1,30 @@
#ifndef __LCD_H_
#define __LCD_H_
#include "periph_general.h"
#include "cmsis_os.h"
#include <stdio.h>
typedef struct{
uint8_t Address;
I2C_HandleTypeDef *hi2c;
unsigned LCD_REINIT : 1;
uint16_t DisplayDelay;
uint8_t ClearDelay;
}LCDI2C_HandleTypeDef;
/**
* @brief Initialization of LCD.
* @note This called from main
*/
void LCD_Init(LCDI2C_HandleTypeDef *hlcd);
void LCD_Reinit(LCDI2C_HandleTypeDef *hlcd);
void LCD_Check(LCDI2C_HandleTypeDef *hlcd);
void LCD_Send_STRING(LCDI2C_HandleTypeDef *hlcd, char *str);
void LCD_Send_INT(LCDI2C_HandleTypeDef *hlcd, int int_to_string, uint8_t size);
void LCD_Send_NUMB(LCDI2C_HandleTypeDef *hlcd, float numb_to_string, uint8_t size);
void LCD_Send_DATA (LCDI2C_HandleTypeDef *hlcd, char data);
void LCD_Send_CMD (LCDI2C_HandleTypeDef *hlcd, char cmd);
#endif

View File

@@ -0,0 +1,517 @@
#include "interface.h"
#include "pwm.h"
TIM_SettingsTypeDef TIM_ENCODER = {0};
extern I2C_HandleTypeDef hi2c1;
LCDI2C_HandleTypeDef hlcd1;
TIM_EncoderTypeDef henc1;
extern PWM_HandleTypeDef hpwm1;
Interface_HandleTypeDef hinterface;
/**
* @brief Read encoder function.
* @param henc - хендл энкодера.
* @param hlcd - хендл LCD-дисплея.
* @note This called from freertos MainTask thread.
*/
void ReadEncoder(TIM_EncoderTypeDef *henc, LCDI2C_HandleTypeDef *hlcd)
{
uint8_t *menu = (uint8_t *)&hinterface.MenuItems;
uint8_t *disp_menu = (uint8_t *)&hinterface.DisplayingItems;
//-----------READ SWITCH-------------
if(hinterface.FineChanging == 0) // если кнопка энкодера не в режиме точной настройки
{
if((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW) // ожидание нажатия кнопки
{
osDelay(50);
if(((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW )&& // если кнопка действительно нажата
(HAL_GetTick() - hinterface.Switch_prevTick > hinterface.DoubleClick_Timeout) ) // и это не второй клик даблклика (слишком большая задержка после предыдущего нажатия)
{
hinterface.Encoder_Shdw = henc->htim->Instance->CNT;
while((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW) // ожидаем её отпускания
{
//------------FINE TUNE--------------
if (hinterface.Encoder_Shdw != henc->htim->Instance->CNT) // если кнопка не отпускается, и енкодер начинает регулироваться
{
hinterface.FineChanging = 1; // переходим в режим точной настройки
break; // выход из цикла
}
osDelay(1);
}
//-----------SWITCH PARAM------------
if(hinterface.FineChanging == 0) // если энкодер не перешел в режим точной настройки
{
hinterface.Switch_prevTick = HAL_GetTick(); // сохраняем время отжатия для регистрации даблклика если он будет
hinterface.CurrentSelection++; // переключаем режим
// skip item if it isnt displayin, until run out of items
while((*disp_menu&(1<<(hinterface.CurrentSelection-1))) == 0)
{
hinterface.CurrentSelection++;
if(hinterface.MenuNumber == 0) // if menu for params (registers)
{
if(hinterface.CurrentSelection > Menu_Size)
{
hinterface.CurrentSelection = NOTHING_SELECTED;
break;
}
}
else // if menu for modes (coils)
{
if(hinterface.CurrentSelection - NOTHING_COIL_SELECTED > Menu_Coil_Size)
{
hinterface.CurrentSelection = NOTHING_COIL_SELECTED;
break;
}
}
}
if(hinterface.MenuNumber == 0)
{
if(hinterface.CurrentSelection > (Menu_Size))
hinterface.CurrentSelection = NOTHING_SELECTED;
}
else
{
if((hinterface.CurrentSelection - NOTHING_COIL_SELECTED) > (Menu_Coil_Size))
hinterface.CurrentSelection = NOTHING_COIL_SELECTED;
}
}
}
else if(((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW )&& // если кнопка действительно нажата
(HAL_GetTick() - hinterface.Switch_prevTick < hinterface.DoubleClick_Timeout) ) // и это не второй клик даблклика (слишком большая задержка после предыдущего нажатия)
{
hinterface.MenuNumber++;
if(hinterface.MenuNumber >= 2)
{
hinterface.MenuNumber = 0;
}
if (hinterface.MenuNumber == 0)
hinterface.CurrentSelection = NOTHING_SELECTED;
else if (hinterface.MenuNumber == 1)
hinterface.CurrentSelection = NOTHING_COIL_SELECTED;
}
}
}
static uint16_t coef_value;
if(hinterface.FineChanging == 0) // если енкодер не регулируется
coef_value = 100;
else
coef_value = 2;
int16_t encoder_diff = (int32_t)henc->htim->Instance->CNT - hinterface.Encoder_Shdw;
int32_t tmpreg;
switch(hinterface.CurrentSelection)
{
case PWM_VALUE_SELECTED:
tmpreg = pwm_ctrl[R_PWM_CTRL_PWM_VALUE];
tmpreg += ((encoder_diff*coef_value)/2);
if (tmpreg >= 0)
pwm_ctrl[R_PWM_CTRL_PWM_VALUE] = tmpreg;
else
pwm_ctrl[R_PWM_CTRL_PWM_VALUE] = 0;
break;
case PWM_HZ_SELECTED:
tmpreg = pwm_ctrl[R_PWM_CTRL_PWM_HZ];
tmpreg += (encoder_diff*coef_value)/2;
if (tmpreg >= 0)
pwm_ctrl[R_PWM_CTRL_PWM_HZ] = tmpreg;
else
pwm_ctrl[R_PWM_CTRL_PWM_HZ] = 0;
break;
case PWM_DUTYBRIDGE_SELECTED:
tmpreg = pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE];
tmpreg += ((encoder_diff*coef_value)/2);
if (tmpreg < 0)
pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE] = 0;
else if (tmpreg > 10000)
pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE] = 10000;
else
pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE] = tmpreg;
break;
case PWM_COIL_DC_SELECTED:
if(encoder_diff)
hpwm1.sPWM_Config.PWM_Mode->DC = ~hpwm1.sPWM_Config.PWM_Mode->DC;
break;
case PWM_COIL_BRIDGE_SELECTED:
if(encoder_diff)
hpwm1.sPWM_Config.PWM_Mode->BRIDGE = ~hpwm1.sPWM_Config.PWM_Mode->BRIDGE;
break;
case PWM_COIL_PHASE_SELECTED:
if(encoder_diff)
hpwm1.sPWM_Config.PWM_Mode->PHASE = ~hpwm1.sPWM_Config.PWM_Mode->PHASE;
break;
case PWM_COIL_POLARITY_SELECTED:
if(encoder_diff)
hpwm1.sPWM_Config.PWM_Mode->POLARITY = ~hpwm1.sPWM_Config.PWM_Mode->POLARITY;
break;
case NOTHING_SELECTED:
if(encoder_diff > 0)
hinterface.StartMenuItem += 1;
else if(encoder_diff < 0)
hinterface.StartMenuItem -= 1;
if(hinterface.StartMenuItem < 0)
hinterface.StartMenuItem = 0;
break;
case NOTHING_COIL_SELECTED:
if(encoder_diff > 0)
hinterface.StartMenuItem += 1;
else if(encoder_diff < 0)
hinterface.StartMenuItem -= 1;
if(hinterface.StartMenuItem < 0)
hinterface.StartMenuItem = 0;
break;
default: break;
}
hinterface.Encoder_Shdw = henc->htim->Instance->CNT;
if(hinterface.FineChanging == 1) // если некодер в режиме точной настройки)
{
if(((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW) == 0) // ожидание отпускания кнопки
{
osDelay(50);
if(((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW) == 0) // если кнопка действительно нажата
{
hinterface.FineChanging = 0; // отключение режима точной настройки
}
}
}
}
void UpdateInterfaceStruct(void)
{
if(hinterface.MenuNumber == 0)
{
if(hpwm1.sPWM_Config.PWM_Mode->BRIDGE && hpwm1.sPWM_Config.PWM_Mode->DC)
hinterface.MenuItems.PWM_DutyBridge = 1;
else
hinterface.MenuItems.PWM_DutyBridge = 0;
hinterface.MenuItems.PWM_Hz = 1;
hinterface.MenuItems.PWM_Value = 1;
}
else
{
hinterface.MenuItems.PWM_DC = 1;
hinterface.MenuItems.PWM_BRIDGE = 1;
hinterface.MenuItems.PWM_PHASE = 1;
hinterface.MenuItems.PWM_POLARITY = 1;
}
}
void UpdateLCDDisplay(LCDI2C_HandleTypeDef *hlcd)
{
LCD_Check(hlcd);
// clear display
LCD_Send_CMD(hlcd, 0x01);
osDelay(hlcd->ClearDelay);
uint8_t *menu = (uint8_t *)&hinterface.MenuItems;
int8_t disp_cnt = 0;
disp_cnt -= hinterface.StartMenuItem;
hinterface.DisplayingItems = (const Menu_HandleTypeDef){0};
if(hinterface.MenuNumber == 0)
disp_cnt = LCD_DisplayMenuRegisters(hlcd, menu, disp_cnt);
else
disp_cnt = LCD_DisplayMenuCoils(hlcd, menu, disp_cnt);
// if less than 2 item displayed - decrease start menu item
if(disp_cnt <= 1) hinterface.StartMenuItem--;
osDelay(hlcd->DisplayDelay);
}
uint8_t LCD_DisplayMenuCoils(LCDI2C_HandleTypeDef *hlcd, uint8_t *menu, int8_t disp_cnt)
{
for(int i = 0; i < Menu_Coil_Size; i++)
{
// if first sring is printed
if (disp_cnt%2 == 0)
LCD_Send_CMD(hlcd, 0x80); // set cursor to second string
// if first sring is printed
if (disp_cnt%2 == 1)
LCD_Send_CMD(hlcd, 0xC0); // set cursor to second string
switch(*menu&(1<<(i+NOTHING_COIL_SELECTED)))
{
case Menu_PWM_DC:
disp_cnt++;
if(disp_cnt > 0)
{
hinterface.DisplayingItems.PWM_DC = 1;
if(hinterface.CurrentSelection == NOTHING_COIL_SELECTED)
Display_PWM_DC(hlcd);
else if (hinterface.CurrentSelection == PWM_COIL_DC_SELECTED)
Display_PWM_DC(hlcd);
}
break;
case Menu_PWM_BRIDGE:
disp_cnt++;
if(disp_cnt > 0)
{
hinterface.DisplayingItems.PWM_BRIDGE = 1;
if(hinterface.CurrentSelection == NOTHING_COIL_SELECTED)
Display_PWM_BRIDGE(hlcd);
else if (hinterface.CurrentSelection == PWM_COIL_BRIDGE_SELECTED)
Display_PWM_BRIDGE(hlcd);
}
break;
case Menu_PWM_PHASE:
disp_cnt++;
if(disp_cnt > 0)
{
hinterface.DisplayingItems.PWM_PHASE = 1;
if(hinterface.CurrentSelection == NOTHING_COIL_SELECTED)
Display_PWM_PHASE(hlcd);
else if (hinterface.CurrentSelection == PWM_COIL_PHASE_SELECTED)
Display_PWM_PHASE(hlcd);
}
break;
case Menu_PWM_POLARITY:
disp_cnt++;
if(disp_cnt > 0)
{
hinterface.DisplayingItems.PWM_POLARITY = 1;
if(hinterface.CurrentSelection == NOTHING_COIL_SELECTED)
Display_PWM_POLARITY(hlcd);
else if (hinterface.CurrentSelection == PWM_COIL_POLARITY_SELECTED)
Display_PWM_POLARITY(hlcd);
}
break;
}
// if second sring is printed
if (disp_cnt >= 2)
break; // stop "displaying"
}
return disp_cnt;
}
uint8_t LCD_DisplayMenuRegisters(LCDI2C_HandleTypeDef *hlcd, uint8_t *menu, int8_t disp_cnt)
{
for(int i = 0; i < Menu_Size; i++)
{
// if first sring is printed
if (disp_cnt%2 == 0)
LCD_Send_CMD(hlcd, 0x80); // set cursor to second string
// if first sring is printed
if (disp_cnt%2 == 1)
LCD_Send_CMD(hlcd, 0xC0); // set cursor to second string
switch(*menu&(1<<i))
{
case Menu_PWM_Value:
disp_cnt++;
if(disp_cnt > 0)
{
hinterface.DisplayingItems.PWM_Value = 1;
if(hinterface.CurrentSelection == NOTHING_SELECTED)
Display_PWM_Value(hlcd);
else if (hinterface.CurrentSelection == PWM_VALUE_SELECTED)
Display_PWM_Value(hlcd);
}
break;
case Menu_PWM_Hz:
disp_cnt++;
if(disp_cnt > 0)
{
hinterface.DisplayingItems.PWM_Hz = 1;
if(hinterface.CurrentSelection == NOTHING_SELECTED)
Display_PWM_Hz(hlcd);
else if (hinterface.CurrentSelection == PWM_HZ_SELECTED)
Display_PWM_Hz(hlcd);
}
break;
case Menu_PWM_DutyBridge:
disp_cnt++;
if(disp_cnt > 0)
{
hinterface.DisplayingItems.PWM_DutyBridge = 1;
if(hinterface.CurrentSelection == NOTHING_SELECTED)
Display_PWM_DutyBridge(hlcd);
else if (hinterface.CurrentSelection == PWM_DUTYBRIDGE_SELECTED)
Display_PWM_DutyBridge(hlcd);
}
break;
}
// if second sring is printed
if (disp_cnt >= 2)
break; // stop "displaying"
}
return disp_cnt;
}
void Display_PWM_Value(LCDI2C_HandleTypeDef *hlcd)
{
if(hpwm1.sPWM_Mode&PWM_DC_MODE && ((hpwm1.sPWM_Mode&PWM_BRIDGE_MODE) == 0)) // in dc mode disp pwm duty
{
LCD_Send_STRING(hlcd, "Duty: ");
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_VALUE]/100, 0);
LCD_Send_STRING(hlcd, ".");
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_VALUE]%100, 2);
LCD_Send_STRING(hlcd, "%");
}
else // in dc mode disp sine freq
{
LCD_Send_STRING(hlcd, "Sine: ");
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_VALUE]/100, 0);
LCD_Send_STRING(hlcd, ".");
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_VALUE]%100, 2);
LCD_Send_STRING(hlcd, " Hz");
}
}
void Display_PWM_Hz(LCDI2C_HandleTypeDef *hlcd)
{
LCD_Send_STRING(hlcd, "PWM: ");
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_HZ], 0);
LCD_Send_STRING(hlcd, " Hz");
}
void Display_PWM_DutyBridge(LCDI2C_HandleTypeDef *hlcd)
{
LCD_Send_STRING(hlcd, "Duty: ");
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE]/100, 0);
LCD_Send_STRING(hlcd, ".");
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE]%100, 2);
LCD_Send_STRING(hlcd, "%");
}
void Display_PWM_DC(LCDI2C_HandleTypeDef *hlcd)
{
LCD_Send_STRING(hlcd, "DC: ");
if(hpwm1.sPWM_Config.PWM_Mode->DC)
LCD_Send_STRING(hlcd, "DC");
else
LCD_Send_STRING(hlcd, "Sine");
}
void Display_PWM_BRIDGE(LCDI2C_HandleTypeDef *hlcd)
{
LCD_Send_STRING(hlcd, "Bridge: ");
if(hpwm1.sPWM_Config.PWM_Mode->BRIDGE)
LCD_Send_STRING(hlcd, "Bridge");
else
LCD_Send_STRING(hlcd, "Single");
}
void Display_PWM_PHASE(LCDI2C_HandleTypeDef *hlcd)
{
LCD_Send_STRING(hlcd, "Phase: ");
if(hpwm1.sPWM_Config.PWM_Mode->PHASE)
LCD_Send_STRING(hlcd, "3-Phase");
else
LCD_Send_STRING(hlcd, "One Phase");
}
void Display_PWM_POLARITY(LCDI2C_HandleTypeDef *hlcd)
{
LCD_Send_STRING(hlcd, "Polarity: ");
if(hpwm1.sPWM_Config.PWM_Mode->POLARITY)
LCD_Send_STRING(hlcd, "Neg");
else
LCD_Send_STRING(hlcd, "Pos");
}
/**
* @brief First initialization of Encoder Timer.
* @note This called from main
*/
void EncoderFirstInit(void)
{
hinterface.DoubleClick_Timeout = 200;
// tim settings
TIM_ENCODER.htim.Instance = TIMER_ENCODER_INSTANCE;
TIM_ENCODER.htim.Init.Period = 0xFFFF;
TIM_ENCODER.htim.Init.Prescaler = 0;
TIM_ENCODER.sTimMode = TIM_IT_MODE;
// TIM_ENCODER.sTickBaseMHz = TIMER_ENCODER_TICKBASE;
// TIM_ENCODER.sTimAHBFreqMHz = TIMER_ENCODER_AHB_FREQ;
// TIM_ENCODER.sTimFreqHz = 0;
TIM_Base_Init(&TIM_ENCODER);
henc1.sConfig.EncoderMode = TIM_ENCODERMODE_TI2;
henc1.sConfig.IC1Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
henc1.sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
henc1.sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
henc1.sConfig.IC1Filter = 5;
henc1.sConfig.IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
henc1.sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
henc1.sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
henc1.sConfig.IC2Filter = 5;
henc1.GPIOx = TIMER_ENCODER_PORT;
henc1.GPIO_PIN_TI1 = TIMER_ENCODER_PIN1;
henc1.GPIO_PIN_TI2 = TIMER_ENCODER_PIN2;
henc1.GPIO_PIN_SW = TIMER_ENCODER_PIN_SW;
TIM_Encoder_Init(&henc1, &TIM_ENCODER.htim);
HAL_TIM_Base_Start(&TIM_ENCODER.htim);
}
/**
* @brief First initialization of LCD.
* @note This called from main
*/
void LCD_FirstInit(void)
{
hlcd1.hi2c = &hi2c1;
hlcd1.DisplayDelay = 250;
hlcd1.ClearDelay = 10;
LCD_Init(&hlcd1);
}

View File

@@ -0,0 +1,94 @@
#ifndef __INTERFACE_H_
#define __INTERFACE_H_
#include "periph_general.h"
#include "i2c_lcd.h"
extern LCDI2C_HandleTypeDef hlcd1;
extern TIM_EncoderTypeDef henc1;
typedef enum
{
NOTHING_SELECTED,
PWM_VALUE_SELECTED,
PWM_HZ_SELECTED,
PWM_DUTYBRIDGE_SELECTED,
NOTHING_COIL_SELECTED,
PWM_COIL_DC_SELECTED,
PWM_COIL_BRIDGE_SELECTED,
PWM_COIL_PHASE_SELECTED,
PWM_COIL_POLARITY_SELECTED,
}CurrentSelection_TypeDef;
typedef struct
{
unsigned PWM_Value:1;
unsigned PWM_Hz:1;
unsigned PWM_DutyBridge:1;
unsigned reserved:1;
unsigned PWM_DC:1;
unsigned PWM_BRIDGE:1;
unsigned PWM_PHASE:1;
unsigned PWM_POLARITY:1;
}Menu_HandleTypeDef;
typedef struct
{
Menu_HandleTypeDef MenuItems;
Menu_HandleTypeDef DisplayingItems;
CurrentSelection_TypeDef CurrentSelection;
uint8_t MenuNumber;
unsigned FineChanging:1;
int8_t StartMenuItem;
uint32_t Encoder_Shdw;
uint32_t Switch_Shdw;
uint32_t Switch_prevTick;
uint32_t DoubleClick_Timeout;
}Interface_HandleTypeDef;
#define Menu_Size 3
#define Menu_Coil_Size 4
#define Menu_PWM_Value (1<<0)
#define Menu_PWM_Hz (1<<1)
#define Menu_PWM_DutyBridge (1<<2)
#define Menu_PWM_DC (1<<4)
#define Menu_PWM_BRIDGE (1<<5)
#define Menu_PWM_PHASE (1<<6)
#define Menu_PWM_POLARITY (1<<7)
void UpdateInterfaceStruct(void);
void ReadEncoder(TIM_EncoderTypeDef *henc, LCDI2C_HandleTypeDef *hlcd);
void UpdateLCDDisplay(LCDI2C_HandleTypeDef *hlcd);
void Display_PWM_Value(LCDI2C_HandleTypeDef *hlcd);
void Display_PWM_Hz(LCDI2C_HandleTypeDef *hlcd);
void Display_PWM_DutyBridge(LCDI2C_HandleTypeDef *hlcd);
void Display_PWM_DC(LCDI2C_HandleTypeDef *hlcd);
void Display_PWM_BRIDGE(LCDI2C_HandleTypeDef *hlcd);
void Display_PWM_PHASE(LCDI2C_HandleTypeDef *hlcd);
void Display_PWM_POLARITY(LCDI2C_HandleTypeDef *hlcd);
uint8_t LCD_DisplayMenuCoils(LCDI2C_HandleTypeDef *hlcd, uint8_t *menu, int8_t disp_cnt);
uint8_t LCD_DisplayMenuRegisters(LCDI2C_HandleTypeDef *hlcd, uint8_t *menu, int8_t disp_cnt);
/**
* @brief First initialization of LCD.
* @note This called from main
*/
void LCD_FirstInit(void);
/**
* @brief First initialization of Encoder Timer.
* @note This called from main
*/
void EncoderFirstInit(void);
#endif // __INTERFACE_H_