stm32f103_lvgl_8080lcd: finish touchscreen calibration code
This commit is contained in:
parent
500130bf8a
commit
9b8e1db906
@ -4,6 +4,10 @@
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
#define BSP_XPT2046_SPI hspi2
|
||||
#define BSP_XPT2046_EEPROM_I2C hi2c2
|
||||
|
||||
#define BSP_XPT2046_EEPROM_I2C_OFFSET 0
|
||||
#define BSP_XPT2046_AVG_SAMPLES 16 //必须是偶数
|
||||
|
||||
HAL_StatusTypeDef bsp_xpt2046_get_touch_status(void);
|
||||
void bsp_xpt2046_get_adc(uint16_t *x_adc, uint16_t *y_adc);
|
||||
|
||||
@ -18,7 +18,7 @@ void app_main(void)
|
||||
lv_init();
|
||||
lv_port_disp_init();
|
||||
lv_create_tick();
|
||||
|
||||
|
||||
uint8_t force = HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET;
|
||||
touchscreen_calibration(force);
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "bsp_xpt2046.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "main.h"
|
||||
#include "util_delay_us.h"
|
||||
|
||||
@ -15,7 +16,7 @@ static uint16_t bsp_xpt2046_conv(uint8_t cmd)
|
||||
HAL_GPIO_WritePin(T_CS_GPIO_Port, T_CS_Pin, GPIO_PIN_RESET); //选中芯片
|
||||
|
||||
HAL_SPI_Transmit(&BSP_XPT2046_SPI, &cmd, 1, 200); //发送指令
|
||||
delay_us(4); //等待转换完成
|
||||
delay_us(2); //等待转换完成 实际延时超过所需最短延时4us
|
||||
|
||||
uint8_t received_data[2];
|
||||
uint8_t transmit_data[2] = { 0x00, 0x00 }; //接收时MOSI必须保持固定电平 否则数据出错
|
||||
@ -25,10 +26,30 @@ static uint16_t bsp_xpt2046_conv(uint8_t cmd)
|
||||
return ((uint16_t)received_data[0] << 8 | received_data[1]) >> 4;
|
||||
}
|
||||
|
||||
static int qsort_comparator(const void *a, const void *b)
|
||||
{
|
||||
return *(uint16_t *)a - *(uint16_t *)b;
|
||||
}
|
||||
|
||||
void bsp_xpt2046_get_adc(uint16_t *x_adc, uint16_t *y_adc)
|
||||
{
|
||||
*x_adc = bsp_xpt2046_conv(BSP_XPT2046_CMD_CONV_X);
|
||||
*y_adc = bsp_xpt2046_conv(BSP_XPT2046_CMD_CONV_Y);
|
||||
uint16_t x_adcs[BSP_XPT2046_AVG_SAMPLES], y_adcs[BSP_XPT2046_AVG_SAMPLES];
|
||||
for (uint8_t i = 0; i < BSP_XPT2046_AVG_SAMPLES; i ++) {
|
||||
x_adcs[i] = bsp_xpt2046_conv(BSP_XPT2046_CMD_CONV_X);
|
||||
y_adcs[i] = bsp_xpt2046_conv(BSP_XPT2046_CMD_CONV_Y);
|
||||
}
|
||||
|
||||
qsort(x_adcs, BSP_XPT2046_AVG_SAMPLES, sizeof(x_adcs[0]), qsort_comparator);
|
||||
qsort(y_adcs, BSP_XPT2046_AVG_SAMPLES, sizeof(y_adcs[0]), qsort_comparator); //升序排序
|
||||
|
||||
uint32_t x_adc_sum = 0, y_adc_sum = 0; //求中间n/2个数的平均值
|
||||
for (uint8_t i = BSP_XPT2046_AVG_SAMPLES / 4; i < BSP_XPT2046_AVG_SAMPLES - BSP_XPT2046_AVG_SAMPLES / 4; i ++) {
|
||||
x_adc_sum += x_adcs[i];
|
||||
y_adc_sum += y_adcs[i];
|
||||
}
|
||||
|
||||
*x_adc = x_adc_sum / (BSP_XPT2046_AVG_SAMPLES / 2);
|
||||
*y_adc = y_adc_sum / (BSP_XPT2046_AVG_SAMPLES / 2);
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef bsp_xpt2046_get_touch_status(void)
|
||||
@ -38,9 +59,8 @@ HAL_StatusTypeDef bsp_xpt2046_get_touch_status(void)
|
||||
|
||||
HAL_StatusTypeDef bsp_xpt2046_get_coord(uint16_t *x, uint16_t *y)
|
||||
{
|
||||
if (tp_x_factor == 0 || tp_x_offset == 0 || tp_y_factor == 0 || tp_y_offset == 0 ||
|
||||
tp_lcd_x_pixels == 0 || tp_lcd_y_pixels == 0) {
|
||||
return HAL_ERROR;
|
||||
if (tp_x_factor == 0 || tp_y_factor == 0 || tp_lcd_x_pixels == 0) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
uint16_t x_adc, y_adc;
|
||||
@ -60,17 +80,49 @@ HAL_StatusTypeDef bsp_xpt2046_calibrate(const uint16_t x_pos[], const uint16_t y
|
||||
tp_y_factor = (float)(y_pos[1] - y_pos[0]) / (y_val[1] - y_val[0]);
|
||||
tp_y_offset = (float)y_pos[0] - tp_y_factor * y_val[0];
|
||||
|
||||
//将校准值写入EEPROM
|
||||
printf("tp_x_factor=%.3f, tp_x_offset=%.3f\r\n", tp_x_factor, tp_x_offset);
|
||||
printf("tp_y_factor=%.3f, tp_y_offset=%.3f\r\n", tp_y_factor, tp_y_offset);
|
||||
printf("tp_x_factor=%.3f, tp_x_offset=%.3f\n", tp_x_factor, tp_x_offset);
|
||||
printf("tp_y_factor=%.3f, tp_y_offset=%.3f\n", tp_y_factor, tp_y_offset);
|
||||
|
||||
return HAL_OK;
|
||||
//将校准值写入EEPROM
|
||||
HAL_StatusTypeDef status;
|
||||
uint8_t addr = BSP_XPT2046_EEPROM_I2C_OFFSET;
|
||||
status |= HAL_I2C_Mem_Write(&BSP_XPT2046_EEPROM_I2C, 0x50 << 1, addr, 1, (uint8_t *)&tp_x_factor, sizeof(tp_x_factor), 200);
|
||||
addr += sizeof(tp_x_factor);
|
||||
HAL_Delay(2); //EEPROM写入比较慢
|
||||
status |= HAL_I2C_Mem_Write(&BSP_XPT2046_EEPROM_I2C, 0x50 << 1, addr, 1, (uint8_t *)&tp_x_offset, sizeof(tp_x_offset), 200);
|
||||
addr += sizeof(tp_x_offset);
|
||||
HAL_Delay(2);
|
||||
status |= HAL_I2C_Mem_Write(&BSP_XPT2046_EEPROM_I2C, 0x50 << 1, addr, 1, (uint8_t *)&tp_y_factor, sizeof(tp_y_factor), 200);
|
||||
addr += sizeof(tp_y_factor);
|
||||
HAL_Delay(2);
|
||||
status |= HAL_I2C_Mem_Write(&BSP_XPT2046_EEPROM_I2C, 0x50 << 1, addr, 1, (uint8_t *)&tp_y_offset, sizeof(tp_y_offset), 200);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef bsp_xpt2046_load_calib_data(uint16_t lcd_x_pixels, uint16_t lcd_y_pixels)
|
||||
{
|
||||
if (lcd_x_pixels == 0 || lcd_y_pixels == 0) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
tp_lcd_x_pixels = lcd_x_pixels;
|
||||
tp_lcd_y_pixels = lcd_y_pixels;
|
||||
|
||||
return HAL_OK;
|
||||
HAL_StatusTypeDef status;
|
||||
uint8_t addr = BSP_XPT2046_EEPROM_I2C_OFFSET;
|
||||
status |= HAL_I2C_Mem_Read(&BSP_XPT2046_EEPROM_I2C, 0x50 << 1, addr, 1, (uint8_t *)&tp_x_factor, sizeof(tp_x_factor), 200);
|
||||
addr += sizeof(tp_x_factor);
|
||||
status |= HAL_I2C_Mem_Read(&BSP_XPT2046_EEPROM_I2C, 0x50 << 1, addr, 1, (uint8_t *)&tp_x_offset, sizeof(tp_x_offset), 200);
|
||||
addr += sizeof(tp_x_offset);
|
||||
status |= HAL_I2C_Mem_Read(&BSP_XPT2046_EEPROM_I2C, 0x50 << 1, addr, 1, (uint8_t *)&tp_y_factor, sizeof(tp_y_factor), 200);
|
||||
addr += sizeof(tp_y_factor);
|
||||
status |= HAL_I2C_Mem_Read(&BSP_XPT2046_EEPROM_I2C, 0x50 << 1, addr, 1, (uint8_t *)&tp_y_offset, sizeof(tp_y_offset), 200);
|
||||
|
||||
if (tp_x_factor == 0 || tp_y_factor == 0 || *(uint32_t *)&tp_x_factor == 0xFFFFFFFF || *(uint32_t *)&tp_y_factor == 0xFFFFFFFF ||
|
||||
tp_x_offset == 0 || tp_y_offset == 0 || *(uint32_t *)&tp_x_offset == 0xFFFFFFFF || *(uint32_t *)&tp_y_offset == 0xFFFFFFFF) {
|
||||
return HAL_ERROR;
|
||||
} else {
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#include "lv_port_indev.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "bsp_xpt2046.h"
|
||||
|
||||
lv_indev_t *indev_touchpad;
|
||||
@ -9,13 +8,18 @@ static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
static lv_coord_t last_x = 0;
|
||||
static lv_coord_t last_y = 0;
|
||||
|
||||
|
||||
if(HAL_GPIO_ReadPin(T_PEN_GPIO_Port, T_PEN_Pin) == GPIO_PIN_RESET) {
|
||||
|
||||
if(bsp_xpt2046_get_touch_status() == HAL_OK) {
|
||||
uint16_t x_coord, y_coord;
|
||||
bsp_xpt2046_get_coord(&x_coord, &y_coord);
|
||||
last_x = x_coord; last_y = y_coord;
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
HAL_StatusTypeDef status = bsp_xpt2046_get_coord(&x_coord, &y_coord);
|
||||
|
||||
if (status == HAL_OK) {
|
||||
last_x = x_coord; last_y = y_coord;
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
LV_LOG_ERROR("Touchscreen is not properly calibrated!");
|
||||
}
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
@ -26,10 +30,10 @@ static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
|
||||
void lv_port_indev_init(void)
|
||||
{
|
||||
static lv_indev_drv_t indev_drv;
|
||||
static lv_indev_drv_t indev_drv;
|
||||
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = touchpad_read;
|
||||
indev_touchpad = lv_indev_drv_register(&indev_drv);
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = touchpad_read;
|
||||
indev_touchpad = lv_indev_drv_register(&indev_drv);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "main.h"
|
||||
#include "lvgl.h"
|
||||
#include "bsp_lcd_ili9341.h"
|
||||
#include "bsp_xpt2046.h"
|
||||
|
||||
@ -20,25 +21,72 @@ void draw_cross(uint16_t x_center, uint16_t y_center)
|
||||
|
||||
void touchscreen_calibration(uint8_t force)
|
||||
{
|
||||
uint16_t x_pos[2] = { 20, BSP_LCD_X_PIXELS - 20 }, y_pos[2] = { 20, BSP_LCD_Y_PIXELS - 20 };
|
||||
uint16_t x_val[2], y_val[2];
|
||||
HAL_StatusTypeDef status = bsp_xpt2046_load_calib_data(BSP_LCD_X_PIXELS, BSP_LCD_Y_PIXELS);
|
||||
if (status == HAL_OK && force == 0) {
|
||||
printf("load touchscreen calibration data from eeprom success\n");
|
||||
return;
|
||||
} else {
|
||||
printf("load touchscreen calibration data from eeprom failed, re-calibrating\n");
|
||||
}
|
||||
|
||||
draw_cross(x_pos[0], y_pos[0]);
|
||||
while (bsp_xpt2046_get_touch_status() == HAL_ERROR);
|
||||
HAL_Delay(50);
|
||||
uint16_t x_pos[2], y_pos[2], x_val[2], y_val[2];
|
||||
|
||||
lv_obj_t *cross = lv_obj_create(lv_scr_act());
|
||||
lv_obj_set_size(cross, 59, 59); //创建一个59x59大小的容器
|
||||
lv_obj_clear_flag(cross, LV_OBJ_FLAG_SCROLLABLE); //防止出现滚动条
|
||||
lv_obj_set_style_bg_opa(cross, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_opa(cross, LV_OPA_TRANSP, 0); //设置容器完全透明
|
||||
|
||||
lv_style_t style_line;
|
||||
lv_style_init(&style_line); //创建线条样式
|
||||
lv_style_set_line_width(&style_line, 3);
|
||||
lv_style_set_line_color(&style_line, lv_palette_main(LV_PALETTE_RED)); //红色 3像素宽
|
||||
|
||||
const static lv_point_t cross_ver_line_points[2] = { { 0, 0 }, { 0, 30 } };
|
||||
lv_obj_t *cross_ver_line = lv_line_create(cross); //十字中的竖线
|
||||
lv_line_set_points(cross_ver_line, cross_ver_line_points, 2);
|
||||
lv_obj_add_style(cross_ver_line, &style_line, 0);
|
||||
lv_obj_center(cross_ver_line); //居中对齐
|
||||
|
||||
const static lv_point_t cross_hor_line_points[2] = { { 0, 0 }, { 30, 0 } };
|
||||
lv_obj_t *cross_hor_line = lv_line_create(cross); //十字中的横线
|
||||
lv_line_set_points(cross_hor_line, cross_hor_line_points, 2);
|
||||
lv_obj_add_style(cross_hor_line, &style_line, 0);
|
||||
lv_obj_center(cross_hor_line);
|
||||
|
||||
lv_obj_align(cross, LV_ALIGN_TOP_LEFT, 0, 0); //十字首先置于左上角
|
||||
lv_area_t cross_obj_area;
|
||||
lv_obj_update_layout(cross); //需要先重新计算布局才能获取容器尺寸
|
||||
lv_obj_get_content_coords(cross, &cross_obj_area); //获取容器尺寸
|
||||
|
||||
x_pos[0] = (cross_obj_area.x1 + cross_obj_area.x2) / 2;
|
||||
y_pos[0] = (cross_obj_area.y1 + cross_obj_area.y2) / 2; //计算得到十字中点坐标
|
||||
|
||||
while (bsp_xpt2046_get_touch_status() != HAL_OK) {
|
||||
lv_task_handler();
|
||||
}
|
||||
bsp_xpt2046_get_adc(&x_val[0], &y_val[0]);
|
||||
printf("x: 0x%03X, y: 0x%03X\r\n", x_val[0], y_val[0]);
|
||||
HAL_Delay(50);
|
||||
while (bsp_xpt2046_get_touch_status() == HAL_OK);
|
||||
|
||||
draw_cross(x_pos[1], y_pos[1]);
|
||||
while (bsp_xpt2046_get_touch_status() == HAL_ERROR);
|
||||
HAL_Delay(50);
|
||||
lv_obj_align(cross, LV_ALIGN_BOTTOM_RIGHT, 0, 0); //然后将置于右下角
|
||||
lv_obj_update_layout(cross); //需要先重新计算布局才能获取容器尺寸
|
||||
lv_obj_get_content_coords(cross, &cross_obj_area); //获取容器尺寸
|
||||
|
||||
x_pos[1] = (cross_obj_area.x1 + cross_obj_area.x2) / 2;
|
||||
y_pos[1] = (cross_obj_area.y1 + cross_obj_area.y2) / 2; //计算得到十字中点坐标
|
||||
|
||||
while (bsp_xpt2046_get_touch_status() != HAL_OK) {
|
||||
lv_task_handler();
|
||||
}
|
||||
bsp_xpt2046_get_adc(&x_val[1], &y_val[1]);
|
||||
printf("x: 0x%03X, y: 0x%03X\r\n", x_val[1], y_val[1]);
|
||||
HAL_Delay(50);
|
||||
while (bsp_xpt2046_get_touch_status() == HAL_OK);
|
||||
|
||||
bsp_xpt2046_calibrate(x_pos, y_pos, x_val, y_val);
|
||||
bsp_xpt2046_load_calib_data(BSP_LCD_X_PIXELS, BSP_LCD_Y_PIXELS);
|
||||
status = bsp_xpt2046_calibrate(x_pos, y_pos, x_val, y_val);
|
||||
if (status != HAL_OK) {
|
||||
printf("error while saving calibration data to eeprom, code=%d\n", status);
|
||||
} else {
|
||||
printf("successfully saved calibration data to eeprom\n");
|
||||
}
|
||||
|
||||
lv_obj_del(cross);
|
||||
}
|
||||
|
||||
@ -153,7 +153,102 @@
|
||||
<Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_512 -FS08000000 -FL080000 -FP0($$Device:STM32F103ZE$Flash\STM32F10x_512.FLM))</Name>
|
||||
</SetRegEntry>
|
||||
</TargetDriverDllRegistry>
|
||||
<Breakpoint/>
|
||||
<Breakpoint>
|
||||
<Bp>
|
||||
<Number>0</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>106</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>..\Core\Src\bsp_xpt2046.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>99</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>..\Core\Src\bsp_xpt2046.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>2</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>44</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>..\Core\Src\bsp_xpt2046.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>3</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>117</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>startup_stm32f103xe.s</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
</Breakpoint>
|
||||
<WatchWindow1>
|
||||
<Ww>
|
||||
<count>0</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>tp_x_factor</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>1</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>tp_x_offset</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>2</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>tp_y_factor</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>3</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>tp_y_offset</ItemText>
|
||||
</Ww>
|
||||
</WatchWindow1>
|
||||
<MemoryWindow1>
|
||||
<Mm>
|
||||
<WinNumber>1</WinNumber>
|
||||
<SubType>0</SubType>
|
||||
<ItemText>tp_calib_data</ItemText>
|
||||
<AccSizeX>0</AccSizeX>
|
||||
</Mm>
|
||||
</MemoryWindow1>
|
||||
<Tracepoint>
|
||||
<THDelay>0</THDelay>
|
||||
</Tracepoint>
|
||||
@ -196,16 +291,6 @@
|
||||
<pszMrulep></pszMrulep>
|
||||
<pSingCmdsp></pSingCmdsp>
|
||||
<pMultCmdsp></pMultCmdsp>
|
||||
<SystemViewers>
|
||||
<Entry>
|
||||
<Name>System Viewer\DMA1</Name>
|
||||
<WinId>35905</WinId>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Name>System Viewer\FSMC</Name>
|
||||
<WinId>35904</WinId>
|
||||
</Entry>
|
||||
</SystemViewers>
|
||||
<DebugDescription>
|
||||
<Enable>1</Enable>
|
||||
<EnableFlashSeq>1</EnableFlashSeq>
|
||||
|
||||
@ -313,7 +313,7 @@
|
||||
</ArmAdsMisc>
|
||||
<Cads>
|
||||
<interw>1</interw>
|
||||
<Optim>5</Optim>
|
||||
<Optim>2</Optim>
|
||||
<oTime>0</oTime>
|
||||
<SplitLS>0</SplitLS>
|
||||
<OneElfS>1</OneElfS>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user