537 lines
13 KiB
C
537 lines
13 KiB
C
#include "power.h"
|
||
#include "base/utility.h"
|
||
#include "gpio_cfg.h"
|
||
#include "base/delay.h"
|
||
#define PowerCurr_AD_BUF_LEN 40
|
||
#define POWER_SET_COUNT 20
|
||
static volatile CurrentSample_Range_eu latest_range = Current_Max;
|
||
static volatile PowerInfo_st def_power_st;
|
||
//static uint16_t PowerCurr_AD_buf[PowerCurr_AD_BUF_LEN];
|
||
static volatile float f_cur_k;
|
||
static volatile float f_cur_b;
|
||
static volatile uint8_t uc_power_cal_flag = 0;
|
||
volatile PowerInfo_st powerinfo_arrayst[POWER_SET_COUNT] ;
|
||
|
||
|
||
/*
|
||
@brief 获取内部基准1.2V电压对应的AD
|
||
*/
|
||
uint32_t Power_GetBaseVAD()
|
||
{
|
||
// y1 = kx1+b y2=kx2+b y1-y2/x1-x2
|
||
// uint16_t adv_buf[10];
|
||
// uint32_t temp_v;
|
||
// GetADC0_Value(ADC_CHANNEL_17,adv_buf,10) ;
|
||
// Bubble_Sort_u16(adv_buf,10);
|
||
// return (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
|
||
|
||
return (uint32_t)(1.2f/3.3f*4096);
|
||
}
|
||
|
||
void Power_CurCalibration()
|
||
{
|
||
uint16_t adv_buf[10],adv2v5,adv1v25;
|
||
uc_power_cal_flag = 1;
|
||
GetADC1_Value(VCC_2V5_CH,adv_buf,10) ;
|
||
Bubble_Sort_u16(adv_buf,10);
|
||
adv2v5 = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
|
||
|
||
GetADC1_Value(VCC_1V25_CH,adv_buf,10) ;
|
||
Bubble_Sort_u16(adv_buf,10);
|
||
adv1v25 = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
|
||
|
||
f_cur_k = 1.245f/((adv2v5 - adv1v25)+1);
|
||
f_cur_b = 2.49f-f_cur_k*adv2v5;
|
||
|
||
|
||
// GetADC0_Value(VCC_1V25_CH,adv_buf,10) ;
|
||
// Bubble_Sort_u16(adv_buf,10);
|
||
// adv1v25 = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
|
||
//
|
||
// f_cur_k = 1.25f/((adv2v5 - adv1v25)+1);
|
||
// f_cur_b = 2.5f-f_cur_k*adv2v5;
|
||
}
|
||
/*
|
||
@brief 将获取的ADC值转换为电压值
|
||
@param1 ul_adv 采样AD原始值
|
||
@rtv 返回AD采集到的电压值 扩大1000000倍
|
||
*/
|
||
uint32_t Power_ADVGetCalVal_106(uint16_t ul_adv)
|
||
{
|
||
if(uc_power_cal_flag == 0)
|
||
{
|
||
Power_CurCalibration();
|
||
}
|
||
return (uint32_t)((f_cur_k*ul_adv+f_cur_b)*1000000);
|
||
}
|
||
|
||
|
||
/*
|
||
@brief 采样高电平电压
|
||
*/
|
||
uint32_t Power_GetHPowerV()
|
||
{
|
||
uint32_t adv;
|
||
uint16_t adv_buf[10];
|
||
Power_CurCalibration();
|
||
GetADC1_Value(V_LA_H_CH,adv_buf,10) ;
|
||
Bubble_Sort_u16(adv_buf,10);
|
||
adv = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
|
||
adv = Power_ADVGetCalVal_106(adv);
|
||
adv = adv*V_PARAM_1/100000;
|
||
return adv;
|
||
}
|
||
|
||
/*
|
||
@brief 采样总线输出电压
|
||
*/
|
||
uint32_t Power_GetBousV()
|
||
{
|
||
uint32_t abus_v,bbus_v;
|
||
uint16_t adv_buf[10];
|
||
uint32_t hbus_v=0;
|
||
Power_CurCalibration();
|
||
GetADC1_Value(AD_OUTA_CH,adv_buf,10) ;
|
||
Bubble_Sort_u16(adv_buf,10);
|
||
abus_v = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
|
||
|
||
GetADC1_Value(AD_OUTB_CH,adv_buf,10) ;
|
||
Bubble_Sort_u16(adv_buf,10);
|
||
bbus_v = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
|
||
|
||
if(bbus_v > abus_v)
|
||
{
|
||
abus_v = bbus_v;
|
||
}
|
||
|
||
abus_v = Power_ADVGetCalVal_106(abus_v);
|
||
abus_v = abus_v*11/100000;
|
||
|
||
// hbus_v=Power_GetHPowerV();
|
||
|
||
//? 验证电压失调
|
||
// 电压相差过大的时候输出一个离谱的值
|
||
// if((hbus_v>abus_v+10)||(abus_v>hbus_v+10)){
|
||
// abus_v=500;
|
||
// }
|
||
|
||
return abus_v;
|
||
}
|
||
|
||
/*
|
||
@brief 采样中电平电压
|
||
*/
|
||
uint32_t Power_GetMPowerV()
|
||
{
|
||
int32_t adv;
|
||
uint16_t adv_buf[10];
|
||
GetADC1_Value(V_LA_M_CH,adv_buf,10) ;
|
||
Bubble_Sort_u16(adv_buf,10);
|
||
adv = (adv_buf[4]+adv_buf[5]+adv_buf[6]+adv_buf[7])>>2;
|
||
adv = Power_ADVGetCalVal_106(adv);
|
||
adv = adv*V_PARAM_1/100000;
|
||
return adv;
|
||
}
|
||
|
||
/*
|
||
typedef enum{
|
||
R510_0uA_32uA_UC = (uint8_t)0,//x201
|
||
R510_0uA_580uA_MC = (uint8_t)1,//x11
|
||
R100_0uA_160uA_UC = (uint8_t)2,//x201
|
||
R100_0p2mA_3mA_MC = (uint8_t)3,//x11
|
||
R10_0p1mA_1p6mA_UC = (uint8_t)4,//x201
|
||
R10_2mA_30mA_MC = (uint8_t)5,//x11
|
||
Current_Max = (uint8_t)6,
|
||
Current_SampleR_OFF = (uint8_t)9,
|
||
} CurrentSample_Range_eu;
|
||
*/
|
||
/*
|
||
@brief 通过采样adc,换算电流
|
||
@param adv adc 采样值
|
||
@param rang 采样电阻
|
||
@rtv uint32_t 电流值 0.1uA
|
||
*/
|
||
uint32_t Power_ConvCur(uint16_t adv,CurrentSample_Range_eu range)
|
||
{
|
||
uint32_t ul_R,ul_Mut;
|
||
uint32_t ul_adv = Power_ADVGetCalVal_106(adv);
|
||
switch(range)
|
||
{
|
||
case R510_0uA_32uA_UC: ul_R = 510; ul_Mut = 201 ; break;
|
||
case R510_0uA_580uA_MC: ul_R = 510; ul_Mut = 11; break;
|
||
case R100_0uA_160uA_UC: ul_R = 100; ul_Mut = 201; break;
|
||
case R100_0p2mA_3mA_MC: ul_R = 100; ul_Mut = 11; break;
|
||
case R10_0p1mA_1p6mA_UC: ul_R = 10; ul_Mut = 201; break;
|
||
case R10_2mA_30mA_MC: ul_R = 10; ul_Mut = 11; break;
|
||
case Current_Max: ul_R = 10; ul_Mut = 1; break;
|
||
case Current_SampleR_OFF: ul_R = 510; ul_Mut = 1;break;
|
||
default: ul_R = 510; ul_Mut = 1;break;
|
||
}
|
||
ul_adv = (ul_adv*100 / ul_R /ul_Mut+4)/10;
|
||
return ul_adv;
|
||
}
|
||
//根据电流大小的范围,设置采样电阻
|
||
CurrentSample_Range_eu Power_SetSampleCurrentRange(CurrentSample_Range_eu range)
|
||
{
|
||
|
||
switch(range)
|
||
{
|
||
case R510_0uA_32uA_UC: R510_SW_ON; R100_SW_OFF; R10_SW_OFF; break;
|
||
case R510_0uA_580uA_MC: R510_SW_ON; R100_SW_OFF; R10_SW_OFF; break;
|
||
case R100_0uA_160uA_UC: R100_SW_ON; R510_SW_OFF; R10_SW_OFF; break;
|
||
case R100_0p2mA_3mA_MC: R100_SW_ON; R510_SW_OFF; R10_SW_OFF; break;
|
||
case R10_0p1mA_1p6mA_UC: R10_SW_ON; R510_SW_OFF; R100_SW_OFF; break;
|
||
case R10_2mA_30mA_MC: R10_SW_ON; R510_SW_OFF; R100_SW_OFF; break;
|
||
case Current_Max: R510_SW_ON; R100_SW_ON; R10_SW_ON;break;
|
||
case Current_SampleR_OFF: R510_SW_OFF;R100_SW_OFF; R10_SW_OFF;break;
|
||
default: range = Current_Max; R510_SW_ON; R100_SW_ON; R10_SW_ON;break;
|
||
}
|
||
latest_range = range;
|
||
return latest_range;
|
||
}
|
||
|
||
/*
|
||
@brief 设置电阻采样通道和AD采样配置
|
||
*/
|
||
CurrentSample_Range_eu Power_SetSampleRange_Seep(CurrentSample_Range_eu range , uint32_t speed)
|
||
{
|
||
switch(range)
|
||
{
|
||
case R510_0uA_32uA_UC: ADC_CurChnnelSet(AN_UA_CH,speed); break;
|
||
case R510_0uA_580uA_MC: ADC_CurChnnelSet(AN_MAL_CH,speed); break;
|
||
case R100_0uA_160uA_UC: ADC_CurChnnelSet(AN_UA_CH,speed); break;
|
||
case R100_0p2mA_3mA_MC: ADC_CurChnnelSet(AN_MAL_CH,speed); break;
|
||
case R10_0p1mA_1p6mA_UC: ADC_CurChnnelSet(AN_UA_CH,speed); break;
|
||
case R10_2mA_30mA_MC: ADC_CurChnnelSet(AN_MAL_CH,speed); break;
|
||
case Current_Max: ADC_CurChnnelSet(AN_MAL_CH,speed); break;
|
||
case Current_SampleR_OFF: ADC_CurChnnelSet(AN_MAL_CH,speed);break;
|
||
default: ADC_CurChnnelSet(AN_MAL_CH,speed);break;
|
||
}
|
||
return Power_SetSampleCurrentRange(range);
|
||
}
|
||
|
||
|
||
//获取总线电流
|
||
uint32_t Power_GetCurrent(void)
|
||
{
|
||
uint32_t adv;
|
||
uint32_t count;
|
||
CurrentSample_Range_eu range = latest_range;//档位保存
|
||
CurrentSample_Range_eu set_range;
|
||
uint32_t adv_base = Power_GetBaseVAD();
|
||
if(adv_base < 500)
|
||
return 0;
|
||
set_range = Power_SetSampleCurrentRange(R10_2mA_30mA_MC);
|
||
StartADC2Channel(AN_MAL_CH,ADC_SPEED_SLOW);
|
||
delay_us(300);
|
||
GetADC_Fast(ADC_CURR_DE);
|
||
adv = 0;
|
||
for(count = 0; count < 4; count++)
|
||
{
|
||
adv += GetADC_Fast(ADC_CURR_DE);
|
||
}
|
||
adv >>= 2;
|
||
if(adv > 250){
|
||
adv = Power_ConvCur(adv,set_range);//0.1uA
|
||
adv = (adv+4)/10;
|
||
Power_SetSampleCurrentRange(range);
|
||
return adv;
|
||
}
|
||
set_range = Power_SetSampleCurrentRange(R100_0p2mA_3mA_MC);
|
||
StartADC2Channel(AN_MAL_CH,ADC_SPEED_SLOW);
|
||
delay_us(300);
|
||
GetADC_Fast(ADC_CURR_DE);
|
||
adv = 0;
|
||
for(count = 0; count < 4; count++)
|
||
{
|
||
adv += GetADC_Fast(ADC_CURR_DE);
|
||
}
|
||
adv >>= 2;
|
||
if(adv > 250){
|
||
adv = Power_ConvCur(adv,set_range);//0.1uA
|
||
adv = (adv+4)/10;
|
||
Power_SetSampleCurrentRange(range);
|
||
return adv;
|
||
}
|
||
|
||
set_range = Power_SetSampleCurrentRange(R10_0p1mA_1p6mA_UC);
|
||
StartADC2Channel(AN_UA_CH,ADC_SPEED_SLOW);
|
||
delay_ms(2);
|
||
GetADC_Fast(ADC_CURR_DE);
|
||
adv = 0;
|
||
for(count = 0; count < 4; count++)
|
||
{
|
||
adv += GetADC_Fast(ADC_CURR_DE);
|
||
}
|
||
adv >>= 2;
|
||
if(adv > 250){
|
||
adv = Power_ConvCur(adv,set_range);//0.1uA
|
||
adv = (adv+4)/10;
|
||
Power_SetSampleCurrentRange(range);
|
||
return adv;
|
||
}
|
||
set_range = Power_SetSampleCurrentRange(R100_0uA_160uA_UC);
|
||
StartADC2Channel(AN_UA_CH,ADC_SPEED_SLOW);
|
||
delay_ms(3);
|
||
GetADC_Fast(ADC_CURR_DE);
|
||
adv = 0;
|
||
for(count = 0; count < 8; count++)
|
||
{
|
||
adv += GetADC_Fast(ADC_CURR_DE);
|
||
}
|
||
adv >>= 3;
|
||
adv = Power_ConvCur(adv,set_range);//0.1uA
|
||
adv = (adv+4)/10;
|
||
Power_SetSampleCurrentRange(range);
|
||
return adv;
|
||
}
|
||
|
||
/*
|
||
@brief 电源调压准备,计数频率和电压的线性关系
|
||
@rtv 返回值:0 成功 其他失败
|
||
*/
|
||
|
||
uint8_t PowerCalPrapare(void)
|
||
{
|
||
//YM硬件直接由公式计算
|
||
return 0;
|
||
}
|
||
//防止突然上电,导致电源崩溃
|
||
static void PowerUpFilter(uint16_t tag_dac)
|
||
{
|
||
uint16_t us_lastdac_h = DAC_GetDataOutputValue(DAC_Channel_1);
|
||
if(us_lastdac_h > (tag_dac + 200))
|
||
{
|
||
while(us_lastdac_h > tag_dac)
|
||
{
|
||
if((tag_dac + 100) < us_lastdac_h)
|
||
{
|
||
us_lastdac_h -= 50;
|
||
C_H_DAC_Set(us_lastdac_h);
|
||
}else{
|
||
us_lastdac_h = tag_dac;
|
||
C_H_DAC_Set(us_lastdac_h);
|
||
}
|
||
delay_ms(10);
|
||
}
|
||
}
|
||
}
|
||
|
||
//电压调节的关系为线性函数
|
||
void PowerCalibration(PowerInfo_st* info_st)
|
||
{
|
||
|
||
float vlp,vlm,v_adc_h,v_adc_m;
|
||
uint16_t us_basedac_h,us_basedac_m;
|
||
uint16_t us_lastdac_h,us_lastdac_m;
|
||
uint16_t us_powderv;
|
||
uint16_t us_timeout ;
|
||
uint32_t diff=0;
|
||
uint16_t ok_flg = 0;
|
||
uint8_t uc_down_up_flag = 0;
|
||
if(info_st->V_LAH < info_st->V_LAM )
|
||
{
|
||
info_st->V_LAH_DAC = 0;
|
||
info_st->V_LAM_DAC = 0;
|
||
return ;
|
||
}
|
||
PAout(LAVC_M_Pin_Nu)=0;PBout(OUTAH_Pin_Nu)=0;
|
||
PBout(OUTBL_Pin_Nu)=0;PBout(OUTAL_Pin_Nu)=0;
|
||
PCout(POWER_ON_Pin_Nu) = 1;
|
||
vlp = info_st->V_LAH;
|
||
vlp /= 10;
|
||
//(VLP-1.229V)/178K + (VDAC-1.229V)/20K = 0.1229mA
|
||
v_adc_h =( 0.1229- (vlp-1.229)/V_PARAM_2)*20+1.229;
|
||
us_timeout = 80;
|
||
info_st->V_LAH_DAC = 0;
|
||
us_basedac_h = (uint16_t)( v_adc_h/3.3 * 4096);
|
||
PowerUpFilter(us_basedac_h);
|
||
us_lastdac_h = 0;
|
||
//us_basedac_h = 250;
|
||
ok_flg = 0;
|
||
uc_down_up_flag = 0;
|
||
while(us_timeout > 0)
|
||
{
|
||
us_timeout--;
|
||
C_H_DAC_Set(us_basedac_h);
|
||
us_lastdac_h = us_basedac_h;
|
||
switch(uc_down_up_flag)
|
||
{
|
||
case 0:delay_os_ms(100);break;//首次调压
|
||
case 1:delay_os_ms(50);break;//降压
|
||
case 2:delay_os_ms(10);break;//升压
|
||
}
|
||
us_powderv = Power_GetHPowerV();
|
||
diff = us_powderv > info_st->V_LAH?us_powderv-info_st->V_LAH:info_st->V_LAH-us_powderv;
|
||
if(diff < 2)
|
||
{
|
||
ok_flg++;
|
||
if(ok_flg > 2)
|
||
{
|
||
info_st->V_LAH_DAC = us_basedac_h;
|
||
break;
|
||
}else{
|
||
continue;
|
||
}
|
||
|
||
}
|
||
diff = diff *2;
|
||
ok_flg = 0;
|
||
if( us_powderv > info_st->V_LAH)
|
||
{
|
||
us_basedac_h += diff;
|
||
uc_down_up_flag = 1;
|
||
}else{
|
||
us_basedac_h -= diff;
|
||
uc_down_up_flag = 2;
|
||
}
|
||
|
||
|
||
if(us_basedac_h < 20)
|
||
us_basedac_h = 20;
|
||
if(us_basedac_h > 4050)
|
||
us_basedac_h = 4050;
|
||
|
||
}
|
||
if(info_st->V_LAH_DAC == 0)
|
||
return;
|
||
|
||
//(VM-2.5V)/20k+(VDAC-2.5V)/4.7K = 0.25mA
|
||
us_timeout = 100;
|
||
info_st->V_LAM_DAC = 0;
|
||
vlm = info_st->V_LAM ;
|
||
vlm /= 10;
|
||
v_adc_m =( 0.25- (vlm-2.5)/20)*4.7+2.5;
|
||
us_basedac_m = (uint16_t)(v_adc_m / 3.3 * 4096);
|
||
//us_lastdac_m = 250;
|
||
ok_flg = 0;
|
||
uc_down_up_flag = 0;
|
||
while( us_timeout > 0)
|
||
{
|
||
us_timeout--;
|
||
C_M_DAC_Set(us_basedac_m);
|
||
us_lastdac_m = us_basedac_m;
|
||
switch(uc_down_up_flag)
|
||
{
|
||
case 0:delay_os_ms(50);break;//首次调压
|
||
case 1:delay_os_ms(40);break;//降压
|
||
case 2:delay_os_ms(30);break;//升压
|
||
default:delay_os_ms(50);break;
|
||
}
|
||
us_powderv = Power_GetMPowerV();
|
||
diff = us_powderv > info_st->V_LAM?us_powderv-info_st->V_LAM:info_st->V_LAM-us_powderv;
|
||
if(diff < 2)
|
||
{
|
||
ok_flg++;
|
||
if(ok_flg > 2)
|
||
{
|
||
info_st->V_LAM_DAC = us_basedac_m;
|
||
break;
|
||
}
|
||
else{
|
||
continue;
|
||
}
|
||
}
|
||
ok_flg = 0;
|
||
diff = diff *10;
|
||
if( us_powderv > info_st->V_LAM)
|
||
{
|
||
us_basedac_m += diff;
|
||
uc_down_up_flag = 1;
|
||
}else{
|
||
uc_down_up_flag = 2;
|
||
us_basedac_m -= diff;
|
||
}
|
||
if(us_basedac_m < 100)
|
||
us_basedac_m = 100;
|
||
if(us_basedac_m > 4050)
|
||
us_basedac_m = 4050;
|
||
}
|
||
|
||
}
|
||
//设置总线电压
|
||
void PowerSetVoltage(PowerInfo_st* info_st)
|
||
{
|
||
memcpy((void *)&def_power_st,info_st,sizeof(PowerInfo_st));
|
||
PowerUpFilter(info_st->V_LAH_DAC);
|
||
C_H_DAC_Set(info_st->V_LAH_DAC);
|
||
C_M_DAC_Set(info_st->V_LAM_DAC);
|
||
POWER_ON;
|
||
//? 验证电压失调
|
||
// delay_ms(5);
|
||
// C_H_DAC_Set(info_st->V_LAH_DAC);
|
||
// C_M_DAC_Set(info_st->V_LAM_DAC);
|
||
}
|
||
//获取当前电压配置值
|
||
void PowerGetSet(PowerInfo_st* info_st)
|
||
{
|
||
uint16_t h_dac = DAC_GetDataOutputValue(DAC_Channel_1);
|
||
uint16_t m_dac = DAC_GetDataOutputValue(DAC_Channel_2);
|
||
info_st->V_LAH = 0;
|
||
info_st->V_LAH_DAC = h_dac;
|
||
if(h_dac == def_power_st.V_LAH_DAC)
|
||
{
|
||
info_st->V_LAH = def_power_st.V_LAH;
|
||
}
|
||
info_st->V_LAM = 0;
|
||
info_st->V_LAM_DAC = h_dac;
|
||
if(m_dac == def_power_st.V_LAM_DAC)
|
||
{
|
||
info_st->V_LAM_DAC = m_dac;
|
||
}
|
||
}
|
||
/*
|
||
@brief 设置总线电压
|
||
@param h_v/10 设置高电平电压
|
||
@param m_v/10 设置中电平电压
|
||
@rtv 0 执行成功 1 执行失败
|
||
*/
|
||
|
||
uint8_t PowerCalibration_set(uint16_t h_v,uint16_t m_v)
|
||
{
|
||
uint32_t ul_index = 0;
|
||
PowerInfo_st powerinfo_st;
|
||
rt_memset(&powerinfo_st,0,sizeof(PowerInfo_st));
|
||
while(ul_index < POWER_SET_COUNT)
|
||
{
|
||
//if( powerinfo_arrayst[ul_index].V_LAH == h_v && powerinfo_arrayst[ul_index].V_LAM == m_v)
|
||
if( powerinfo_arrayst[ul_index].V_LAH == h_v)
|
||
{
|
||
break;
|
||
}
|
||
ul_index++;
|
||
}
|
||
//在现有电压列表中能够查询到校准后的电压
|
||
if(ul_index < POWER_SET_COUNT)
|
||
{
|
||
memcpy((void *)&powerinfo_st,(void *)&powerinfo_arrayst[ul_index],sizeof(PowerInfo_st));
|
||
PowerSetVoltage(&powerinfo_st);
|
||
return 0;
|
||
}
|
||
|
||
powerinfo_st.V_LAH = h_v;
|
||
powerinfo_st.V_LAM = m_v;
|
||
PowerCalibration(&powerinfo_st);
|
||
if(powerinfo_st.V_LAH_DAC == 0 || powerinfo_st.V_LAM_DAC == 0)
|
||
{
|
||
LED1_Out = 1;
|
||
return 1;
|
||
}
|
||
//校准完成后,设置总线电压
|
||
PowerSetVoltage(&powerinfo_st);
|
||
//查找为使用的配置缓存,将新设置的电压保存
|
||
ul_index = 0;
|
||
while(ul_index < POWER_SET_COUNT)
|
||
{
|
||
if( powerinfo_arrayst[ul_index].V_LAH_DAC == 0 || powerinfo_arrayst[ul_index].V_LAM_DAC == 0)
|
||
{
|
||
memcpy((void *)&powerinfo_arrayst[ul_index],&powerinfo_st,sizeof(PowerInfo_st));
|
||
break;
|
||
}
|
||
ul_index++;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|