/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
*
© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* Display timeout, sec */
#define DISP_WDT_TIME 10
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
volatile flag_t Flag = {0};
static rtc_t Clock;
static btn_t Button[BTN_NUM] = {
{0, evBTN1Pressed, evBTN1Holded, BTN1_PIN},
{0, evBTN2Pressed, evBTN2Pressed, BTN2_PIN},
{0, evBTN3Pressed, evBTN3Pressed, BTN3_PIN},
{0, evBTN4Pressed, evBTN4Holded, BTN4_PIN}
};
static volatile uint8_t dispWDT = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
static void btnProcess(void);
static void Color_RGB(uint8_t r, uint8_t g, uint8_t b);
static void ColorCircle(void);
void MinusFadeIn(void);
void MinusFadeOut(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* Initialize onBoard Hardware */
Board_Init();
/* Initialize Scheduler */
RTOS_Init();
/* tdelay_ms() work now, I2C can work too */
RTC_Init();
RTC_ReadAll(&Clock);
sensor_Init();
/* Initialize Event State Machine */
ES_Init(stShowTime);
es_event_t event = eventNull;
/** Set tasks for Sheduler */
RTOS_SetTask(btnProcess, 1, BTN_SCAN_PERIOD);
/* USER CODE BEGIN WHILE */
Color_RGB(0xFF, 0x12, 0x0); // Nixie color. FF1200 or FF7E00 or FFBF00
showTime();
uint8_t oldsec;
/* Infinite loop */
while (1)
{
oldsec = Clock.Sec;
RTC_ReadAll(&Clock);
if (oldsec != Clock.Sec) {
Flag.RTC_IRQ = 1;
ES_PlaceEvent(evNewSecond);
}
/* new second interrupt from RTC */
if (Flag.RTC_IRQ != 0) {
Flag.RTC_IRQ = 0;
ColorCircle();
Blink_Start(); // !!! TODO
RTC_ReadAll(&Clock);
if (dispWDT != 0) {
dispWDT --;
if (dispWDT == 0) {
ES_PlaceEvent(evDisplayWDT);
}
}
} /* end of New second */
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
event = ES_GetEvent();
if (event) {
ES_Dispatch(event);
}
RTOS_DispatchTask();
__WFI();
}
/* USER CODE END 3 */
} /* End of mine() */
/* USER CODE BEGIN 4 */
/*************************
* S U B R O U T I N E S *
*************************/
/**
* @brief Вывод HEX значений цвета в таймер.
* @param : RGB value in range 0x00-0xFF
* @retval : None
*/
static void Color_RGB(uint8_t r, uint8_t g, uint8_t b) {
COLOR_R(r);
COLOR_G(g);
COLOR_B(b);
}
/* cheng led color by time seconds */
static void ColorCircle(void) {
static int16_t hue = 0, stage = 0;
if (stage == 0) {
hue = (Clock.Sec * 6) - 6;
RTOS_SetTask(ColorCircle, 100, 100);
} else if (stage > 4) {
RTOS_DeleteTask(ColorCircle);
stage = 0;
hue ++;
} else {
hue ++;
stage ++;
}
HSV2LED(hue, 255, 255);
}
/**
* @brief Обработка кнопок.
* @param : None
* @retval : None
*/
static void btnProcess(void) {
/* get pin state */
uint32_t pins = BTNS_STATE;
int i;
for (i=0; i= (BTN_TIME_HOLDED/BTN_SCAN_PERIOD)) {
Button[i].time -= (BTN_TIME_REPEATED/BTN_SCAN_PERIOD);
if (Button[i].holded == Button[i].pressed) {
/* if pressed and holded - same function, then button pressed auto repeat */
ES_PlaceEvent(Button[i].pressed);
}
}
} else if (Button[i].time != 0) {
/* button released */
if (Button[i].time >= ((BTN_TIME_HOLDED - BTN_TIME_REPEATED)/BTN_SCAN_PERIOD)) {
/* process long press */
ES_PlaceEvent(Button[i].holded);
} else if (Button[i].time >= (BTN_TIME_PRESSED/BTN_SCAN_PERIOD)) {
/* process short press */
ES_PlaceEvent(Button[i].pressed);
}
Button[i].time = 0;
RTOS_SetTask(btnProcess, BTN_SCAN_PAUSE, BTN_SCAN_PERIOD);
}
} /* end FOR */
}
/**
* On/off symbols on IN-15 tube.
*/
void in15Off(void) {
IN15_OFF;
TUBE_C_OFF;
}
void in15Minus(void) {
IN15_OFF;
IN15_Minus;
TUBE_C_ON;
}
void MinusFadeIn(void) {
static uint8_t cnt = 0;
TUBE_C_ON;
switch (cnt) {
case 0:
IN15_Minus;
RTOS_DeleteTask(MinusFadeOut);
RTOS_SetTask(MinusFadeIn, 2, 0);
break;
case 1:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 18, 0);
break;
case 2:
IN15_Minus;
RTOS_SetTask(MinusFadeIn, 4, 0);
break;
case 3:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 16, 0);
break;
case 4:
IN15_Minus;
RTOS_SetTask(MinusFadeIn, 6, 0);
break;
case 5:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 14, 0);
break;
case 6:
IN15_Minus;
RTOS_SetTask(MinusFadeIn, 8, 0);
break;
case 7:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 12, 0);
break;
case 8:
IN15_Minus;
RTOS_SetTask(MinusFadeIn, 10, 0);
break;
case 9:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 10, 0);
break;
case 10:
IN15_Minus;
RTOS_SetTask(MinusFadeIn, 12, 0);
break;
case 11:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 8, 0);
break;
case 12:
IN15_Minus;
RTOS_SetTask(MinusFadeIn, 14, 0);
break;
case 13:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 6, 0);
break;
case 14:
IN15_Minus;
RTOS_SetTask(MinusFadeIn, 16, 0);
break;
case 15:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 4, 0);
break;
case 16:
IN15_Minus;
RTOS_SetTask(MinusFadeIn, 18, 0);
break;
case 17:
IN15_OFF;
RTOS_SetTask(MinusFadeIn, 2, 0);
break;
case 18:
IN15_Minus;
cnt = 0;
return;
break;
default:
cnt = 0;
break;
}
cnt ++;
}
void MinusFadeOut(void) {
static uint8_t off = 0;
static uint8_t on = 20;
static uint8_t st = 0;
if (st == 0) {
st = 1;
IN15_OFF;
off += 2;
if (off < 20) {
RTOS_SetTask(MinusFadeOut, off, 0);
} else {
off = 0; on = 20; st = 0;
}
} else {
st = 0;
IN15_Minus;
on -= 2;
RTOS_SetTask(MinusFadeOut, on, 0);
}
}
void in15Plus(void) {
IN15_OFF;
IN15_Plus;
TUBE_C_ON;
}
void in15Percent(void) {
IN15_OFF;
IN15_Percent;
TUBE_C_ON;
}
void in15P(void) {
IN15_OFF;
IN15_P;
TUBE_C_ON;
}
/**
* Show info on tubes.
*/
void showTime(void) {
//in15Minus();
//RTOS_SetTask(in15Off, 500, 0);
MinusFadeIn();
RTOS_SetTask(MinusFadeOut, 500, 0);
uint8_t buf[4];
buf[Tube_A] = Clock.Hr >> 4;
buf[Tube_B] = Clock.Hr & 0xf;
buf[Tube_D] = Clock.Min >> 4;
buf[Tube_E] = Clock.Min & 0xf;
showDigits(buf);
}
void showWD(void) {
dispWDT = DISP_WDT_TIME;
IN15_OFF;
uint8_t buf[4];
buf[Tube_A] = 0xf;
buf[Tube_B] = Clock.WD & 0xf;
buf[Tube_D] = 0xf;
buf[Tube_E] = 0xf;
showDigits(buf);
}
void showDay(void) {
dispWDT = DISP_WDT_TIME;
IN15_OFF;
uint8_t buf[4];
buf[Tube_A] = Clock.Day >> 4;
buf[Tube_B] = Clock.Day & 0xf;
buf[Tube_D] = 0xf;
buf[Tube_E] = 0xf;
showDigits(buf);
}
void showMonth(void) {
dispWDT = DISP_WDT_TIME;
IN15_OFF;
uint8_t buf[4];
buf[Tube_A] = 0xf;
buf[Tube_B] = 0xf;
buf[Tube_D] = Clock.Mon >> 4;
buf[Tube_E] = Clock.Mon & 0xf;
showDigits(buf);
}
void showDayMon(void) {
dispWDT = DISP_WDT_TIME;
IN15_OFF;
uint8_t buf[4];
buf[Tube_A] = Clock.Day >> 4;
buf[Tube_B] = Clock.Day & 0xf;
buf[Tube_D] = Clock.Mon >> 4;
buf[Tube_E] = Clock.Mon & 0xf;
showDigits(buf);
}
void showYear(void) {
dispWDT = DISP_WDT_TIME;
IN15_OFF;
uint8_t buf[4];
buf[Tube_A] = 2;
buf[Tube_B] = 0;
buf[Tube_D] = Clock.Year >> 4;
buf[Tube_E] = Clock.Year & 0xf;
showDigits(buf);
}
void showHumidity(void) {
dispWDT = DISP_WDT_TIME;
in15Percent();
uint8_t buf[4];
buf[Tube_A] = Humidity / 10;
buf[Tube_B] = Humidity % 10;
buf[Tube_D] = 0xf;
buf[Tube_E] = 0xf;
showDigits(buf);
}
void showTemperature(void) {
dispWDT = DISP_WDT_TIME;
in15Plus();
uint8_t buf[4];
buf[Tube_A] = 0xf;
buf[Tube_B] = 0xf;
buf[Tube_D] = Temperature / 10;
buf[Tube_E] = Temperature % 10;
showDigits(buf);
}
void showPressure(void) {
dispWDT = DISP_WDT_TIME;
in15P();
uint8_t buf[4];
int tmp;
buf[Tube_A] = 0xf;
buf[Tube_B] = Pressure / 100;
tmp = Pressure % 100;
buf[Tube_D] = tmp / 10;
buf[Tube_E] = tmp % 10;
showDigits(buf);
}
/* Simple function for cyclic show all sensor data */
void showSensorData(void) {
ES_SetState(stShowSensorData);
RTOS_DeleteTask(in15Off);
showTemperature();
tdelay_ms(3000);
showHumidity();
tdelay_ms(3000);
showPressure();
tdelay_ms(3000);
ES_SetState(stShowTime);
showTime();
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/