存档:负数处理功能基本完成,待后续排查
This commit is contained in:
parent
c8ca325958
commit
008b4279f1
|
@ -2,7 +2,7 @@
|
|||
* @Author: wujunchao wujunchao@wuxismart.com
|
||||
* @Date: 2024-12-27 11:51:06
|
||||
* @LastEditors: wujunchao wujunchao@wuxismart.com
|
||||
* @LastEditTime: 2025-03-12 17:11:15
|
||||
* @LastEditTime: 2025-03-13 11:52:18
|
||||
* @FilePath: \signal_generator\App\APP_WU\Inc\apps_gather.h
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
|
@ -70,7 +70,7 @@ extern const lv_img_dsc_t * screen_main_ani_out_sign_imgs[3];
|
|||
#define KEY_BACK 94
|
||||
|
||||
//绝对值计算
|
||||
#define MY_ABS(pa, pb) ( ( (pa-pb) >= 0 )?(pa-pb):(pb-pa) )
|
||||
#define MY_ABS(pa) ( ( (pa) >= 0 )?( (pa) ):( 0 - (pa) ) )
|
||||
|
||||
//初始界面
|
||||
//{
|
||||
|
@ -107,6 +107,12 @@ extern const lv_img_dsc_t * screen_main_ani_out_sign_imgs[3];
|
|||
//绘图等待滴答数上限
|
||||
#define PLOT_WAIT_TICK_MAX 5
|
||||
|
||||
//数码管数值增加(正负情况交替时,up和down两个键起到的作用会对调,因此专门定义参数用于区分数值的增减)
|
||||
#define NIXIE_INCREASE 1
|
||||
|
||||
//数码管数值增加(正负情况交替时,up和down两个键起到的作用会对调,因此专门定义参数用于区分数值的增减)
|
||||
#define NIXIE_DECREASE 0
|
||||
|
||||
//}
|
||||
|
||||
//设置界面
|
||||
|
@ -269,6 +275,9 @@ typedef struct
|
|||
//模拟正式产品,实现基本功能
|
||||
void menu_test5(void);
|
||||
|
||||
//计算a的b次方
|
||||
float32 my_power(int a, int b);
|
||||
|
||||
//物理量内容初始化
|
||||
void physical_quantity_init(void);
|
||||
|
||||
|
@ -308,14 +317,21 @@ void plot_drawing(void);
|
|||
//设置游标位置【0000.000】,0~7
|
||||
void set_cursor_position(void);
|
||||
|
||||
//设置数码管符号位
|
||||
//设置数码管符号位,0->熄灭,1->显示负号
|
||||
void set_nixie_cube_sign(uint8_t on2off, uint8_t sg);
|
||||
|
||||
//设置数码管显示值:io_slc->输入/输出,pos->第几个数字,num->数值
|
||||
//补充说明:pos = 99时,num=[0000000,9999999];pos = 10时,数值显示为空白。
|
||||
//该部分未对输出缓存数组做处理
|
||||
void set_nixie_cube(uint8_t io_slc, uint8_t pos, int32_t num);
|
||||
|
||||
//按键触发后对数码管值进行修改(主角界面KEY_UP & KEY_DOWN, dir->KEY_UP/KEY_DOWN, val->步进量
|
||||
//获取当前设定的输出值(数组&符号 -> (有符号)实际值)
|
||||
float32 get_output_value(void);
|
||||
|
||||
//设置当前的输出值(实际值*1000 -> (无符号)数组),可直接输入负数
|
||||
void set_output_value(int32_t pvo);
|
||||
|
||||
//改变数码管的显示与缓存值,dir:增加或减少(NIXIE_INCREASE & NIXIE_DECREASE),val:改变量(通常为1)
|
||||
void change_nixie_cube_OUT(uint8_t dir, uint8_t val);
|
||||
|
||||
//设置工作模式和工作模式类型
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: wujunchao wujunchao@wuxismart.com
|
||||
* @Date: 2024-12-27 11:50:56
|
||||
* @LastEditors: wujunchao wujunchao@wuxismart.com
|
||||
* @LastEditTime: 2025-03-13 08:28:54
|
||||
* @LastEditTime: 2025-03-13 12:13:11
|
||||
* @FilePath: \signal_generator\App\APP_WU\Src\apps_gather.c
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
|
@ -327,8 +327,60 @@ void key_functions_main(void)
|
|||
m5data.twk_flag = 1; // 上、下、左、右 任意一个键按下后,闪烁开始
|
||||
m5data.twk_cnt = 0; //每次按下后闪烁计数清零
|
||||
|
||||
//该部分需要作溢出判断:第0个数字达到9之后不作循环处理,第1~5个数字达到9后循环计数并向前进1(直至第0个为9)
|
||||
change_nixie_cube_OUT(KEY_UP, 1);
|
||||
uint8_t step = 1; //up键步长,默认为1
|
||||
float32 step_real = 0; //实际值步长
|
||||
float32 pv = 0, sv = 0, up = 0;
|
||||
|
||||
//根据当前游标位置计算步进值
|
||||
step_real = step * my_power(10, (3 - m5data.io_cursor));
|
||||
//按下up键后,即将刷新的实际值
|
||||
pv = get_output_value();
|
||||
sv = pv + step_real;
|
||||
up = pltdata.yreal_pri_up;
|
||||
|
||||
if( sv >= up )
|
||||
{
|
||||
//超过上限的情况下,直接显示上限
|
||||
sv = up;
|
||||
sv *= 1000;
|
||||
set_nixie_cube(IO_OUTPUT, 99, (int32_t)sv);
|
||||
set_output_value((int32_t)sv);
|
||||
|
||||
if(up >= 0)
|
||||
{
|
||||
set_nixie_cube_sign(IO_OUTPUT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_nixie_cube_sign(IO_OUTPUT, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//没超过上限的情况下,仅考虑pv、0、sv三者的位置关系
|
||||
if( pv >= 0 )
|
||||
{
|
||||
//一定为正数,直接调用以下函数,增加数值
|
||||
change_nixie_cube_OUT(NIXIE_INCREASE, step);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sv < 0 )
|
||||
{
|
||||
//pv和sv都为负数的情况下,仅调转方向,减小数值
|
||||
change_nixie_cube_OUT(NIXIE_DECREASE, step);
|
||||
}
|
||||
else
|
||||
{
|
||||
//跨越0后,负号熄灭
|
||||
set_nixie_cube_sign(IO_OUTPUT, 0);
|
||||
//pv变为sv后跨越了0,数值可能增大也可能减小,因此直接赋值
|
||||
sv *= 1000;
|
||||
set_nixie_cube(IO_OUTPUT, 99, (int32_t)sv);
|
||||
set_output_value((int32_t)sv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -641,7 +693,61 @@ void key_functions_main(void)
|
|||
m5data.twk_flag = 1; // 上、下、左、右 任意一个键按下后,闪烁开始
|
||||
m5data.twk_cnt = 0; //每次按下后闪烁计数清零
|
||||
|
||||
change_nixie_cube_OUT(KEY_DOWN, 1);
|
||||
uint8_t step = 1; //down键步长,默认为1
|
||||
float32 step_real = 0; //实际值步长
|
||||
float32 pv = 0, sv = 0, low = 0;
|
||||
|
||||
//根据当前游标位置计算步进值
|
||||
step_real = step * my_power(10, (3 - m5data.io_cursor));
|
||||
//按下down键后,即将刷新的实际值
|
||||
pv = get_output_value();
|
||||
sv = pv - step_real;
|
||||
low = pltdata.yreal_pri_low;
|
||||
|
||||
if( sv <= low )
|
||||
{
|
||||
//超过下限的情况下,直接显示下限
|
||||
sv = low;
|
||||
sv *= 1000;
|
||||
set_nixie_cube(IO_OUTPUT, 99, (int32_t)sv);
|
||||
set_output_value((int32_t)sv);
|
||||
|
||||
if(low >= 0)
|
||||
{
|
||||
set_nixie_cube_sign(IO_OUTPUT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_nixie_cube_sign(IO_OUTPUT, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//没超过下限的情况下,仅考虑pv、0、sv三者的位置关系
|
||||
if( sv >= 0 )
|
||||
{
|
||||
//一定为正数,直接调用以下函数,减小数值
|
||||
change_nixie_cube_OUT(NIXIE_DECREASE, step);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pv < 0 )
|
||||
{
|
||||
//pv和sv都为负数的情况下,仅调转方向,增大数值
|
||||
change_nixie_cube_OUT(NIXIE_INCREASE, step);
|
||||
}
|
||||
else
|
||||
{
|
||||
//跨越0后,负号点亮
|
||||
set_nixie_cube_sign(IO_OUTPUT, 1);
|
||||
//pv变为sv后跨越了0,数值可能增大也可能减小,因此直接赋值
|
||||
sv *= 1000;
|
||||
set_nixie_cube(IO_OUTPUT, 99, (int32_t)sv);
|
||||
set_output_value((int32_t)sv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1013,6 +1119,8 @@ void set_nixie_cube(uint8_t io_slc, uint8_t pos, int32_t num)
|
|||
|
||||
case 99:
|
||||
{
|
||||
num = ( num >= 0 )?(num):(0 - num);
|
||||
|
||||
if(num > 9999999)
|
||||
{
|
||||
num = 99999999;
|
||||
|
@ -1057,12 +1165,39 @@ void set_nixie_cube(uint8_t io_slc, uint8_t pos, int32_t num)
|
|||
}
|
||||
}
|
||||
|
||||
//获取当前设定的输出值
|
||||
float32 get_output_value(void)
|
||||
{
|
||||
float32 pvo = 0;
|
||||
|
||||
pvo = m5data.o_numbers[0]*1000 + m5data.o_numbers[1]*100 + 10*m5data.o_numbers[2] + \
|
||||
m5data.o_numbers[3] + m5data.o_numbers[4]*(float32)0.1 + m5data.o_numbers[5]*(float32)0.01 + m5data.o_numbers[6]*(float32)0.001;
|
||||
|
||||
pvo = (m5data.sign_flag_out)?(0 - pvo):(pvo);
|
||||
|
||||
return pvo;
|
||||
}
|
||||
|
||||
//设置当前的输出值(无符号实际值*1000 -> 数组)
|
||||
void set_output_value(int32_t pvo)
|
||||
{
|
||||
pvo = (pvo > 0)?(pvo):(0 - pvo);
|
||||
//将实际值转换成6个独立数字
|
||||
m5data.o_numbers[0] = (pvo/1000000 > 9)?(9):(pvo/1000000);
|
||||
m5data.o_numbers[1] = (pvo/100000) % 10;
|
||||
m5data.o_numbers[2] = (pvo/10000) % 10;
|
||||
m5data.o_numbers[3] = (pvo/1000) % 10;
|
||||
m5data.o_numbers[4] = (pvo/100) % 10;
|
||||
m5data.o_numbers[5] = (pvo/10) % 10;
|
||||
m5data.o_numbers[6] = pvo % 10;
|
||||
}
|
||||
|
||||
//按键触发后对数码管值进行修改(主角界面KEY_UP & KEY_DOWN, dir->KEY_UP/KEY_DOWN, val->步进量
|
||||
void change_nixie_cube_OUT(uint8_t dir, uint8_t val)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case KEY_UP:
|
||||
case NIXIE_INCREASE:
|
||||
{
|
||||
switch (m5data.io_cursor)
|
||||
{
|
||||
|
@ -1217,86 +1352,28 @@ void change_nixie_cube_OUT(uint8_t dir, uint8_t val)
|
|||
break;
|
||||
}
|
||||
|
||||
int oftemp = 0;
|
||||
//发生向上溢出时,根据溢出的位置对实际数值进行处理
|
||||
if(m5data.overflow_flag_up)
|
||||
{
|
||||
int32_t oftemp = 0;
|
||||
//还原成实际数值
|
||||
oftemp = 1000000*m5data.o_numbers[0] + 100000*m5data.o_numbers[1] + 10000*m5data.o_numbers[2] + \
|
||||
1000*m5data.o_numbers[3] + 100*m5data.o_numbers[4] + 10*m5data.o_numbers[5] + m5data.o_numbers[6];
|
||||
|
||||
//发生向上溢出时,根据溢出的位置对实际数值进行处理
|
||||
if(m5data.overflow_flag_up)
|
||||
{
|
||||
//根据溢出的位置对实际值进行计算
|
||||
switch (m5data.overflow_flag_up)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
oftemp += 1000000;
|
||||
}
|
||||
break;
|
||||
oftemp += my_power(10, ( 7 - m5data.overflow_flag_up) );
|
||||
|
||||
case 2:
|
||||
{
|
||||
oftemp += 100000;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
oftemp += 10000;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
oftemp += 1000;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
{
|
||||
oftemp += 100;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
{
|
||||
oftemp += 10;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//输入值上限限幅
|
||||
if(oftemp >= (pltdata.yreal_pri_up*1000) )
|
||||
{
|
||||
oftemp = pltdata.yreal_pri_up*1000;
|
||||
}
|
||||
|
||||
//仅当发生过溢出或者达到上限的情况下才需要执行以下操作
|
||||
if( (m5data.overflow_flag_up)||(oftemp == pltdata.yreal_pri_up*1000) )
|
||||
{
|
||||
set_nixie_cube(IO_OUTPUT, 99, oftemp);
|
||||
|
||||
//将实际值转换成6个独立数字
|
||||
m5data.o_numbers[0] = (oftemp/1000000 > 9)?(9):(oftemp/1000000);
|
||||
m5data.o_numbers[1] = (oftemp/100000) % 10;
|
||||
m5data.o_numbers[2] = (oftemp/10000) % 10;
|
||||
m5data.o_numbers[3] = (oftemp/1000) % 10;
|
||||
m5data.o_numbers[4] = (oftemp/100) % 10;
|
||||
m5data.o_numbers[5] = (oftemp/10) % 10;
|
||||
m5data.o_numbers[6] = oftemp % 10;
|
||||
}
|
||||
set_output_value(oftemp);
|
||||
|
||||
//溢出处理完成,标志清零
|
||||
m5data.overflow_flag_up = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_DOWN:
|
||||
case NIXIE_DECREASE:
|
||||
{
|
||||
switch (m5data.io_cursor)
|
||||
{
|
||||
|
@ -1457,79 +1534,25 @@ void change_nixie_cube_OUT(uint8_t dir, uint8_t val)
|
|||
break;
|
||||
}
|
||||
|
||||
int oftemp = 0;
|
||||
oftemp = 1000000*m5data.o_numbers[0] + 100000*m5data.o_numbers[1] + 10000*m5data.o_numbers[2] + \
|
||||
1000*m5data.o_numbers[3] + 100*m5data.o_numbers[4] + 10*m5data.o_numbers[5] + m5data.o_numbers[6];
|
||||
|
||||
//向下溢出处理
|
||||
if(m5data.overflow_flag_low)
|
||||
{
|
||||
switch (m5data.overflow_flag_low)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
oftemp -= 1000000;
|
||||
}
|
||||
break;
|
||||
int32_t oftemp = 0;
|
||||
oftemp = 1000000*m5data.o_numbers[0] + 100000*m5data.o_numbers[1] + 10000*m5data.o_numbers[2] + \
|
||||
1000*m5data.o_numbers[3] + 100*m5data.o_numbers[4] + 10*m5data.o_numbers[5] + m5data.o_numbers[6];
|
||||
|
||||
case 2:
|
||||
{
|
||||
oftemp -= 100000;
|
||||
}
|
||||
break;
|
||||
oftemp -= my_power(10, ( 7 - m5data.overflow_flag_low) );
|
||||
|
||||
case 3:
|
||||
{
|
||||
oftemp -= 10000;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
oftemp -= 1000;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
{
|
||||
oftemp -= 100;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
{
|
||||
oftemp -= 10;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//输入值下限限幅
|
||||
if(oftemp <= (pltdata.yreal_pri_low*1000) )
|
||||
{
|
||||
oftemp = pltdata.yreal_pri_low*1000;
|
||||
}
|
||||
|
||||
//仅当发生过溢出或者达到下限的情况下才需要执行以下操作
|
||||
if( (m5data.overflow_flag_low)||(oftemp == pltdata.yreal_pri_low*1000) )
|
||||
{
|
||||
//更新数码管显示
|
||||
set_nixie_cube(IO_OUTPUT, 99, oftemp);
|
||||
|
||||
m5data.o_numbers[0] = (oftemp/1000000 > 9)?(0):(oftemp/1000000);
|
||||
m5data.o_numbers[1] = (oftemp/100000) % 10;
|
||||
m5data.o_numbers[2] = (oftemp/10000) % 10;
|
||||
m5data.o_numbers[3] = (oftemp/1000) % 10;
|
||||
m5data.o_numbers[4] = (oftemp/100) % 10;
|
||||
m5data.o_numbers[5] = (oftemp/10) % 10;
|
||||
m5data.o_numbers[6] = oftemp % 10;
|
||||
}
|
||||
//更新数码管数组
|
||||
set_output_value(oftemp);
|
||||
|
||||
//溢出标志清零
|
||||
m5data.overflow_flag_low = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1762,20 +1785,20 @@ void set_working_mode(SIG_FUNCTIONS mode, SIG_FUNCTIONS_TYPE type)
|
|||
int32_t temp = 0;
|
||||
temp = pltdata.yreal_pri_low*1000;
|
||||
set_nixie_cube(IO_OUTPUT, 99, temp);
|
||||
temp = (temp >= 0)?(temp):(0 - temp);
|
||||
//将实际值转换成6个独立数字,之后在plot_drawing中会对当前输出实际值pltdata.yreal_pri_value进行更新
|
||||
m5data.o_numbers[0] = (temp/1000000 > 9)?(9):(temp/1000000);
|
||||
m5data.o_numbers[1] = (temp/100000) % 10;
|
||||
m5data.o_numbers[2] = (temp/10000) % 10;
|
||||
m5data.o_numbers[3] = (temp/1000) % 10;
|
||||
m5data.o_numbers[4] = (temp/100) % 10;
|
||||
m5data.o_numbers[5] = (temp/10) % 10;
|
||||
m5data.o_numbers[6] = (temp) % 10;
|
||||
set_output_value(temp);
|
||||
if(temp > 0)
|
||||
{
|
||||
set_nixie_cube_sign(IO_OUTPUT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_nixie_cube_sign(IO_OUTPUT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void input_value_show(void)
|
||||
{
|
||||
if( MY_ABS(pltdata.yreal_scd_value , pltdata.yreal_scd_value_prv) < (float32)0.01)
|
||||
if( MY_ABS(pltdata.yreal_scd_value - pltdata.yreal_scd_value_prv) < (float32)0.01)
|
||||
{
|
||||
//变化值过小的情况下不更新显示内容
|
||||
return;
|
||||
|
@ -2699,11 +2722,7 @@ void plot_drawing(void)
|
|||
//输出曲线
|
||||
//{
|
||||
//将独立数字转换成实际值
|
||||
pltdata.yreal_pri_value = m5data.o_numbers[0]*1000 + m5data.o_numbers[1]*100 + 10*m5data.o_numbers[2] + \
|
||||
m5data.o_numbers[3] + m5data.o_numbers[4]*(float32)0.1 + m5data.o_numbers[5]*(float32)0.01 + m5data.o_numbers[6]*(float32)0.001;
|
||||
|
||||
//绘图时只用正值
|
||||
pltdata.yreal_pri_value = (m5data.sign_flag_out == 0)?(pltdata.yreal_pri_value):(0 - pltdata.yreal_pri_value);
|
||||
pltdata.yreal_pri_value = get_output_value();
|
||||
|
||||
//改变之前先记录前一时刻的绘图值
|
||||
pltdata.y_pri_value_prv = pltdata.y_pri_value;
|
||||
|
@ -2712,7 +2731,7 @@ void plot_drawing(void)
|
|||
pltdata.y_pri_value = ( pltdata.y_pri_up - pltdata.y_pri_low ) * \
|
||||
( pltdata.yreal_pri_value - pltdata.yreal_pri_low ) / ( pltdata.yreal_pri_up - pltdata.yreal_pri_low );
|
||||
|
||||
if( MY_ABS(pltdata.y_pri_value, pltdata.y_pri_value_prv) < 1 )
|
||||
if( MY_ABS(pltdata.y_pri_value - pltdata.y_pri_value_prv) < 1 )
|
||||
{
|
||||
//变化幅度小的情况下不更新显示值
|
||||
//等待一段时间后不再更新
|
||||
|
@ -2749,7 +2768,7 @@ void plot_drawing(void)
|
|||
pltdata.y_scd_value = ( pltdata.y_scd_up - pltdata.y_scd_low ) * \
|
||||
( pltdata.yreal_scd_value - pltdata.yreal_scd_low ) / ( pltdata.yreal_scd_up - pltdata.yreal_scd_low );
|
||||
|
||||
if( MY_ABS(pltdata.y_scd_value, pltdata.y_scd_value_prv) < 1 )
|
||||
if( MY_ABS(pltdata.y_scd_value - pltdata.y_scd_value_prv) < 1 )
|
||||
{
|
||||
//变化幅度小的情况下不更新显示值
|
||||
//等待一段时间后不再更新
|
||||
|
@ -2814,6 +2833,38 @@ void scr_setting_recover(void)
|
|||
}
|
||||
}
|
||||
|
||||
//计算a的b次方
|
||||
float32 my_power(int a, int b)
|
||||
{
|
||||
if(a == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(b == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
float32 result = 1;
|
||||
|
||||
if( b > 0 )
|
||||
{
|
||||
for(uint8_t i = 0; i < b; i++)
|
||||
{
|
||||
result *= a;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uint8_t i = 0; i < b; i++)
|
||||
{
|
||||
result /= (float32)a;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void scr_setting_run(void) //详细设置界面
|
||||
{
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue