mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-19 17:26:38 +00:00
Add Windows client
This commit is contained in:
parent
027ffa983f
commit
a70eb1fd5f
75
hal/sdl2/app_hal.c
Normal file
75
hal/sdl2/app_hal.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include "display/monitor.h"
|
||||||
|
#include "indev/mouse.h"
|
||||||
|
#include "indev/mousewheel.h"
|
||||||
|
#include "indev/keyboard.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A task to measure the elapsed time for LittlevGL
|
||||||
|
* @param data unused
|
||||||
|
* @return never return
|
||||||
|
*/
|
||||||
|
static int tick_thread(void * data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
SDL_Delay(5); /*Sleep for 5 millisecond*/
|
||||||
|
lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void hal_setup(void)
|
||||||
|
{
|
||||||
|
// Workaround for sdl2 `-m32` crash
|
||||||
|
// https://bugs.launchpad.net/ubuntu/+source/libsdl2/+bug/1775067/comments/7
|
||||||
|
#ifndef WIN32
|
||||||
|
setenv("DBUS_FATAL_WARNINGS", "0", 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Add a display
|
||||||
|
* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/
|
||||||
|
monitor_init();
|
||||||
|
/* Tick init.
|
||||||
|
* You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed
|
||||||
|
* Create an SDL thread to do this*/
|
||||||
|
SDL_CreateThread(tick_thread, "tick", NULL);
|
||||||
|
|
||||||
|
lv_init();
|
||||||
|
static lv_disp_buf_t disp_buf;
|
||||||
|
static lv_color_t buf[LV_HOR_RES_MAX * 10]; /*Declare a buffer for 10 lines*/
|
||||||
|
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||||
|
|
||||||
|
lv_disp_drv_t disp_drv;
|
||||||
|
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||||
|
disp_drv.flush_cb = monitor_flush; /*Used when `LV_VDB_SIZE != 0` in lv_conf.h (buffered drawing)*/
|
||||||
|
disp_drv.buffer = &disp_buf;
|
||||||
|
//disp_drv.disp_fill = monitor_fill; /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/
|
||||||
|
//disp_drv.disp_map = monitor_map; /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/
|
||||||
|
lv_disp_drv_register(&disp_drv);
|
||||||
|
|
||||||
|
/* Add the mouse as input device
|
||||||
|
* Use the 'mouse' driver which reads the PC's mouse*/
|
||||||
|
mouse_init();
|
||||||
|
lv_indev_drv_t indev_drv;
|
||||||
|
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
|
||||||
|
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||||
|
indev_drv.read_cb = mouse_read; /*This function will be called periodically (by the library) to get the mouse position and state*/
|
||||||
|
lv_indev_drv_register(&indev_drv);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void hal_loop(void)
|
||||||
|
{
|
||||||
|
/*while(1)*/ {
|
||||||
|
SDL_Delay(5);
|
||||||
|
lv_task_handler();
|
||||||
|
}
|
||||||
|
}
|
17
hal/sdl2/app_hal.h
Normal file
17
hal/sdl2/app_hal.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef DRIVER_H
|
||||||
|
#define DRIVER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void hal_setup(void);
|
||||||
|
void hal_loop(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*DRIVER_H*/
|
50
hal/stm32f407_btt/app_hal.c
Normal file
50
hal/stm32f407_btt/app_hal.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
//#include "stm32f429i_discovery.h"
|
||||||
|
#include "tft.h"
|
||||||
|
//#include "touchpad.h"
|
||||||
|
|
||||||
|
#ifdef USE_RTOS_SYSTICK
|
||||||
|
#include <cmsis_os.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void hal_setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PD12, OUTPUT);
|
||||||
|
digitalWrite(PD12, HIGH);
|
||||||
|
|
||||||
|
// HAL_Init();
|
||||||
|
|
||||||
|
// /* Configure the system clock to 180 MHz */
|
||||||
|
// SystemClock_Config();
|
||||||
|
|
||||||
|
// /* Start up indication */
|
||||||
|
// BSP_LED_Init(LED3);
|
||||||
|
// for (uint8_t i = 0; i < 8; i++) { BSP_LED_Toggle(LED3); delay(50); }
|
||||||
|
|
||||||
|
tft_init();
|
||||||
|
//touchpad_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
// void SysTick_Handler(void)
|
||||||
|
// {
|
||||||
|
// HAL_IncTick();
|
||||||
|
// HAL_SYSTICK_IRQHandler();
|
||||||
|
|
||||||
|
// lv_tick_inc(1);
|
||||||
|
|
||||||
|
// #ifdef USE_RTOS_SYSTICK
|
||||||
|
// osSystickHandler();
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
|
||||||
|
void hal_loop(void)
|
||||||
|
{
|
||||||
|
//while (1)
|
||||||
|
{
|
||||||
|
delay(5);
|
||||||
|
lv_task_handler();
|
||||||
|
}
|
||||||
|
}
|
17
hal/stm32f407_btt/app_hal.h
Normal file
17
hal/stm32f407_btt/app_hal.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef DRIVER_H
|
||||||
|
#define DRIVER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void hal_setup(void);
|
||||||
|
void hal_loop(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*DRIVER_H*/
|
65
hal/stm32f407_btt/tft.c
Normal file
65
hal/stm32f407_btt/tft.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* @file disp.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "tft.h"
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "fsmc_ssd1963.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC VARIABLES
|
||||||
|
**********************/
|
||||||
|
static lv_disp_drv_t disp_drv;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
/**
|
||||||
|
* Initialize your display here
|
||||||
|
*/
|
||||||
|
void tft_init(void)
|
||||||
|
{
|
||||||
|
static lv_color_t disp_buf1[TFT_HOR_RES * 40];
|
||||||
|
static lv_disp_buf_t buf;
|
||||||
|
lv_disp_buf_init(&buf, disp_buf1, NULL, TFT_HOR_RES * 40);
|
||||||
|
|
||||||
|
lv_disp_drv_init(&disp_drv);
|
||||||
|
fsmc_ssd1963_init(0, false);
|
||||||
|
|
||||||
|
disp_drv.buffer = &buf;
|
||||||
|
disp_drv.flush_cb = fsmc_ssd1963_flush;
|
||||||
|
disp_drv.hor_res = TFT_HOR_RES;
|
||||||
|
disp_drv.ver_res = TFT_VER_RES;
|
||||||
|
#if TFT_USE_GPU != 0
|
||||||
|
DMA2D_Config();
|
||||||
|
disp_drv.gpu_blend_cb = gpu_mem_blend;
|
||||||
|
disp_drv.gpu_fill_cb = gpu_mem_fill;
|
||||||
|
#endif
|
||||||
|
lv_disp_drv_register(&disp_drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC FUNCTIONS
|
||||||
|
**********************/
|
37
hal/stm32f407_btt/tft.h
Normal file
37
hal/stm32f407_btt/tft.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* @file disp.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DISP_H
|
||||||
|
#define DISP_H
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "lvgl.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
#define TFT_HOR_RES TFT_WIDTH
|
||||||
|
#define TFT_VER_RES TFT_HEIGHT
|
||||||
|
|
||||||
|
#define TFT_EXT_FB 1 /*Frame buffer is located into an external SDRAM*/
|
||||||
|
#define TFT_USE_GPU 0 /*Enable hardware accelerator*/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
void tft_init(void);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#endif
|
123
hal/stm32f429_disco/app_hal.c
Normal file
123
hal/stm32f429_disco/app_hal.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "stm32f429i_discovery.h"
|
||||||
|
#include "tft.h"
|
||||||
|
#include "touchpad.h"
|
||||||
|
|
||||||
|
#ifdef USE_RTOS_SYSTICK
|
||||||
|
#include <cmsis_os.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System Clock Configuration
|
||||||
|
* The system Clock is configured as follow :
|
||||||
|
* System Clock source = PLL (HSE)
|
||||||
|
* SYSCLK(Hz) = 180000000
|
||||||
|
* HCLK(Hz) = 180000000
|
||||||
|
* AHB Prescaler = 1
|
||||||
|
* APB1 Prescaler = 4
|
||||||
|
* APB2 Prescaler = 2
|
||||||
|
* HSE Frequency(Hz) = 8000000
|
||||||
|
* PLL_M = 8
|
||||||
|
* PLL_N = 360
|
||||||
|
* PLL_P = 2
|
||||||
|
* PLL_Q = 7
|
||||||
|
* VDD(V) = 3.3
|
||||||
|
* Main regulator output voltage = Scale1 mode
|
||||||
|
* Flash Latency(WS) = 5
|
||||||
|
* The LTDC Clock is configured as follow :
|
||||||
|
* PLLSAIN = 192
|
||||||
|
* PLLSAIR = 4
|
||||||
|
* PLLSAIDivR = 8
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void SystemClock_Config(void)
|
||||||
|
{
|
||||||
|
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||||
|
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||||||
|
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
|
||||||
|
|
||||||
|
/* Enable Power Control clock */
|
||||||
|
__HAL_RCC_PWR_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* The voltage scaling allows optimizing the power consumption when the device is
|
||||||
|
clocked below the maximum system frequency, to update the voltage scaling value
|
||||||
|
regarding system frequency refer to product datasheet. */
|
||||||
|
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||||
|
|
||||||
|
/*##-1- System Clock Configuration #########################################*/
|
||||||
|
/* Enable HSE Oscillator and activate PLL with HSE as source */
|
||||||
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||||
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||||
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
|
RCC_OscInitStruct.PLL.PLLM = 8;
|
||||||
|
RCC_OscInitStruct.PLL.PLLN = 360;
|
||||||
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
||||||
|
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||||
|
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||||||
|
|
||||||
|
/* Activate the Over-Drive mode */
|
||||||
|
HAL_PWREx_EnableOverDrive();
|
||||||
|
|
||||||
|
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
|
||||||
|
clocks dividers */
|
||||||
|
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
|
||||||
|
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||||
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||||
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
|
||||||
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
|
||||||
|
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
|
||||||
|
|
||||||
|
/*##-2- LTDC Clock Configuration ###########################################*/
|
||||||
|
/* LCD clock configuration */
|
||||||
|
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 MHz */
|
||||||
|
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 MHz */
|
||||||
|
/* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/4 = 48 MHz */
|
||||||
|
/* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDIVR_8 = 48/8 = 6 MHz */
|
||||||
|
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
||||||
|
PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
|
||||||
|
PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
|
||||||
|
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
|
||||||
|
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void hal_setup(void)
|
||||||
|
{
|
||||||
|
HAL_Init();
|
||||||
|
|
||||||
|
/* Configure the system clock to 180 MHz */
|
||||||
|
SystemClock_Config();
|
||||||
|
|
||||||
|
/* Start up indication */
|
||||||
|
BSP_LED_Init(LED3);
|
||||||
|
for (uint8_t i = 0; i < 8; i++) { BSP_LED_Toggle(LED3); HAL_Delay(50); }
|
||||||
|
|
||||||
|
tft_init();
|
||||||
|
touchpad_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SysTick_Handler(void)
|
||||||
|
{
|
||||||
|
HAL_IncTick();
|
||||||
|
HAL_SYSTICK_IRQHandler();
|
||||||
|
|
||||||
|
lv_tick_inc(1);
|
||||||
|
|
||||||
|
#ifdef USE_RTOS_SYSTICK
|
||||||
|
osSystickHandler();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void hal_loop(void)
|
||||||
|
{
|
||||||
|
while(1) {
|
||||||
|
HAL_Delay(5);
|
||||||
|
lv_task_handler();
|
||||||
|
}
|
||||||
|
}
|
17
hal/stm32f429_disco/app_hal.h
Normal file
17
hal/stm32f429_disco/app_hal.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef DRIVER_H
|
||||||
|
#define DRIVER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void hal_setup(void);
|
||||||
|
void hal_loop(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*DRIVER_H*/
|
236
hal/stm32f429_disco/tft.c
Normal file
236
hal/stm32f429_disco/tft.c
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
/**
|
||||||
|
* @file disp.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "tft.h"
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "stm32f429i_discovery_lcd.h"
|
||||||
|
#include "ili9341.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
#define SDRAM_BANK_ADDR ((uint32_t)0xD0000000)
|
||||||
|
|
||||||
|
#define DMA_STREAM DMA2_Stream0
|
||||||
|
#define DMA_CHANNEL DMA_CHANNEL_0
|
||||||
|
#define DMA_STREAM_IRQ DMA2_Stream0_IRQn
|
||||||
|
#define DMA_STREAM_IRQHANDLER DMA2_Stream0_IRQHandler
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
static void tft_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC VARIABLES
|
||||||
|
**********************/
|
||||||
|
extern LTDC_HandleTypeDef LtdcHandler;
|
||||||
|
|
||||||
|
#if TFT_USE_GPU != 0
|
||||||
|
static DMA2D_HandleTypeDef Dma2dHandle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TFT_EXT_FB != 0
|
||||||
|
static __IO uint16_t *my_fb = (__IO uint16_t *)(SDRAM_BANK_ADDR);
|
||||||
|
#else
|
||||||
|
static uint16_t my_fb[TFT_HOR_RES * TFT_VER_RES];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*DMA to flush to frame buffer*/
|
||||||
|
static void DMA_Config(void);
|
||||||
|
static void DMA_TransferComplete(DMA_HandleTypeDef *han);
|
||||||
|
static void DMA_TransferError(DMA_HandleTypeDef *han);
|
||||||
|
|
||||||
|
DMA_HandleTypeDef DmaHandle;
|
||||||
|
static lv_disp_drv_t disp_drv;
|
||||||
|
static int32_t x1_flush;
|
||||||
|
static int32_t y1_flush;
|
||||||
|
static int32_t x2_flush;
|
||||||
|
static int32_t y2_fill;
|
||||||
|
static int32_t y_fill_act;
|
||||||
|
static const lv_color_t *buf_to_flush;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
/**
|
||||||
|
* Initialize your display here
|
||||||
|
*/
|
||||||
|
void tft_init(void)
|
||||||
|
{
|
||||||
|
static lv_color_t disp_buf1[TFT_HOR_RES * 40];
|
||||||
|
static lv_disp_buf_t buf;
|
||||||
|
lv_disp_buf_init(&buf, disp_buf1, NULL, TFT_HOR_RES * 40);
|
||||||
|
|
||||||
|
lv_disp_drv_init(&disp_drv);
|
||||||
|
|
||||||
|
BSP_LCD_Init();
|
||||||
|
BSP_LCD_LayerDefaultInit(0, (uint32_t)my_fb);
|
||||||
|
HAL_LTDC_SetPixelFormat(&LtdcHandler, LTDC_PIXEL_FORMAT_RGB565, 0);
|
||||||
|
DMA_Config();
|
||||||
|
disp_drv.buffer = &buf;
|
||||||
|
disp_drv.flush_cb = tft_flush;
|
||||||
|
disp_drv.hor_res = TFT_HOR_RES;
|
||||||
|
disp_drv.ver_res = TFT_VER_RES;
|
||||||
|
#if TFT_USE_GPU != 0
|
||||||
|
DMA2D_Config();
|
||||||
|
disp_drv.gpu_blend_cb = gpu_mem_blend;
|
||||||
|
disp_drv.gpu_fill_cb = gpu_mem_fill;
|
||||||
|
#endif
|
||||||
|
lv_disp_drv_register(&disp_drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush a color buffer
|
||||||
|
* @param x1 left coordinate of the rectangle
|
||||||
|
* @param x2 right coordinate of the rectangle
|
||||||
|
* @param y1 top coordinate of the rectangle
|
||||||
|
* @param y2 bottom coordinate of the rectangle
|
||||||
|
* @param color_p pointer to an array of colors
|
||||||
|
*/
|
||||||
|
static void tft_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p)
|
||||||
|
{
|
||||||
|
/*Return if the area is out the screen*/
|
||||||
|
if (area->x2 < 0)
|
||||||
|
return;
|
||||||
|
if (area->y2 < 0)
|
||||||
|
return;
|
||||||
|
if (area->x1 > TFT_HOR_RES - 1)
|
||||||
|
return;
|
||||||
|
if (area->y1 > TFT_VER_RES - 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*Truncate the area to the screen*/
|
||||||
|
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
|
||||||
|
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
|
||||||
|
int32_t act_x2 = area->x2 > TFT_HOR_RES - 1 ? TFT_HOR_RES - 1 : area->x2;
|
||||||
|
int32_t act_y2 = area->y2 > TFT_VER_RES - 1 ? TFT_VER_RES - 1 : area->y2;
|
||||||
|
|
||||||
|
x1_flush = act_x1;
|
||||||
|
y1_flush = act_y1;
|
||||||
|
x2_flush = act_x2;
|
||||||
|
y2_fill = act_y2;
|
||||||
|
y_fill_act = act_y1;
|
||||||
|
buf_to_flush = color_p;
|
||||||
|
|
||||||
|
/*##-7- Start the DMA transfer using the interrupt mode #*/
|
||||||
|
/* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */
|
||||||
|
/* Enable All the DMA interrupts */
|
||||||
|
HAL_StatusTypeDef err;
|
||||||
|
err = HAL_DMA_Start_IT(&DmaHandle, (uint32_t)buf_to_flush, (uint32_t)&my_fb[y_fill_act * TFT_HOR_RES + x1_flush],
|
||||||
|
(x2_flush - x1_flush + 1));
|
||||||
|
if (err != HAL_OK)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
; /*Halt on error*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DMA_Config(void)
|
||||||
|
{
|
||||||
|
/*## -1- Enable DMA2 clock #################################################*/
|
||||||
|
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||||
|
|
||||||
|
/*##-2- Select the DMA functional Parameters ###############################*/
|
||||||
|
DmaHandle.Init.Channel = DMA_CHANNEL; /* DMA_CHANNEL_0 */
|
||||||
|
DmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY; /* M2M transfer mode */
|
||||||
|
DmaHandle.Init.PeriphInc = DMA_PINC_ENABLE; /* Peripheral increment mode Enable */
|
||||||
|
DmaHandle.Init.MemInc = DMA_MINC_ENABLE; /* Memory increment mode Enable */
|
||||||
|
DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; /* Peripheral data alignment : 16bit */
|
||||||
|
DmaHandle.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD; /* memory data alignment : 16bit */
|
||||||
|
DmaHandle.Init.Mode = DMA_NORMAL; /* Normal DMA mode */
|
||||||
|
DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; /* priority level : high */
|
||||||
|
DmaHandle.Init.FIFOMode = DMA_FIFOMODE_ENABLE; /* FIFO mode enabled */
|
||||||
|
DmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; /* FIFO threshold: 1/4 full */
|
||||||
|
DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE; /* Memory burst */
|
||||||
|
DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE; /* Peripheral burst */
|
||||||
|
|
||||||
|
/*##-3- Select the DMA instance to be used for the transfer : DMA2_Stream0 #*/
|
||||||
|
DmaHandle.Instance = DMA_STREAM;
|
||||||
|
|
||||||
|
/*##-4- Initialize the DMA stream ##########################################*/
|
||||||
|
if (HAL_DMA_Init(&DmaHandle) != HAL_OK)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*##-5- Select Callbacks functions called after Transfer complete and Transfer error */
|
||||||
|
HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_CPLT_CB_ID, DMA_TransferComplete);
|
||||||
|
HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_ERROR_CB_ID, DMA_TransferError);
|
||||||
|
|
||||||
|
/*##-6- Configure NVIC for DMA transfer complete/error interrupts ##########*/
|
||||||
|
HAL_NVIC_SetPriority(DMA_STREAM_IRQ, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(DMA_STREAM_IRQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA conversion complete callback
|
||||||
|
* @note This function is executed when the transfer complete interrupt
|
||||||
|
* is generated
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void DMA_TransferComplete(DMA_HandleTypeDef *han)
|
||||||
|
{
|
||||||
|
y_fill_act++;
|
||||||
|
|
||||||
|
if (y_fill_act > y2_fill)
|
||||||
|
{
|
||||||
|
lv_disp_flush_ready(&disp_drv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf_to_flush += x2_flush - x1_flush + 1;
|
||||||
|
/*##-7- Start the DMA transfer using the interrupt mode ####################*/
|
||||||
|
/* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */
|
||||||
|
/* Enable All the DMA interrupts */
|
||||||
|
if (HAL_DMA_Start_IT(han, (uint32_t)buf_to_flush, (uint32_t)&my_fb[y_fill_act * TFT_HOR_RES + x1_flush],
|
||||||
|
(x2_flush - x1_flush + 1)) != HAL_OK)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
; /*Halt on error*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA conversion error callback
|
||||||
|
* @note This function is executed when the transfer error interrupt
|
||||||
|
* is generated during DMA transfer
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void DMA_TransferError(DMA_HandleTypeDef *han)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles DMA Stream interrupt request.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void DMA_STREAM_IRQHANDLER(void)
|
||||||
|
{
|
||||||
|
/* Check the interrupt and clear flag */
|
||||||
|
HAL_DMA_IRQHandler(&DmaHandle);
|
||||||
|
}
|
37
hal/stm32f429_disco/tft.h
Normal file
37
hal/stm32f429_disco/tft.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* @file disp.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DISP_H
|
||||||
|
#define DISP_H
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "lvgl.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
#define TFT_HOR_RES 240
|
||||||
|
#define TFT_VER_RES 320
|
||||||
|
|
||||||
|
#define TFT_EXT_FB 1 /*Frame buffer is located into an external SDRAM*/
|
||||||
|
#define TFT_USE_GPU 0 /*Enable hardware accelerator*/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
void tft_init(void);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#endif
|
144
hal/stm32f429_disco/touchpad.c
Normal file
144
hal/stm32f429_disco/touchpad.c
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/**
|
||||||
|
* @file indev.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "tft.h"
|
||||||
|
#include "lvgl.h"
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "stm32f429i_discovery.h"
|
||||||
|
#include "stmpe811.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
static bool touchpad_read(lv_indev_drv_t * drv, lv_indev_data_t *data);
|
||||||
|
static bool touchpad_get_xy(int16_t *x, int16_t *y);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC VARIABLES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize your input devices here
|
||||||
|
*/
|
||||||
|
void touchpad_init(void)
|
||||||
|
{
|
||||||
|
stmpe811_Init(TS_I2C_ADDRESS);
|
||||||
|
stmpe811_TS_Start(TS_I2C_ADDRESS);
|
||||||
|
|
||||||
|
lv_indev_drv_t indev_drv;
|
||||||
|
lv_indev_drv_init(&indev_drv);
|
||||||
|
indev_drv.read_cb = touchpad_read;
|
||||||
|
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||||
|
lv_indev_drv_register(&indev_drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an input device
|
||||||
|
* @param indev_id id of the input device to read
|
||||||
|
* @param x put the x coordinate here
|
||||||
|
* @param y put the y coordinate here
|
||||||
|
* @return true: the device is pressed, false: released
|
||||||
|
*/
|
||||||
|
static bool touchpad_read(lv_indev_drv_t * drv, lv_indev_data_t *data)
|
||||||
|
{
|
||||||
|
static int16_t last_x = 0;
|
||||||
|
static int16_t last_y = 0;
|
||||||
|
|
||||||
|
bool detected;
|
||||||
|
int16_t x;
|
||||||
|
int16_t y;
|
||||||
|
detected = touchpad_get_xy(&x, &y);
|
||||||
|
if(detected) {
|
||||||
|
data->point.x = x;
|
||||||
|
data->point.y = y;
|
||||||
|
last_x = data->point.x;
|
||||||
|
last_y = data->point.y;
|
||||||
|
|
||||||
|
data->state = LV_INDEV_STATE_PR;
|
||||||
|
} else {
|
||||||
|
data->point.x = last_x;
|
||||||
|
data->point.y = last_y;
|
||||||
|
data->state = LV_INDEV_STATE_REL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool touchpad_get_xy(int16_t *x, int16_t *y)
|
||||||
|
{
|
||||||
|
static int32_t _x = 0, _y = 0;
|
||||||
|
int16_t xDiff, yDiff, xr, yr, x_raw, y_raw;;
|
||||||
|
|
||||||
|
bool detected;
|
||||||
|
detected = stmpe811_TS_DetectTouch(TS_I2C_ADDRESS);
|
||||||
|
|
||||||
|
if(!detected) return false;
|
||||||
|
|
||||||
|
|
||||||
|
stmpe811_TS_GetXY(TS_I2C_ADDRESS, &x_raw, &y_raw);
|
||||||
|
|
||||||
|
/* Y value first correction */
|
||||||
|
y_raw -= 360;
|
||||||
|
|
||||||
|
/* Y value second correction */
|
||||||
|
yr = y_raw / 11;
|
||||||
|
|
||||||
|
/* Return y_raw position value */
|
||||||
|
if(yr <= 0) yr = 0;
|
||||||
|
else if (yr > TFT_VER_RES) yr = TFT_VER_RES - 1;
|
||||||
|
|
||||||
|
y_raw = yr;
|
||||||
|
|
||||||
|
/* X value first correction */
|
||||||
|
if(x_raw <= 3000) x_raw = 3870 - x_raw;
|
||||||
|
else x_raw = 3800 - x_raw;
|
||||||
|
|
||||||
|
/* X value second correction */
|
||||||
|
xr = x_raw / 15;
|
||||||
|
|
||||||
|
/* Return X position value */
|
||||||
|
if(xr <= 0) xr = 0;
|
||||||
|
else if (xr > TFT_HOR_RES) xr = TFT_HOR_RES - 1;
|
||||||
|
|
||||||
|
x_raw = xr;
|
||||||
|
xDiff = x_raw > _x? (x_raw - _x): (_x - x_raw);
|
||||||
|
yDiff = y_raw > _y? (y_raw - _y): (_y - y_raw);
|
||||||
|
|
||||||
|
if (xDiff + yDiff > 5) {
|
||||||
|
_x = x_raw;
|
||||||
|
_y = y_raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the X and Y position */
|
||||||
|
*x = _x;
|
||||||
|
*y = _y;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
32
hal/stm32f429_disco/touchpad.h
Normal file
32
hal/stm32f429_disco/touchpad.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* @file indev.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INDEV_H
|
||||||
|
#define INDEV_H
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
void touchpad_init(void);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#endif
|
7
include/VersionInfo.h
Normal file
7
include/VersionInfo.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef VERSIONINFO_H
|
||||||
|
#define VERSIONINFO_H
|
||||||
|
|
||||||
|
#define BUILD_TIMESTAMP "@BUILD_TIMESTAMP@"
|
||||||
|
#define CLIENT_VERSION "@CLIENT_VERSION@"
|
||||||
|
|
||||||
|
#endif /* VERSIONINFO_H */
|
@ -1,6 +1,9 @@
|
|||||||
#ifndef HASP_CONF_H
|
#ifndef HASP_CONF_H
|
||||||
#define HASP_CONF_H
|
#define HASP_CONF_H
|
||||||
|
|
||||||
|
// language specific defines
|
||||||
|
#include "lang/lang.h"
|
||||||
|
|
||||||
#define HASP_USE_APP 1
|
#define HASP_USE_APP 1
|
||||||
|
|
||||||
#ifndef HASP_USE_DEBUG
|
#ifndef HASP_USE_DEBUG
|
||||||
@ -101,7 +104,12 @@
|
|||||||
#define HASP_OBJECT_NOTATION "p%ub%u"
|
#define HASP_OBJECT_NOTATION "p%ub%u"
|
||||||
|
|
||||||
/* Includes */
|
/* Includes */
|
||||||
#include <Arduino.h>
|
#ifdef WINDOWS
|
||||||
|
#include "winsock2.h"
|
||||||
|
#include "Windows.h"
|
||||||
|
#else
|
||||||
|
#include "Arduino.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HASP_USE_SPIFFS > 0
|
#if HASP_USE_SPIFFS > 0
|
||||||
// #if defined(ARDUINO_ARCH_ESP32)
|
// #if defined(ARDUINO_ARCH_ESP32)
|
||||||
@ -132,7 +140,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HASP_USE_WIFI > 0
|
#if HASP_USE_WIFI > 0
|
||||||
#include "net/hasp_wifi.h"
|
#include "sys/net/hasp_wifi.h"
|
||||||
|
|
||||||
#if defined(STM32F4xx)
|
#if defined(STM32F4xx)
|
||||||
#include "WiFiSpi.h"
|
#include "WiFiSpi.h"
|
||||||
@ -173,11 +181,18 @@ static WiFiSpiClass WiFi;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HASP_USE_MQTT > 0
|
#if HASP_USE_MQTT > 0
|
||||||
#include "svc/hasp_mqtt.h"
|
#include "mqtt/hasp_mqtt.h"
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
#define USE_PAHO
|
||||||
|
#else
|
||||||
|
#define USE_PUBSUBCLIENT
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HASP_USE_GPIO > 0
|
#if HASP_USE_GPIO > 0
|
||||||
#include "hasp_gpio.h"
|
#include "sys/gpio/hasp_gpio.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HASP_USE_HTTP > 0
|
#if HASP_USE_HTTP > 0
|
||||||
@ -215,4 +230,54 @@ static WiFiSpiClass WiFi;
|
|||||||
#define PGM_P const char *
|
#define PGM_P const char *
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __FlashStringHelper
|
||||||
|
#define __FlashStringHelper char
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FPSTR
|
||||||
|
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PGM_P
|
||||||
|
#define PGM_P const char *
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef F
|
||||||
|
#define F(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PSTR
|
||||||
|
#define PSTR(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PROGMEM
|
||||||
|
#define PROGMEM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
#define snprintf_P snprintf
|
||||||
|
#define memcpy_P memcpy
|
||||||
|
#define strcasecmp_P strcmp // TODO: should be strcasecmp
|
||||||
|
#define strcmp_P strcmp
|
||||||
|
#define strstr_P strstr
|
||||||
|
#define halRestartMcu()
|
||||||
|
#define delay Sleep
|
||||||
|
#define millis SDL_GetTicks
|
||||||
|
|
||||||
|
#define DEC 10
|
||||||
|
#define HEX 16
|
||||||
|
#define BIN 2
|
||||||
|
|
||||||
|
#define guiGetDim() 255
|
||||||
|
#define guiSetDim(x)
|
||||||
|
#define guiGetBacklight() 1
|
||||||
|
#define guiSetBacklight(x)
|
||||||
|
#define guiCalibrate()
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // HASP_CONF_H
|
#endif // HASP_CONF_H
|
@ -1,14 +1,21 @@
|
|||||||
#ifndef HASP_MACRO_H
|
#ifndef HASP_MACRO_H
|
||||||
#define HASP_MACRO_H
|
#define HASP_MACRO_H
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
#define LOG_OUTPUT(x, ...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LOG_OUTPUT(...) Log.output(...)
|
||||||
|
|
||||||
#if HASP_LOG_LEVEL > LOG_LEVEL_FATAL
|
#if HASP_LOG_LEVEL > LOG_LEVEL_FATAL
|
||||||
#define LOG_FATAL(...) \
|
#define LOG_FATAL(...) \
|
||||||
Log.fatal(__VA_ARGS__); \
|
Log.fatal(__VA_ARGS__); \
|
||||||
while(true) { \
|
while (true) \
|
||||||
|
{ \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define LOG_FATAL(...) \
|
#define LOG_FATAL(...) \
|
||||||
do { \
|
do \
|
||||||
|
{ \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -60,6 +67,6 @@
|
|||||||
#define LOG_DEBUG(...)
|
#define LOG_DEBUG(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOG_OUTPUT(...) Log.output(...)
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -26,6 +26,8 @@
|
|||||||
/* Maximal horizontal and vertical resolution to support by the library.*/
|
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||||
#define LV_HOR_RES_MAX (TFT_WIDTH)
|
#define LV_HOR_RES_MAX (TFT_WIDTH)
|
||||||
#define LV_VER_RES_MAX (TFT_HEIGHT)
|
#define LV_VER_RES_MAX (TFT_HEIGHT)
|
||||||
|
#define LV_HOR_RES (TFT_WIDTH)
|
||||||
|
#define LV_VER_RES (TFT_HEIGHT)
|
||||||
|
|
||||||
/* Color depth:
|
/* Color depth:
|
||||||
* - 1: 1 byte per pixel
|
* - 1: 1 byte per pixel
|
||||||
@ -181,7 +183,7 @@ typedef void* lv_group_user_data_t;
|
|||||||
typedef void* lv_fs_drv_user_data_t;
|
typedef void* lv_fs_drv_user_data_t;
|
||||||
|
|
||||||
/*File system interface*/
|
/*File system interface*/
|
||||||
#define LV_USE_FS_IF 1
|
#define LV_USE_FS_IF 0
|
||||||
#if LV_USE_FS_IF
|
#if LV_USE_FS_IF
|
||||||
# define LV_FS_IF_FATFS '\0'
|
# define LV_FS_IF_FATFS '\0'
|
||||||
#if defined(ARDUINO_ARCH_ESP32) // || defined(ARDUINO_ARCH_ESP8266)
|
#if defined(ARDUINO_ARCH_ESP32) // || defined(ARDUINO_ARCH_ESP8266)
|
||||||
@ -251,12 +253,18 @@ typedef void* lv_img_decoder_user_data_t;
|
|||||||
|
|
||||||
/* 1: use a custom tick source.
|
/* 1: use a custom tick source.
|
||||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||||
|
#ifdef ARDUINO
|
||||||
|
|
||||||
#define LV_TICK_CUSTOM 1
|
#define LV_TICK_CUSTOM 1
|
||||||
#if LV_TICK_CUSTOM == 1
|
#if LV_TICK_CUSTOM == 1
|
||||||
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the sys time function*/
|
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the sys time function*/
|
||||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||||
#endif /*LV_TICK_CUSTOM*/
|
#endif /*LV_TICK_CUSTOM*/
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define LV_TICK_CUSTOM 0
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef void* lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
typedef void* lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||||
typedef void* lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
typedef void* lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
||||||
|
|
||||||
@ -280,7 +288,7 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in
|
|||||||
|
|
||||||
/* 1: Print the log with 'printf';
|
/* 1: Print the log with 'printf';
|
||||||
* 0: user need to register a callback with `lv_log_register_print_cb`*/
|
* 0: user need to register a callback with `lv_log_register_print_cb`*/
|
||||||
# define LV_LOG_PRINTF 0
|
# define LV_LOG_PRINTF 1
|
||||||
#endif /*LV_USE_LOG*/
|
#endif /*LV_USE_LOG*/
|
||||||
|
|
||||||
/*=================
|
/*=================
|
||||||
@ -431,7 +439,7 @@ typedef void* lv_font_user_data_t;
|
|||||||
/*Always enable at least on theme*/
|
/*Always enable at least on theme*/
|
||||||
#define LV_USE_THEME_MATERIAL 1 /*A fast and impressive theme*/
|
#define LV_USE_THEME_MATERIAL 1 /*A fast and impressive theme*/
|
||||||
|
|
||||||
#define LV_THEME_DEFAULT_INIT lv_theme_hasp_init // We init the theme ourselves
|
#define LV_THEME_DEFAULT_INIT lv_theme_material_init // lv_theme_hasp_init // We init the theme ourselves
|
||||||
#define LV_THEME_DEFAULT_COLOR_PRIMARY LV_COLOR_RED
|
#define LV_THEME_DEFAULT_COLOR_PRIMARY LV_COLOR_RED
|
||||||
#define LV_THEME_DEFAULT_COLOR_SECONDARY LV_COLOR_BLUE
|
#define LV_THEME_DEFAULT_COLOR_SECONDARY LV_COLOR_BLUE
|
||||||
#define LV_THEME_DEFAULT_FLAG 0 //LV_THEME_MATERIAL_FLAG_NONE
|
#define LV_THEME_DEFAULT_FLAG 0 //LV_THEME_MATERIAL_FLAG_NONE
|
||||||
|
135
platformio.ini
135
platformio.ini
@ -34,7 +34,6 @@ extra_default_envs =
|
|||||||
; Common environment settings
|
; Common environment settings
|
||||||
;***************************************************
|
;***************************************************
|
||||||
[env]
|
[env]
|
||||||
framework = arduino
|
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
@ -49,21 +48,20 @@ build_flags =
|
|||||||
-D LV_CONF_INCLUDE_SIMPLE ; for lvgl
|
-D LV_CONF_INCLUDE_SIMPLE ; for lvgl
|
||||||
-D LV_LVGL_H_INCLUDE_SIMPLE ; for lv_drivers
|
-D LV_LVGL_H_INCLUDE_SIMPLE ; for lv_drivers
|
||||||
-D LV_COMP_CONF_INCLUDE_SIMPLE ; for components
|
-D LV_COMP_CONF_INCLUDE_SIMPLE ; for components
|
||||||
; -- littlevgl build options ------------------------------
|
; -- ESP build options ------------------------------------
|
||||||
-D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files
|
-D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files
|
||||||
; -- ArduinoJson build options ----------------------------
|
; -- ArduinoJson build options ----------------------------
|
||||||
-D ARDUINOJSON_DECODE_UNICODE=1 ; for utf-8 symbols
|
-D ARDUINOJSON_DECODE_UNICODE=1 ; for utf-8 symbols
|
||||||
-D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments
|
;-D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments
|
||||||
|
|
||||||
; -- StreamUtils build options ----------------------------
|
; -- StreamUtils build options ----------------------------
|
||||||
-D STREAMUTILS_ENABLE_EEPROM=1 ; for STM32, it also supports EEPROM
|
-D STREAMUTILS_ENABLE_EEPROM=1 ; for STM32, it also supports EEPROM
|
||||||
|
|
||||||
; -- Hasp build options ----------------------------
|
; -- Hasp build options ----------------------------
|
||||||
-D HASP_VER_MAJ=0
|
-D HASP_VER_MAJ=0
|
||||||
-D HASP_VER_MIN=3
|
-D HASP_VER_MIN=4
|
||||||
-D HASP_VER_REV=3
|
-D HASP_VER_REV=0
|
||||||
-D HASP_LOG_LEVEL=9
|
-D HASP_LOG_LEVEL=9
|
||||||
-D HASP_USE_CONFIG=1 ; Native application, not library
|
|
||||||
${override.build_flags}
|
${override.build_flags}
|
||||||
|
|
||||||
; -- Shared library dependencies in all environments
|
; -- Shared library dependencies in all environments
|
||||||
@ -93,6 +91,7 @@ extra_scripts = tools/copy_fw.py ; tools/pre:extra_script.py
|
|||||||
|
|
||||||
; -- Platform specific build flags
|
; -- Platform specific build flags
|
||||||
[esp32]
|
[esp32]
|
||||||
|
framework = arduino
|
||||||
build_flags =
|
build_flags =
|
||||||
${env.build_flags}
|
${env.build_flags}
|
||||||
-D HTTP_UPLOAD_BUFLEN=1024 ; lower http upload buffer
|
-D HTTP_UPLOAD_BUFLEN=1024 ; lower http upload buffer
|
||||||
@ -108,6 +107,7 @@ build_flags =
|
|||||||
;-D HASP_USE_SPIFFS=1
|
;-D HASP_USE_SPIFFS=1
|
||||||
-D HASP_USE_LITTLEFS=1
|
-D HASP_USE_LITTLEFS=1
|
||||||
;-D HASP_USE_EEPROM=1
|
;-D HASP_USE_EEPROM=1
|
||||||
|
-D HASP_USE_CONFIG=1 ; Native application, not library
|
||||||
; -- LittleFS build options ------------------------
|
; -- LittleFS build options ------------------------
|
||||||
-D CONFIG_LITTLEFS_FOR_IDF_3_2
|
-D CONFIG_LITTLEFS_FOR_IDF_3_2
|
||||||
|
|
||||||
@ -146,6 +146,7 @@ hspi =
|
|||||||
-D TFT_SCLK=14
|
-D TFT_SCLK=14
|
||||||
|
|
||||||
[esp8266]
|
[esp8266]
|
||||||
|
framework = arduino
|
||||||
build_flags=
|
build_flags=
|
||||||
-D HTTP_UPLOAD_BUFLEN=512 ; lower http upload buffer
|
-D HTTP_UPLOAD_BUFLEN=512 ; lower http upload buffer
|
||||||
-D MQTT_MAX_PACKET_SIZE=1024 ; longer PubSubClient messages
|
-D MQTT_MAX_PACKET_SIZE=1024 ; longer PubSubClient messages
|
||||||
@ -163,6 +164,7 @@ build_flags=
|
|||||||
-D HASP_USE_LITTLEFS=1
|
-D HASP_USE_LITTLEFS=1
|
||||||
-D HASP_USE_EEPROM=1
|
-D HASP_USE_EEPROM=1
|
||||||
-D HASP_USE_ETHERNET=0
|
-D HASP_USE_ETHERNET=0
|
||||||
|
-D HASP_USE_CONFIG=1 ; Native application, not library
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
ESP32 BLE Arduino
|
ESP32 BLE Arduino
|
||||||
@ -174,6 +176,7 @@ lib_ignore =
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
|
|
||||||
[stm32f4]
|
[stm32f4]
|
||||||
|
framework = arduino
|
||||||
build_flags=
|
build_flags=
|
||||||
-I include/stm32f4
|
-I include/stm32f4
|
||||||
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
|
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
|
||||||
@ -187,6 +190,7 @@ build_flags=
|
|||||||
-D HASP_USE_SYSLOG=0 ; Needs UDP
|
-D HASP_USE_SYSLOG=0 ; Needs UDP
|
||||||
-D HASP_USE_SPIFFS=0
|
-D HASP_USE_SPIFFS=0
|
||||||
-D HASP_USE_LITTLEFS=0
|
-D HASP_USE_LITTLEFS=0
|
||||||
|
-D HASP_USE_CONFIG=1 ; Native application, not library
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
; sstaub/Ticker @ ^3.2.0
|
; sstaub/Ticker @ ^3.2.0
|
||||||
@ -219,3 +223,122 @@ lib_deps =
|
|||||||
; ;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/master.zip
|
; ;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/master.zip
|
||||||
; lv_drivers@^6.0.2
|
; lv_drivers@^6.0.2
|
||||||
;src_filter = +<*> +<../drivers/sdl2>
|
;src_filter = +<*> +<../drivers/sdl2>
|
||||||
|
|
||||||
|
[env:emulator_64bits]
|
||||||
|
platform = native@^1.1.3
|
||||||
|
extra_scripts = tools/sdl2_build_extra.py
|
||||||
|
build_flags =
|
||||||
|
${env.build_flags}
|
||||||
|
; ----- Monitor
|
||||||
|
-D TFT_WIDTH=800
|
||||||
|
-D TFT_HEIGHT=480
|
||||||
|
; SDL drivers options
|
||||||
|
;-D LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
;-D LV_DRV_NO_CONF
|
||||||
|
-D USE_MONITOR
|
||||||
|
-D MONITOR_ZOOM=1 ; 2
|
||||||
|
-D USE_MOUSE
|
||||||
|
-D USE_MOUSEWHEEL
|
||||||
|
-D USE_KEYBOARD
|
||||||
|
; ----- ArduinoJson
|
||||||
|
-D ARDUINOJSON_DECODE_UNICODE=1
|
||||||
|
-D HASP_NUM_PAGES=4
|
||||||
|
-D HASP_USE_SPIFFS=0
|
||||||
|
-D HASP_USE_LITTLEFS=0
|
||||||
|
-D HASP_USE_EEPROM=0
|
||||||
|
-D HASP_USE_GPIO=0
|
||||||
|
-D HASP_USE_CONFIG=0 ; Standalone application, as library
|
||||||
|
-D HASP_USE_DEBUG=1
|
||||||
|
-D HASP_USE_MQTT=1
|
||||||
|
-D MQTT_MAX_PACKET_SIZE=2048
|
||||||
|
;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO
|
||||||
|
;-D LV_LOG_PRINTF=1
|
||||||
|
; Add recursive dirs for hal headers search
|
||||||
|
!python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
|
||||||
|
-mconsole
|
||||||
|
-lSDL2
|
||||||
|
-D PAHO_MQTT_STATIC
|
||||||
|
-D _WIN64
|
||||||
|
-D WINDOWS ; We add this for code branching in hasp
|
||||||
|
-D WIN32_LEAN_AND_MEAN
|
||||||
|
-DPAHO_WITH_SSL=FALSE
|
||||||
|
-DPAHO_BUILD_DOCUMENTATION=FALSE
|
||||||
|
-DPAHO_BUILD_SAMPLES=FALSE
|
||||||
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
|
-DCMAKE_VERBOSE_MAKEFILE=TRUE
|
||||||
|
;-D NO_PERSISTENCE
|
||||||
|
-I.pio/libdeps/emulator_64bits/paho/src
|
||||||
|
-I.pio/libdeps/emulator_64bits/ArduinoJson/src
|
||||||
|
-I lib/ArduinoJson/src
|
||||||
|
-I lib/lv_fs_if
|
||||||
|
-l"ws2_32"
|
||||||
|
-lrpcrt4
|
||||||
|
-lcrypt32
|
||||||
|
-lmingw32
|
||||||
|
-lSDL2main
|
||||||
|
-lSDL2
|
||||||
|
-mwindows
|
||||||
|
-lm
|
||||||
|
-ldinput8
|
||||||
|
-ldxguid
|
||||||
|
-ldxerr8
|
||||||
|
-luser32
|
||||||
|
-lgdi32
|
||||||
|
-lwinmm
|
||||||
|
-limm32
|
||||||
|
-lole32
|
||||||
|
-loleaut32
|
||||||
|
-lshell32
|
||||||
|
-lversion
|
||||||
|
-luuid
|
||||||
|
-lsetupapi
|
||||||
|
-lhid
|
||||||
|
;-v
|
||||||
|
|
||||||
|
|
||||||
|
lib_deps =
|
||||||
|
${env.lib_deps}
|
||||||
|
lv_drivers@~7.9.0
|
||||||
|
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
|
||||||
|
https://github.com/eclipse/paho.mqtt.c.git
|
||||||
|
bblanchon/ArduinoJson@^6.17.2 ; Json(l) parser
|
||||||
|
|
||||||
|
lib_ignore = paho
|
||||||
|
|
||||||
|
src_filter =
|
||||||
|
+<*>
|
||||||
|
-<*.h>
|
||||||
|
+<../hal/sdl2>
|
||||||
|
+<../.pio/libdeps/emulator_64bits/paho/src/*.c>
|
||||||
|
-<../.pio/libdeps/emulator_64bits/paho/src/MQTTClient.c>
|
||||||
|
-<../.pio/libdeps/emulator_64bits/paho/src/MQTTVersion.c>
|
||||||
|
-<../.pio/libdeps/emulator_64bits/paho/src/SSLSocket.c>
|
||||||
|
-<MQTTClient.c>
|
||||||
|
-<MQTTVersion.c>
|
||||||
|
-<SSLSocket.c>
|
||||||
|
-<../.pio/libdeps/emulator_64bits/lv_fs_if/lv_fs_pc.c>
|
||||||
|
-<../.pio/libdeps/emulator_64bits/ArduinoLog/ArduinoLog.cpp>
|
||||||
|
-<sys>
|
||||||
|
-<hal>
|
||||||
|
-<drv>
|
||||||
|
-<drv/touch>
|
||||||
|
-<drv/tft>
|
||||||
|
-<dev>
|
||||||
|
-<hal>
|
||||||
|
-<svc>
|
||||||
|
-<hasp_filesystem.cpp>
|
||||||
|
-<hasp_gui.cpp>
|
||||||
|
-<hasp_gui.h>
|
||||||
|
+<font>
|
||||||
|
+<hasp>
|
||||||
|
+<lang>
|
||||||
|
-<log>
|
||||||
|
+<mqtt>
|
||||||
|
-<lib/ArduinoLog>
|
||||||
|
-<lib/lv_fs_if>
|
||||||
|
-<../lib/lv_fs_if>
|
||||||
|
-<../lib/lv_fs_if/lv_fs_if.cpp>
|
||||||
|
-<../lib/lv_fs_if/lv_fs_if.h>
|
||||||
|
-<../lib/lv_fs_if/lv_fs_spiffs.cpp>
|
||||||
|
-<../lib/lv_fs_if/lv_fs_spiffs.h>
|
||||||
|
+<../.pio/libdeps/emulator_64bits/ArduinoJson/src/ArduinoJson.h>
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
/* MIT License - Copyright (c) 2020 Francis Van Roie
|
/* MIT License - Copyright (c) 2020 Francis Van Roie
|
||||||
For full license information read the LICENSE file in the project folder */
|
For full license information read the LICENSE file in the project folder */
|
||||||
|
|
||||||
|
#ifdef ARDUINO
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "hasp_conf.h" // load first
|
#include "hasp_conf.h" // load first
|
||||||
|
|
||||||
|
#if HASP_USE_CONFIG > 0
|
||||||
#include "hasp_debug.h"
|
#include "hasp_debug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HASP_USE_CONFIG > 0
|
||||||
#include "hasp_config.h"
|
#include "hasp_config.h"
|
||||||
#include "hasp_gui.h"
|
#include "hasp_gui.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "hasp_oobe.h"
|
#include "hasp_oobe.h"
|
||||||
|
|
||||||
#include "hasp/hasp_dispatch.h"
|
#include "hasp/hasp_dispatch.h"
|
||||||
#include "hasp/hasp.h"
|
#include "hasp/hasp.h"
|
||||||
|
|
||||||
#include "net/hasp_network.h"
|
#include "sys/net/hasp_network.h"
|
||||||
|
|
||||||
#include "dev/device.h"
|
#include "dev/device.h"
|
||||||
|
|
||||||
@ -49,6 +57,7 @@ void setup()
|
|||||||
dispatchSetup();
|
dispatchSetup();
|
||||||
guiSetup();
|
guiSetup();
|
||||||
debugSetup(); // Init the console
|
debugSetup(); // Init the console
|
||||||
|
|
||||||
#if HASP_USE_GPIO > 0
|
#if HASP_USE_GPIO > 0
|
||||||
gpioSetup();
|
gpioSetup();
|
||||||
#endif
|
#endif
|
||||||
@ -137,7 +146,7 @@ void loop()
|
|||||||
/* Timer Loop */
|
/* Timer Loop */
|
||||||
if(millis() - mainLastLoopTime >= 1000) {
|
if(millis() - mainLastLoopTime >= 1000) {
|
||||||
/* Runs Every Second */
|
/* Runs Every Second */
|
||||||
haspEverySecond();
|
haspEverySecond(); // sleep timer
|
||||||
debugEverySecond(); // statusupdate
|
debugEverySecond(); // statusupdate
|
||||||
|
|
||||||
#if HASP_USE_OTA > 0
|
#if HASP_USE_OTA > 0
|
||||||
@ -178,3 +187,5 @@ void loop()
|
|||||||
delay(6);
|
delay(6);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
120
src/main_windows.cpp
Normal file
120
src/main_windows.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* MIT License - Copyright (c) 2020 Francis Van Roie
|
||||||
|
For full license information read the LICENSE file in the project folder */
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include "app_hal.h"
|
||||||
|
|
||||||
|
#include "hasp_conf.h"
|
||||||
|
#include "hasp_debug.h"
|
||||||
|
|
||||||
|
#include "hasp/hasp_dispatch.h"
|
||||||
|
#include "hasp/hasp.h"
|
||||||
|
|
||||||
|
#include "dev/device.h"
|
||||||
|
#include "app_hal.h"
|
||||||
|
|
||||||
|
bool isConnected;
|
||||||
|
uint8_t mainLoopCounter = 0;
|
||||||
|
unsigned long mainLastLoopTime = 0;
|
||||||
|
|
||||||
|
void debugLvglLogEvent(lv_log_level_t level, const char * file, uint32_t line, const char * funcname,
|
||||||
|
const char * descr)
|
||||||
|
{
|
||||||
|
printf("%s %d\n", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
printf("%s %d\n", __FILE__, __LINE__);
|
||||||
|
fflush(stdout);
|
||||||
|
lv_init();
|
||||||
|
lv_log_register_print_cb(debugLvglLogEvent);
|
||||||
|
|
||||||
|
printf("%s %d\n", __FILE__, __LINE__);
|
||||||
|
fflush(stdout);
|
||||||
|
hal_setup();
|
||||||
|
|
||||||
|
printf("%s %d\n", __FILE__, __LINE__);
|
||||||
|
haspDevice.pre_setup();
|
||||||
|
|
||||||
|
printf("%s %d\n", __FILE__, __LINE__);
|
||||||
|
dispatchSetup();
|
||||||
|
// debugSetup(); // Init the console
|
||||||
|
|
||||||
|
#if HASP_USE_MQTT > 0
|
||||||
|
printf("%s %d\n", __FILE__, __LINE__);
|
||||||
|
mqttSetup(); // Load Hostname before starting WiFi
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("%s %d\n", __FILE__, __LINE__);
|
||||||
|
haspSetup();
|
||||||
|
mainLastLoopTime = millis() - 1000; // reset loop counter
|
||||||
|
delay(250);
|
||||||
|
|
||||||
|
mqttStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
haspLoop();
|
||||||
|
|
||||||
|
// debugLoop(); // Console
|
||||||
|
haspDevice.loop();
|
||||||
|
|
||||||
|
/* Timer Loop */
|
||||||
|
if(millis() - mainLastLoopTime >= 1000) {
|
||||||
|
/* Runs Every Second */
|
||||||
|
haspEverySecond(); // sleep timer
|
||||||
|
|
||||||
|
#if HASP_USE_OTA > 0
|
||||||
|
otaEverySecond(); // progressbar
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Runs Every 5 Seconds */
|
||||||
|
if(mainLoopCounter == 0 || mainLoopCounter == 5) {
|
||||||
|
|
||||||
|
haspDevice.loop_5s();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset loop counter every 10 seconds */
|
||||||
|
if(mainLoopCounter >= 9) {
|
||||||
|
mainLoopCounter = 0;
|
||||||
|
} else {
|
||||||
|
mainLoopCounter++;
|
||||||
|
}
|
||||||
|
mainLastLoopTime += 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
int main(int argv, char ** args)
|
||||||
|
{
|
||||||
|
printf("%s %d\n", __FILE__, __LINE__);
|
||||||
|
fflush(stdout);
|
||||||
|
setup();
|
||||||
|
std::cout << "HSetup OK\n";
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
SDL_Delay(5);
|
||||||
|
lv_task_handler();
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
std::cout << "Hloop OK\n";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
delay(5);
|
||||||
|
lv_task_handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -4,7 +4,11 @@
|
|||||||
#ifndef HASP_MQTT_H
|
#ifndef HASP_MQTT_H
|
||||||
#define HASP_MQTT_H
|
#define HASP_MQTT_H
|
||||||
|
|
||||||
#include "ArduinoJson.h"
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "hasp_conf.h"
|
||||||
|
|
||||||
|
#define __FlashStringHelper char
|
||||||
|
|
||||||
void mqttSetup();
|
void mqttSetup();
|
||||||
void mqttLoop();
|
void mqttLoop();
|
||||||
@ -22,6 +26,6 @@ bool mqttGetConfig(const JsonObject & settings);
|
|||||||
bool mqttSetConfig(const JsonObject & settings);
|
bool mqttSetConfig(const JsonObject & settings);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String mqttGetNodename(void);
|
//String mqttGetNodename(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -35,7 +35,7 @@ EthernetClient mqttNetworkClient;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "hasp_hal.h"
|
#include "hasp_hal.h"
|
||||||
#include "hasp_debug.h"
|
#include "log/hasp_debug.h"
|
||||||
#include "hasp_config.h"
|
#include "hasp_config.h"
|
||||||
|
|
||||||
#include "../hasp/hasp_dispatch.h"
|
#include "../hasp/hasp_dispatch.h"
|
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
#include "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
#include "hasp_conf.h"
|
#include "hasp_conf.h"
|
||||||
#if HASP_USE_MQTT > 0
|
|
||||||
|
#if 0 && HASP_USE_MQTT > 0
|
||||||
|
|
||||||
#include "PubSubClient.h"
|
#include "PubSubClient.h"
|
||||||
|
|
423
src/mqtt/hasp_mqtt_paho.cpp
Normal file
423
src/mqtt/hasp_mqtt_paho.cpp
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
/* MIT License - Copyright (c) 2020 Francis Van Roie
|
||||||
|
For full license information read the LICENSE file in the project folder */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "hasp_conf.h"
|
||||||
|
|
||||||
|
#if HASP_USE_MQTT > 0
|
||||||
|
#ifdef USE_PAHO
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2012, 2020 IBM Corp.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v2.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Ian Craggs - initial contribution
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "MQTTAsync.h"
|
||||||
|
|
||||||
|
#include "hasp_mqtt.h" // functions to implement here
|
||||||
|
|
||||||
|
#include "hasp/hasp_dispatch.h" // for dispatch_topic_payload
|
||||||
|
#include "hasp_debug.h" // for logging
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WRS_KERNEL)
|
||||||
|
#include <OsWrapper.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ADDRESS "10.4.0.5:1883"
|
||||||
|
#define CLIENTID "ExampleClientSub"
|
||||||
|
#define TOPIC "hasp/plate35/"
|
||||||
|
#define QOS 1
|
||||||
|
#define TIMEOUT 10000L
|
||||||
|
|
||||||
|
const char * mqttNodeTopic = TOPIC;
|
||||||
|
const char * mqttGroupTopic = TOPIC;
|
||||||
|
// char mqttNodeTopic[24];
|
||||||
|
// char mqttGroupTopic[24];
|
||||||
|
bool mqttEnabled = false;
|
||||||
|
bool mqttHAautodiscover = true;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// These defaults may be overwritten with values saved by the web interface
|
||||||
|
#ifndef MQTT_HOST
|
||||||
|
#define MQTT_HOST "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MQTT_PORT
|
||||||
|
#define MQTT_PORT 1883;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MQTT_USER
|
||||||
|
#define MQTT_USER "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MQTT_PASSW
|
||||||
|
#define MQTT_PASSW "";
|
||||||
|
#endif
|
||||||
|
#ifndef MQTT_NODENAME
|
||||||
|
#define MQTT_NODENAME "";
|
||||||
|
#endif
|
||||||
|
#ifndef MQTT_GROUPNAME
|
||||||
|
#define MQTT_GROUPNAME "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MQTT_PREFIX
|
||||||
|
#define MQTT_PREFIX "hasp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LWT_TOPIC "LWT"
|
||||||
|
|
||||||
|
char mqttServer[16] = MQTT_HOST;
|
||||||
|
char mqttUser[23] = MQTT_USER;
|
||||||
|
char mqttPassword[32] = MQTT_PASSW;
|
||||||
|
char mqttNodeName[16] = MQTT_NODENAME;
|
||||||
|
char mqttGroupName[16] = MQTT_GROUPNAME;
|
||||||
|
uint16_t mqttPort = MQTT_PORT;
|
||||||
|
|
||||||
|
MQTTAsync mqtt_client;
|
||||||
|
|
||||||
|
int disc_finished = 0;
|
||||||
|
int subscribed = 0;
|
||||||
|
int connected = 0;
|
||||||
|
|
||||||
|
static bool mqttPublish(const char * topic, const char * payload, size_t len, bool retain = false);
|
||||||
|
|
||||||
|
/* ===== Paho event callbacks ===== */
|
||||||
|
|
||||||
|
void connlost(void * context, char * cause)
|
||||||
|
{
|
||||||
|
MQTTAsync client = (MQTTAsync)context;
|
||||||
|
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
|
||||||
|
int rc;
|
||||||
|
connected = 0;
|
||||||
|
|
||||||
|
printf("\nConnection lost\n");
|
||||||
|
if(cause) printf(" cause: %s\n", cause);
|
||||||
|
|
||||||
|
printf("Reconnecting\n");
|
||||||
|
conn_opts.keepAliveInterval = 20;
|
||||||
|
conn_opts.cleansession = 1;
|
||||||
|
if((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) {
|
||||||
|
printf("Failed to start connect, return code %d\n", rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive incoming messages
|
||||||
|
static void mqtt_message_cb(char * topic, char * payload, unsigned int length)
|
||||||
|
{ // Handle incoming commands from MQTT
|
||||||
|
if(length + 1 >= MQTT_MAX_PACKET_SIZE) {
|
||||||
|
LOG_ERROR(TAG_MQTT_RCV, F("Payload too long (%d bytes)"), length);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
payload[length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_TRACE(TAG_MQTT_RCV, F("%s = %s"), topic, (char *)payload);
|
||||||
|
|
||||||
|
if(topic == strstr(topic, mqttNodeTopic)) { // startsWith mqttNodeTopic
|
||||||
|
|
||||||
|
// Node topic
|
||||||
|
topic += strlen(mqttNodeTopic); // shorten topic
|
||||||
|
|
||||||
|
} else if(topic == strstr(topic, mqttGroupTopic)) { // startsWith mqttGroupTopic
|
||||||
|
|
||||||
|
// Group topic
|
||||||
|
topic += strlen(mqttGroupTopic); // shorten topic
|
||||||
|
dispatch_topic_payload(topic, (const char *)payload);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if(topic == strstr_P(topic, PSTR("homeassistant/status"))) { // HA discovery topic
|
||||||
|
if(mqttHAautodiscover && !strcasecmp_P((char *)payload, PSTR("online"))) {
|
||||||
|
// dispatch_current_state();
|
||||||
|
// mqtt_ha_register_auto_discovery();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Other topic
|
||||||
|
LOG_ERROR(TAG_MQTT, F(D_MQTT_INVALID_TOPIC));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// catch a dangling LWT from a previous connection if it appears
|
||||||
|
if(!strcmp_P(topic, PSTR(LWT_TOPIC))) { // endsWith LWT
|
||||||
|
if(!strcasecmp_P((char *)payload, PSTR("offline"))) {
|
||||||
|
{
|
||||||
|
char msg[8];
|
||||||
|
char tmp_topic[strlen(mqttNodeTopic) + 8];
|
||||||
|
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic);
|
||||||
|
snprintf_P(msg, sizeof(msg), PSTR("online"));
|
||||||
|
|
||||||
|
// /*bool res =*/mqttClient.publish(tmp_topic, msg, true);
|
||||||
|
mqttPublish(tmp_topic, msg, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// LOG_TRACE(TAG_MQTT, F("ignoring LWT = online"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dispatch_topic_payload(topic, (const char *)payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int msgarrvd(void * context, char * topicName, int topicLen, MQTTAsync_message * message)
|
||||||
|
{
|
||||||
|
printf("MQT RCV >> ");
|
||||||
|
printf("%s => %.*s (%d)\n", topicName, message->payloadlen, (char *)message->payload, message->payloadlen);
|
||||||
|
|
||||||
|
char msg[message->payloadlen + 1];
|
||||||
|
memcpy(msg, (char *)message->payload, message->payloadlen);
|
||||||
|
msg[message->payloadlen] = '\0';
|
||||||
|
|
||||||
|
mqtt_message_cb(topicName, (char *)message->payload, message->payloadlen);
|
||||||
|
|
||||||
|
MQTTAsync_freeMessage(&message);
|
||||||
|
MQTTAsync_free(topicName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDisconnectFailure(void * context, MQTTAsync_failureData * response)
|
||||||
|
{
|
||||||
|
printf("Disconnect failed, rc %d\n", response->code);
|
||||||
|
disc_finished = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDisconnect(void * context, MQTTAsync_successData * response)
|
||||||
|
{
|
||||||
|
printf("Successful disconnection\n");
|
||||||
|
disc_finished = 1;
|
||||||
|
connected = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSubscribe(void * context, MQTTAsync_successData * response)
|
||||||
|
{
|
||||||
|
printf("Subscribe succeeded %d\n", response->token);
|
||||||
|
subscribed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSubscribeFailure(void * context, MQTTAsync_failureData * response)
|
||||||
|
{
|
||||||
|
printf("Subscribe failed, rc %d\n", response->code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onConnectFailure(void * context, MQTTAsync_failureData * response)
|
||||||
|
{
|
||||||
|
connected = 0;
|
||||||
|
printf("Connect failed, rc %d\n", response->code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_subscribe(void * context, const char * topic)
|
||||||
|
{
|
||||||
|
MQTTAsync client = (MQTTAsync)context;
|
||||||
|
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n", topic, CLIENTID, QOS);
|
||||||
|
opts.onSuccess = onSubscribe;
|
||||||
|
opts.onFailure = onSubscribeFailure;
|
||||||
|
opts.context = client;
|
||||||
|
if((rc = MQTTAsync_subscribe(client, topic, QOS, &opts)) != MQTTASYNC_SUCCESS) {
|
||||||
|
printf("Failed to start subscribe, return code %d\n", rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onConnect(void * context, MQTTAsync_successData * response)
|
||||||
|
{
|
||||||
|
MQTTAsync client = (MQTTAsync)context;
|
||||||
|
connected = 1;
|
||||||
|
|
||||||
|
printf("Successful connection\n");
|
||||||
|
|
||||||
|
mqtt_subscribe(context, TOPIC "command/#");
|
||||||
|
mqtt_subscribe(context, TOPIC "command");
|
||||||
|
mqtt_subscribe(context, TOPIC "light");
|
||||||
|
mqtt_subscribe(context, TOPIC "dim");
|
||||||
|
|
||||||
|
mqtt_send_object_state(0, 0, "connected");
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSendFailure(void * context, MQTTAsync_failureData * response)
|
||||||
|
{
|
||||||
|
MQTTAsync client = (MQTTAsync)context;
|
||||||
|
MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
printf("Message send failed token %d error code %d\n", response->token, response->code);
|
||||||
|
opts.onSuccess = onDisconnect;
|
||||||
|
opts.onFailure = onDisconnectFailure;
|
||||||
|
opts.context = client;
|
||||||
|
if((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) {
|
||||||
|
printf("Failed to start disconnect, return code %d\n", rc);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSend(void * context, MQTTAsync_successData * response)
|
||||||
|
{
|
||||||
|
MQTTAsync client = (MQTTAsync)context;
|
||||||
|
MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
printf("Message with token value %d delivery confirmed\n", response->token);
|
||||||
|
// opts.onSuccess = onDisconnect;
|
||||||
|
// opts.onFailure = onDisconnectFailure;
|
||||||
|
// opts.context = client;
|
||||||
|
// if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
|
||||||
|
// {
|
||||||
|
// printf("Failed to start disconnect, return code %d\n", rc);
|
||||||
|
// exit(EXIT_FAILURE);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Local HASP MQTT functions ===== */
|
||||||
|
|
||||||
|
static bool mqttPublish(const char * topic, const char * payload, size_t len, bool retain)
|
||||||
|
{
|
||||||
|
if(mqttIsConnected()) {
|
||||||
|
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
|
||||||
|
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
opts.onSuccess = onSend;
|
||||||
|
opts.onFailure = onSendFailure;
|
||||||
|
opts.context = mqtt_client;
|
||||||
|
pubmsg.payload = (char *)payload;
|
||||||
|
pubmsg.payloadlen = (int)strlen(payload);
|
||||||
|
pubmsg.qos = QOS;
|
||||||
|
pubmsg.retained = 0;
|
||||||
|
if((rc = MQTTAsync_sendMessage(mqtt_client, topic, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) {
|
||||||
|
LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " %s => %s"), topic, payload);
|
||||||
|
} else {
|
||||||
|
LOG_TRACE(TAG_MQTT_PUB, F("%s => %s"), topic, payload);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Public HASP MQTT functions ===== */
|
||||||
|
|
||||||
|
bool mqttIsConnected()
|
||||||
|
{
|
||||||
|
return connected == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_send_state(const __FlashStringHelper * subtopic, const char * payload)
|
||||||
|
{
|
||||||
|
char tmp_topic[strlen(mqttNodeTopic) + 20];
|
||||||
|
printf(("%sstate/%s\n"), mqttNodeTopic, subtopic);
|
||||||
|
snprintf_P(tmp_topic, sizeof(tmp_topic), ("%sstate/%s"), mqttNodeTopic, subtopic);
|
||||||
|
mqttPublish(tmp_topic, payload, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, char * payload)
|
||||||
|
{
|
||||||
|
char tmp_topic[strlen(mqttNodeTopic) + 20];
|
||||||
|
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/p%ub%u"), mqttNodeTopic, pageid, btnid);
|
||||||
|
mqttPublish(tmp_topic, payload, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttStart()
|
||||||
|
{
|
||||||
|
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
|
||||||
|
int rc;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if((rc = MQTTAsync_create(&mqtt_client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) !=
|
||||||
|
MQTTASYNC_SUCCESS) {
|
||||||
|
printf("Failed to create client, return code %d\n", rc);
|
||||||
|
rc = EXIT_FAILURE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((rc = MQTTAsync_setCallbacks(mqtt_client, mqtt_client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) {
|
||||||
|
printf("Failed to set callbacks, return code %d\n", rc);
|
||||||
|
rc = EXIT_FAILURE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn_opts.keepAliveInterval = 20;
|
||||||
|
conn_opts.cleansession = 1;
|
||||||
|
conn_opts.onSuccess = onConnect;
|
||||||
|
conn_opts.onFailure = onConnectFailure;
|
||||||
|
conn_opts.context = mqtt_client;
|
||||||
|
if((rc = MQTTAsync_connect(mqtt_client, &conn_opts)) != MQTTASYNC_SUCCESS) {
|
||||||
|
printf("Failed to start connect, return code %d\n", rc);
|
||||||
|
rc = EXIT_FAILURE;
|
||||||
|
// goto destroy_exit;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
// while (!subscribed && !finished)
|
||||||
|
// #if defined(_WIN32)
|
||||||
|
// Sleep(100);
|
||||||
|
// #else
|
||||||
|
// usleep(10000L);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// if (finished)
|
||||||
|
// goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttStop()
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
|
||||||
|
disc_opts.onSuccess = onDisconnect;
|
||||||
|
disc_opts.onFailure = onDisconnectFailure;
|
||||||
|
if((rc = MQTTAsync_disconnect(mqtt_client, &disc_opts)) != MQTTASYNC_SUCCESS) {
|
||||||
|
printf("Failed to start disconnect, return code %d\n", rc);
|
||||||
|
rc = EXIT_FAILURE;
|
||||||
|
// goto destroy_exit;
|
||||||
|
}
|
||||||
|
// while (!disc_finished)
|
||||||
|
// {
|
||||||
|
// #if defined(_WIN32)
|
||||||
|
// Sleep(100);
|
||||||
|
// #else
|
||||||
|
// usleep(10000L);
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
|
||||||
|
// destroy_exit:
|
||||||
|
// MQTTAsync_destroy(&client);
|
||||||
|
// exit:
|
||||||
|
// return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttSetup(){};
|
||||||
|
|
||||||
|
void mqttLoop(){};
|
||||||
|
|
||||||
|
void mqttEvery5Seconds(bool wifiIsConnected){};
|
||||||
|
|
||||||
|
// String mqttGetNodename(void){return "palte35"};
|
||||||
|
|
||||||
|
#endif // USE_PAHO
|
||||||
|
#endif // USE_MQTT
|
455
src/mqtt/hasp_mqtt_pubsubclient.cpp
Normal file
455
src/mqtt/hasp_mqtt_pubsubclient.cpp
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
/* MIT License - Copyright (c) 2020 Francis Van Roie
|
||||||
|
For full license information read the LICENSE file in the project folder */
|
||||||
|
|
||||||
|
#include "hasp_conf.h"
|
||||||
|
|
||||||
|
#if HASP_USE_MQTT > 0
|
||||||
|
#ifdef USE_PUBSUBCLIENT
|
||||||
|
|
||||||
|
#include "PubSubClient.h"
|
||||||
|
|
||||||
|
#include "hasp/hasp.h"
|
||||||
|
#include "hasp_mqtt.h"
|
||||||
|
#include "hasp_mqtt_ha.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
#include <WiFi.h>
|
||||||
|
WiFiClient mqttNetworkClient;
|
||||||
|
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <EEPROM.h>
|
||||||
|
#include <Esp.h>
|
||||||
|
WiFiClient mqttNetworkClient;
|
||||||
|
#else
|
||||||
|
#if defined(STM32F4xx) && HASP_USE_WIFI > 0
|
||||||
|
// #include <WiFi.h>
|
||||||
|
WiFiSpiClient mqttNetworkClient;
|
||||||
|
#else
|
||||||
|
#if defined(W5500_MOSI) && defined(W5500_MISO) && defined(W5500_SCLK)
|
||||||
|
#define W5500_LAN
|
||||||
|
#include <Ethernet.h>
|
||||||
|
#else
|
||||||
|
#include <STM32Ethernet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EthernetClient mqttNetworkClient;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "hasp_hal.h"
|
||||||
|
#include "log/hasp_debug.h"
|
||||||
|
#include "hasp_config.h"
|
||||||
|
|
||||||
|
#include "../hasp/hasp_dispatch.h"
|
||||||
|
|
||||||
|
#ifdef USE_CONFIG_OVERRIDE
|
||||||
|
#include "user_config_override.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char mqttNodeTopic[24];
|
||||||
|
char mqttGroupTopic[24];
|
||||||
|
bool mqttEnabled = false;
|
||||||
|
bool mqttHAautodiscover = true;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// These defaults may be overwritten with values saved by the web interface
|
||||||
|
#ifndef MQTT_HOST
|
||||||
|
#define MQTT_HOST "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MQTT_PORT
|
||||||
|
#define MQTT_PORT 1883;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MQTT_USER
|
||||||
|
#define MQTT_USER "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MQTT_PASSW
|
||||||
|
#define MQTT_PASSW "";
|
||||||
|
#endif
|
||||||
|
#ifndef MQTT_NODENAME
|
||||||
|
#define MQTT_NODENAME "";
|
||||||
|
#endif
|
||||||
|
#ifndef MQTT_GROUPNAME
|
||||||
|
#define MQTT_GROUPNAME "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MQTT_PREFIX
|
||||||
|
#define MQTT_PREFIX "hasp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LWT_TOPIC "LWT"
|
||||||
|
|
||||||
|
char mqttServer[16] = MQTT_HOST;
|
||||||
|
char mqttUser[23] = MQTT_USER;
|
||||||
|
char mqttPassword[32] = MQTT_PASSW;
|
||||||
|
char mqttNodeName[16] = MQTT_NODENAME;
|
||||||
|
char mqttGroupName[16] = MQTT_GROUPNAME;
|
||||||
|
uint16_t mqttPort = MQTT_PORT;
|
||||||
|
PubSubClient mqttClient(mqttNetworkClient);
|
||||||
|
|
||||||
|
static bool mqttPublish(const char * topic, const char * payload, size_t len, bool retain = false)
|
||||||
|
{
|
||||||
|
if(mqttIsConnected()) {
|
||||||
|
if(mqttClient.beginPublish(topic, len, retain)) {
|
||||||
|
mqttClient.write((uint8_t *)payload, len);
|
||||||
|
mqttClient.endPublish();
|
||||||
|
|
||||||
|
LOG_TRACE(TAG_MQTT_PUB, F("%s => %s"), topic, payload);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " %s => %s"), topic, payload);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mqttPublish(const char * topic, const char * payload, bool retain = false)
|
||||||
|
{
|
||||||
|
return mqttPublish(topic, payload, strlen(payload), retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Send changed values OUT
|
||||||
|
|
||||||
|
bool mqttIsConnected()
|
||||||
|
{
|
||||||
|
return mqttEnabled && mqttClient.connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_send_lwt(bool online)
|
||||||
|
{
|
||||||
|
char tmp_payload[8];
|
||||||
|
char tmp_topic[strlen(mqttNodeTopic) + 4];
|
||||||
|
strncpy(tmp_topic, mqttNodeTopic, sizeof(tmp_topic));
|
||||||
|
strncat_P(tmp_topic, PSTR(LWT_TOPIC), sizeof(tmp_topic));
|
||||||
|
// snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic);
|
||||||
|
|
||||||
|
size_t len = snprintf_P(tmp_payload, sizeof(tmp_payload), online ? PSTR("online") : PSTR("offline"));
|
||||||
|
bool res = mqttPublish(tmp_topic, tmp_payload, len, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, char * payload)
|
||||||
|
{
|
||||||
|
char tmp_topic[strlen(mqttNodeTopic) + 16];
|
||||||
|
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/" HASP_OBJECT_NOTATION), mqttNodeTopic, pageid, btnid);
|
||||||
|
mqttPublish(tmp_topic, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_send_state(const __FlashStringHelper * subtopic, const char * payload)
|
||||||
|
{
|
||||||
|
char tmp_topic[strlen(mqttNodeTopic) + 20];
|
||||||
|
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/%s"), mqttNodeTopic, subtopic);
|
||||||
|
mqttPublish(tmp_topic, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Receive incoming messages
|
||||||
|
static void mqtt_message_cb(char * topic, byte * payload, unsigned int length)
|
||||||
|
{ // Handle incoming commands from MQTT
|
||||||
|
if(length + 1 >= mqttClient.getBufferSize()) {
|
||||||
|
LOG_ERROR(TAG_MQTT_RCV, F("Payload too long (%d bytes)"), length);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
payload[length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_TRACE(TAG_MQTT_RCV, F("%s = %s"), topic, (char *)payload);
|
||||||
|
|
||||||
|
if(topic == strstr(topic, mqttNodeTopic)) { // startsWith mqttNodeTopic
|
||||||
|
|
||||||
|
// Node topic
|
||||||
|
topic += strlen(mqttNodeTopic); // shorten topic
|
||||||
|
|
||||||
|
} else if(topic == strstr(topic, mqttGroupTopic)) { // startsWith mqttGroupTopic
|
||||||
|
|
||||||
|
// Group topic
|
||||||
|
topic += strlen(mqttGroupTopic); // shorten topic
|
||||||
|
dispatch_topic_payload(topic, (const char *)payload);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if(topic == strstr_P(topic, PSTR("homeassistant/status"))) { // HA discovery topic
|
||||||
|
if(mqttHAautodiscover && !strcasecmp_P((char *)payload, PSTR("online"))) {
|
||||||
|
dispatch_current_state();
|
||||||
|
mqtt_ha_register_auto_discovery();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Other topic
|
||||||
|
LOG_ERROR(TAG_MQTT, F(D_MQTT_INVALID_TOPIC));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// catch a dangling LWT from a previous connection if it appears
|
||||||
|
if(!strcmp_P(topic, PSTR(LWT_TOPIC))) { // endsWith LWT
|
||||||
|
if(!strcasecmp_P((char *)payload, PSTR("offline"))) {
|
||||||
|
{
|
||||||
|
char msg[8];
|
||||||
|
char tmp_topic[strlen(mqttNodeTopic) + 8];
|
||||||
|
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic);
|
||||||
|
snprintf_P(msg, sizeof(msg), PSTR("online"));
|
||||||
|
|
||||||
|
// /*bool res =*/mqttClient.publish(tmp_topic, msg, true);
|
||||||
|
mqttPublish(tmp_topic, msg, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// LOG_TRACE(TAG_MQTT, F("ignoring LWT = online"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dispatch_topic_payload(topic, (const char *)payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mqttSubscribeTo(const __FlashStringHelper * format, const char * data)
|
||||||
|
{
|
||||||
|
char tmp_topic[strlen_P((PGM_P)format) + 2 + strlen(data)];
|
||||||
|
snprintf_P(tmp_topic, sizeof(tmp_topic), (PGM_P)format, data);
|
||||||
|
if(mqttClient.subscribe(tmp_topic)) {
|
||||||
|
LOG_VERBOSE(TAG_MQTT, F(D_BULLET D_MQTT_SUBSCRIBED), tmp_topic);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_SUBSCRIBED), tmp_topic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttStart()
|
||||||
|
{
|
||||||
|
char buffer[64];
|
||||||
|
char mqttClientId[64];
|
||||||
|
char lastWillPayload[8];
|
||||||
|
static uint8_t mqttReconnectCount = 0;
|
||||||
|
// bool mqttFirstConnect = true;
|
||||||
|
|
||||||
|
mqttClient.setServer(mqttServer, 1883);
|
||||||
|
// mqttClient.setSocketTimeout(10); //in seconds
|
||||||
|
|
||||||
|
/* Construct unique Client ID*/
|
||||||
|
{
|
||||||
|
String mac = halGetMacAddress(3, "");
|
||||||
|
mac.toLowerCase();
|
||||||
|
memset(mqttClientId, 0, sizeof(mqttClientId));
|
||||||
|
snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR(D_MQTT_DEFAULT_NAME), mac.c_str());
|
||||||
|
LOG_INFO(TAG_MQTT, mqttClientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to connect and set LWT and Clean Session
|
||||||
|
snprintf_P(buffer, sizeof(buffer), PSTR("%s" LWT_TOPIC), mqttNodeTopic); // lastWillTopic
|
||||||
|
snprintf_P(lastWillPayload, sizeof(lastWillPayload), PSTR("offline")); // lastWillPayload
|
||||||
|
|
||||||
|
haspProgressMsg(F(D_MQTT_CONNECTING));
|
||||||
|
haspProgressVal(mqttReconnectCount * 5);
|
||||||
|
if(!mqttClient.connect(mqttClientId, mqttUser, mqttPassword, buffer, 0, true, lastWillPayload, true)) {
|
||||||
|
// Retry until we give up and restart after connectTimeout seconds
|
||||||
|
mqttReconnectCount++;
|
||||||
|
|
||||||
|
switch(mqttClient.state()) {
|
||||||
|
case MQTT_CONNECTION_TIMEOUT:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("Connection timeout"));
|
||||||
|
break;
|
||||||
|
case MQTT_CONNECTION_LOST:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("Connection lost"));
|
||||||
|
break;
|
||||||
|
case MQTT_CONNECT_FAILED:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("Connection failed"));
|
||||||
|
break;
|
||||||
|
case MQTT_DISCONNECTED:
|
||||||
|
snprintf_P(buffer, sizeof(buffer), PSTR(D_MQTT_DISCONNECTED));
|
||||||
|
break;
|
||||||
|
case MQTT_CONNECTED:
|
||||||
|
break;
|
||||||
|
case MQTT_CONNECT_BAD_PROTOCOL:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("MQTT version not suported"));
|
||||||
|
break;
|
||||||
|
case MQTT_CONNECT_BAD_CLIENT_ID:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("Client ID rejected"));
|
||||||
|
break;
|
||||||
|
case MQTT_CONNECT_UNAVAILABLE:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("Server unavailable"));
|
||||||
|
break;
|
||||||
|
case MQTT_CONNECT_BAD_CREDENTIALS:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("Bad credentials"));
|
||||||
|
break;
|
||||||
|
case MQTT_CONNECT_UNAUTHORIZED:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("Unauthorized"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_WARNING(TAG_MQTT, F("Unknown failure"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mqttReconnectCount > 20) {
|
||||||
|
LOG_ERROR(TAG_MQTT, F("Retry count exceeded, rebooting..."));
|
||||||
|
dispatch_reboot(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(TAG_MQTT, F(D_MQTT_CONNECTED), mqttServer, mqttClientId);
|
||||||
|
|
||||||
|
// Subscribe to our incoming topics
|
||||||
|
const __FlashStringHelper * F_topic;
|
||||||
|
F_topic = F("%scommand/#");
|
||||||
|
mqttSubscribeTo(F_topic, mqttGroupTopic);
|
||||||
|
mqttSubscribeTo(F_topic, mqttNodeTopic);
|
||||||
|
F_topic = F("%sconfig/#");
|
||||||
|
mqttSubscribeTo(F_topic, mqttGroupTopic);
|
||||||
|
mqttSubscribeTo(F_topic, mqttNodeTopic);
|
||||||
|
mqttSubscribeTo(F("%slight/#"), mqttNodeTopic);
|
||||||
|
mqttSubscribeTo(F("%sbrightness/#"), mqttNodeTopic);
|
||||||
|
// mqttSubscribeTo(F("%s"LWT_TOPIC), mqttNodeTopic);
|
||||||
|
mqttSubscribeTo(F("hass/status"), mqttClientId);
|
||||||
|
|
||||||
|
/* Home Assistant auto-configuration */
|
||||||
|
if(mqttHAautodiscover) mqttSubscribeTo(F("homeassistant/status"), mqttClientId);
|
||||||
|
|
||||||
|
// Force any subscribed clients to toggle offline/online when we first connect to
|
||||||
|
// make sure we get a full panel refresh at power on. Sending offline,
|
||||||
|
// "online" will be sent by the mqttStatusTopic subscription action.
|
||||||
|
mqtt_send_lwt(true);
|
||||||
|
|
||||||
|
// mqttFirstConnect = false;
|
||||||
|
mqttReconnectCount = 0;
|
||||||
|
|
||||||
|
haspReconnect();
|
||||||
|
haspProgressVal(255);
|
||||||
|
|
||||||
|
dispatch_current_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttSetup()
|
||||||
|
{
|
||||||
|
mqttEnabled = strlen(mqttServer) > 0 && mqttPort > 0;
|
||||||
|
if(mqttEnabled) {
|
||||||
|
mqttClient.setServer(mqttServer, mqttPort);
|
||||||
|
mqttClient.setCallback(mqtt_message_cb);
|
||||||
|
// if(!mqttClient.setBufferSize(1024)) {
|
||||||
|
// LOG_ERROR(TAG_MQTT, F("Buffer allocation failed"));
|
||||||
|
// } else {
|
||||||
|
LOG_INFO(TAG_MQTT, F(D_MQTT_STARTED), mqttClient.getBufferSize());
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(TAG_MQTT, F(D_MQTT_NOT_CONFIGURED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttLoop(void)
|
||||||
|
{
|
||||||
|
if(mqttEnabled) mqttClient.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttEvery5Seconds(bool networkIsConnected)
|
||||||
|
{
|
||||||
|
if(mqttEnabled && networkIsConnected && !mqttClient.connected()) {
|
||||||
|
LOG_TRACE(TAG_MQTT, F(D_MQTT_RECONNECTING));
|
||||||
|
mqttStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String mqttGetNodename()
|
||||||
|
{
|
||||||
|
return mqttNodeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttStop()
|
||||||
|
{
|
||||||
|
if(mqttEnabled && mqttClient.connected()) {
|
||||||
|
LOG_TRACE(TAG_MQTT, F(D_MQTT_DISCONNECTING));
|
||||||
|
mqtt_send_lwt(false);
|
||||||
|
mqttClient.disconnect();
|
||||||
|
LOG_INFO(TAG_MQTT, F(D_MQTT_DISCONNECTED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HASP_USE_CONFIG > 0
|
||||||
|
bool mqttGetConfig(const JsonObject & settings)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if(strcmp(mqttNodeName, settings[FPSTR(FP_CONFIG_NAME)].as<String>().c_str()) != 0) changed = true;
|
||||||
|
settings[FPSTR(FP_CONFIG_NAME)] = mqttNodeName;
|
||||||
|
|
||||||
|
if(strcmp(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)].as<String>().c_str()) != 0) changed = true;
|
||||||
|
settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName;
|
||||||
|
|
||||||
|
if(strcmp(mqttServer, settings[FPSTR(FP_CONFIG_HOST)].as<String>().c_str()) != 0) changed = true;
|
||||||
|
settings[FPSTR(FP_CONFIG_HOST)] = mqttServer;
|
||||||
|
|
||||||
|
if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as<uint16_t>()) changed = true;
|
||||||
|
settings[FPSTR(FP_CONFIG_PORT)] = mqttPort;
|
||||||
|
|
||||||
|
if(strcmp(mqttUser, settings[FPSTR(FP_CONFIG_USER)].as<String>().c_str()) != 0) changed = true;
|
||||||
|
settings[FPSTR(FP_CONFIG_USER)] = mqttUser;
|
||||||
|
|
||||||
|
if(strcmp(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)].as<String>().c_str()) != 0) changed = true;
|
||||||
|
settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword;
|
||||||
|
|
||||||
|
if(changed) configOutput(settings, TAG_MQTT);
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set MQTT Configuration.
|
||||||
|
*
|
||||||
|
* Read the settings from json and sets the application variables.
|
||||||
|
*
|
||||||
|
* @note: data pixel should be formated to uint32_t RGBA. Imagemagick requirements.
|
||||||
|
*
|
||||||
|
* @param[in] settings JsonObject with the config settings.
|
||||||
|
**/
|
||||||
|
bool mqttSetConfig(const JsonObject & settings)
|
||||||
|
{
|
||||||
|
configOutput(settings, TAG_MQTT);
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
changed |= configSet(mqttPort, settings[FPSTR(FP_CONFIG_PORT)], F("mqttPort"));
|
||||||
|
|
||||||
|
if(!settings[FPSTR(FP_CONFIG_NAME)].isNull()) {
|
||||||
|
changed |= strcmp(mqttNodeName, settings[FPSTR(FP_CONFIG_NAME)]) != 0;
|
||||||
|
strncpy(mqttNodeName, settings[FPSTR(FP_CONFIG_NAME)], sizeof(mqttNodeName));
|
||||||
|
}
|
||||||
|
// Prefill node name
|
||||||
|
if(strlen(mqttNodeName) == 0) {
|
||||||
|
String mac = halGetMacAddress(3, "");
|
||||||
|
mac.toLowerCase();
|
||||||
|
snprintf_P(mqttNodeName, sizeof(mqttNodeName), PSTR(D_MQTT_DEFAULT_NAME), mac.c_str());
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!settings[FPSTR(FP_CONFIG_GROUP)].isNull()) {
|
||||||
|
changed |= strcmp(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)]) != 0;
|
||||||
|
strncpy(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)], sizeof(mqttGroupName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strlen(mqttGroupName) == 0) {
|
||||||
|
strcpy_P(mqttGroupName, PSTR("plates"));
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!settings[FPSTR(FP_CONFIG_HOST)].isNull()) {
|
||||||
|
changed |= strcmp(mqttServer, settings[FPSTR(FP_CONFIG_HOST)]) != 0;
|
||||||
|
strncpy(mqttServer, settings[FPSTR(FP_CONFIG_HOST)], sizeof(mqttServer));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!settings[FPSTR(FP_CONFIG_USER)].isNull()) {
|
||||||
|
changed |= strcmp(mqttUser, settings[FPSTR(FP_CONFIG_USER)]) != 0;
|
||||||
|
strncpy(mqttUser, settings[FPSTR(FP_CONFIG_USER)], sizeof(mqttUser));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!settings[FPSTR(FP_CONFIG_PASS)].isNull() &&
|
||||||
|
settings[FPSTR(FP_CONFIG_PASS)].as<String>() != String(FPSTR(D_PASSWORD_MASK))) {
|
||||||
|
changed |= strcmp(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)]) != 0;
|
||||||
|
strncpy(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)], sizeof(mqttPassword));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf_P(mqttNodeTopic, sizeof(mqttNodeTopic), PSTR(MQTT_PREFIX "/%s/"), mqttNodeName);
|
||||||
|
snprintf_P(mqttGroupTopic, sizeof(mqttGroupTopic), PSTR(MQTT_PREFIX "/%s/"), mqttGroupName);
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
#endif // HASP_USE_CONFIG
|
||||||
|
|
||||||
|
#endif // PUBSUBCLIENT
|
||||||
|
|
||||||
|
#endif // HASP_USE_MQTT
|
33
tools/sdl2_build_extra.py
Normal file
33
tools/sdl2_build_extra.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
Import("env", "projenv")
|
||||||
|
|
||||||
|
for e in [ env, projenv ]:
|
||||||
|
# If compiler uses `-m32`, propagate it to linker.
|
||||||
|
# Add via script, because `-Wl,-m32` does not work.
|
||||||
|
if "-m32" in e['CCFLAGS']:
|
||||||
|
e.Append(LINKFLAGS = ["-m32"])
|
||||||
|
|
||||||
|
env.Append(
|
||||||
|
LINKFLAGS=[
|
||||||
|
"-static",
|
||||||
|
"-static-libgcc",
|
||||||
|
"-static-libstdc++"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Override unused "upload" to execute compiled binary
|
||||||
|
from SCons.Script import AlwaysBuild
|
||||||
|
AlwaysBuild(env.Alias("build", "$BUILD_DIR/${PROGNAME}", "$BUILD_DIR/${PROGNAME}"))
|
||||||
|
|
||||||
|
# Add custom target to explorer
|
||||||
|
env.AddTarget(
|
||||||
|
name = "execute",
|
||||||
|
dependencies = "$BUILD_DIR\${PROGNAME}.exe",
|
||||||
|
actions = "$BUILD_DIR\${PROGNAME}.exe",
|
||||||
|
# actions = 'cmd.exe /C "start cmd.exe /C $BUILD_DIR\${PROGNAME}.exe"',
|
||||||
|
title = "Execute",
|
||||||
|
description = "Build and execute",
|
||||||
|
group="General"
|
||||||
|
)
|
||||||
|
|
||||||
|
#print('=====================================')
|
||||||
|
#print(env.Dump())
|
Loading…
x
Reference in New Issue
Block a user