/****************************************************************************** �� �� ����Analog_Signal_Conversion.c ����������ģ���ź�ת�����ļ� �� �ߣ����� �� ����V1.0 �� �ڣ�2017.03.25 ******************************************************************************/ #include "Analog_Signal_Conversion.h" #pragma MESSAGE DISABLE C2705 #if ANALOG_KL30_VOLTAGE_DET_ENABLE volatile uint16_t AnalogKL30Voltage; volatile uint8_t AnalogKL30VoltageValid; #endif #if ANALOG_KL15_VOLTAGE_DET_ENABLE volatile uint16_t AnalogKL15Voltage; volatile uint8_t AnalogKL15VoltageValid; #endif #if ANALOG_STANDARD_FUEL_SENSOR_RES_DET_ENABLE volatile uint16_t AnalogFuelSensorRes; volatile uint16_t AnalogFuelSensorResValid; #endif #if ANALOG_STANDARD_COOLING_SENSOR_RES_DET_ENABLE uint16_t AnalogCOOLINGSensorRes; uint16_t AnalogCOOLINGSensorResValid; #endif //----hyq--20180410 ��ѹ #if ANALOG_GAS1_VOLTAGE_DET_ENABLE volatile uint16_t AnalogGAS1Voltage; volatile uint8_t AnalogGAS1VoltageValid; #endif #if ANALOG_GAS2_VOLTAGE_DET_ENABLE volatile uint16_t AnalogGAS2Voltage; volatile uint8_t AnalogGAS2VoltageValid; #endif #if ANALOG_KEY_VOLTAGE_DET_ENABLE volatile uint16_t AnalogKEYSensorVoltage; volatile uint16_t AnalogKEYSensorVoltageValid; #endif AnalogConvCtrlStruct AnalogConv; /****************************************************************************** ��������Analog_Signal_Converter_Init �� �ܣ�ģ���ź�ת����ʼ�� ��ʼ��ADC,����ת�����Ʊ��������ź�ת�� �� ������ ����ֵ���� ******************************************************************************/ void Analog_Signal_Converter_Init(void) { AnalogConv.TotalChCnt = 0; AnalogConv.CurrentCh = 0; ADC_Init(); #if ANALOG_KL30_VOLTAGE_DET_ENABLE ADC_Channel_Enable(ANALOG_KL30_ADC_CH); AnalogKL30Voltage = 0; AnalogKL30VoltageValid = 0; //AnalogKL30Voltage = 13000; //AnalogKL30VoltageValid = 1; AnalogConv.SignalType[AnalogConv.TotalChCnt] = ANALOG_SIG_KL30_VOLTAGE; AnalogConv.ChNumber[AnalogConv.TotalChCnt] = ANALOG_KL30_ADC_CH; AnalogConv.TotalChCnt += 1; #endif #if ANALOG_KL15_VOLTAGE_DET_ENABLE ADC_Channel_Enable(ANALOG_KL15_ADC_CH); AnalogKL15Voltage = 0; AnalogKL15VoltageValid = 0; AnalogConv.SignalType[AnalogConv.TotalChCnt] = ANALOG_SIG_KL15_VOLTAGE; AnalogConv.ChNumber[AnalogConv.TotalChCnt] = ANALOG_KL15_ADC_CH; AnalogConv.TotalChCnt += 1; #endif #if ANALOG_STANDARD_FUEL_SENSOR_RES_DET_ENABLE ADC_Channel_Enable(ANALOG_FUEL_ADC_CH); AnalogFuelSensorRes = 0; AnalogFuelSensorResValid = 0; AnalogConv.SignalType[AnalogConv.TotalChCnt] = ANALOG_SIG_STANDARD_FUEL_SENSOR_RES; AnalogConv.ChNumber[AnalogConv.TotalChCnt] = ANALOG_FUEL_ADC_CH; AnalogConv.TotalChCnt += 1; #endif #if ANALOG_STANDARD_COOLING_SENSOR_RES_DET_ENABLE ADC_Channel_Enable(ANALOG_COOLING_ADC_CH); AnalogCOOLINGSensorRes = 0; AnalogCOOLINGSensorResValid = 0; AnalogConv.SignalType[AnalogConv.TotalChCnt] = ANALOG_SIG_STANDARD_COOLING_SENSOR_RES; AnalogConv.ChNumber[AnalogConv.TotalChCnt] = ANALOG_COOLING_ADC_CH; AnalogConv.TotalChCnt += 1; #endif #if ANALOG_GAS1_VOLTAGE_DET_ENABLE //��ѹ1 ADC_Channel_Enable(ANALOG_GAS1_ADC_CH); AnalogGAS1Voltage = 0; AnalogGAS1VoltageValid = 0; AnalogConv.SignalType[AnalogConv.TotalChCnt] = ANALOG_SIG_GAS1_VOLTAGE; AnalogConv.ChNumber[AnalogConv.TotalChCnt] = ANALOG_GAS1_ADC_CH; AnalogConv.TotalChCnt += 1; #endif #if ANALOG_GAS2_VOLTAGE_DET_ENABLE //��ѹ2 ADC_Channel_Enable(ANALOG_GAS2_ADC_CH); AnalogGAS2Voltage = 0; AnalogGAS2VoltageValid = 0; AnalogConv.SignalType[AnalogConv.TotalChCnt] = ANALOG_SIG_GAS2_VOLTAGE; AnalogConv.ChNumber[AnalogConv.TotalChCnt] = ANALOG_GAS2_ADC_CH; AnalogConv.TotalChCnt += 1; #endif #if ANALOG_KEY_VOLTAGE_DET_ENABLE //���� ADC_Channel_Enable(ANALOG_KEY_ADC_CH); AnalogKEYSensorVoltage = 0; AnalogKEYSensorVoltageValid = 0; AnalogConv.SignalType[AnalogConv.TotalChCnt] = ANALOG_SIG_STANDARD_KEY_SENSOR_RES; AnalogConv.ChNumber[AnalogConv.TotalChCnt] = ANALOG_KEY_ADC_CH; AnalogConv.TotalChCnt += 1; #endif if (AnalogConv.TotalChCnt) { ADC_Start_Conversion(AnalogConv.ChNumber[AnalogConv.CurrentCh]); AnalogConv.Busy = 1; //�ѿ�ʼ����ת�� } else AnalogConv.Busy = 0; //��ת��ͨ�� } /****************************************************************************** ��������Analog_Signal_Conversion_Service �� �ܣ�ģ���ź�ת�������� �� ������ ����ֵ���� ******************************************************************************* ע �⣺�÷���������ÿ2ms������һ�� ******************************************************************************/ uint32_t hyqhyq; void Analog_Signal_Conversion_Service(void) { uint16_t ConvValue; uint8_t Channel; uint32_t ADCVoltage; #if ANALOG_STANDARD_FUEL_SENSOR_RES_DET_ENABLE uint32_t DeltaVoltage; uint32_t ConvRes; #endif #if ANALOG_STANDARD_COOLING_SENSOR_RES_DET_ENABLE uint32_t DeltaCOOLINGVoltage; uint32_t ConvCOOLINGRes; #endif if (AnalogConv.TotalChCnt == 0) return; if (AnalogConv.Busy) //��������ת���� { if (ADC_Get_Conversion_Status() != ADC_CONV_COMPLETE) return; } else //����ת������Ϲ� { ADC_Start_Conversion(AnalogConv.ChNumber[AnalogConv.CurrentCh]); AnalogConv.Busy = 1; //������������ת�� return; } ConvValue = ADC_Get_Conversion_Result(); ADCVoltage = (uint32_t)ConvValue; ADCVoltage *= ADC_VREF; ADCVoltage /= ADC_CONV_VALUE_MAX; Channel = AnalogConv.CurrentCh; AnalogConv.CurrentCh++; if (AnalogConv.CurrentCh >= AnalogConv.TotalChCnt) AnalogConv.CurrentCh = 0; ADC_Start_Conversion(AnalogConv.ChNumber[AnalogConv.CurrentCh]); AnalogConv.Busy = 1; //�ѿ�ʼ����ת�� switch (AnalogConv.SignalType[Channel]) { #if ANALOG_KL30_VOLTAGE_DET_ENABLE case ANALOG_SIG_KL30_VOLTAGE : if(NVM_CONFIG_POWER==1) { ADCVoltage *= (ANALOG_KL30_EQU_CIRCIUT_RE1 + 47); ADCVoltage /= 47; } else { ADCVoltage *= (ANALOG_KL30_EQU_CIRCIUT_RE1 + 100); ADCVoltage /= 100; } ANALOG_KL30_VOLTAGE = (uint16_t)ADCVoltage; #if ANALOG_KL30_VOLTAGE_NEGATIVE_OFFSET if (ANALOG_KL30_VOLTAGE > ANALOG_KL30_VOLTAGE_OFFSET) ANALOG_KL30_VOLTAGE -= ANALOG_KL30_VOLTAGE_OFFSET; else ANALOG_KL30_VOLTAGE = 0; #else if ((65535 - ANALOG_KL30_VOLTAGE > ANALOG_KL30_VOLTAGE_OFFSET)) ANALOG_KL30_VOLTAGE += ANALOG_KL30_VOLTAGE_OFFSET; else ANALOG_KL30_VOLTAGE = 65535; #endif AnalogKL30VoltageValid = 1; break; #endif #if ANALOG_KL15_VOLTAGE_DET_ENABLE case ANALOG_SIG_KL15_VOLTAGE : if(NVM_CONFIG_POWER==1) { ADCVoltage *= (ANALOG_KL15_EQU_CIRCIUT_RE1 + 47); ADCVoltage /= 47; } else { ADCVoltage *= (ANALOG_KL15_EQU_CIRCIUT_RE1 + 100); ADCVoltage /= 100; } ANALOG_KL15_VOLTAGE = (uint16_t)ADCVoltage; #if ANALOG_KL15_VOLTAGE_NEGATIVE_OFFSET if (ANALOG_KL15_VOLTAGE > ANALOG_KL15_VOLTAGE_OFFSET) ANALOG_KL15_VOLTAGE -= ANALOG_KL15_VOLTAGE_OFFSET; else ANALOG_KL15_VOLTAGE = 0; #else if ((65535 - ANALOG_KL15_VOLTAGE > ANALOG_KL15_VOLTAGE_OFFSET)) ANALOG_KL15_VOLTAGE += ANALOG_KL15_VOLTAGE_OFFSET; else ANALOG_KL15_VOLTAGE = 65535; #endif AnalogKL15VoltageValid = 1; break; #endif #if ANALOG_STANDARD_FUEL_SENSOR_RES_DET_ENABLE case ANALOG_SIG_STANDARD_FUEL_SENSOR_RES : if(NVM_CONFIG_POWER==1) { if ((ANALOG_KL15_VOLTAGE <= 16000) ||(ANALOG_KL15_VOLTAGE >= 32000)) { ANALOG_FUEL_SENSOR_RES = 65535; AnalogFuelSensorResValid = 0; } else { if (ADCVoltage >= 2450) //�ѳ���ADC����������ֱ�Ӱ������ֵ���� //2021.2.18��2500��Ϊ2450 { ANALOG_FUEL_SENSOR_RES = 65535; AnalogFuelSensorResValid = 1; } else { ADCVoltage *= 2; hyqhyq = ADCVoltage ; DeltaVoltage = 4900-ADCVoltage; //2021.2.8��5000��Ϊ4900 ConvRes = ADCVoltage * 1000; ConvRes /= DeltaVoltage; if (ConvRes > 65534) ANALOG_FUEL_SENSOR_RES = 65535; else ANALOG_FUEL_SENSOR_RES = (uint16_t)ConvRes; if(ANALOG_FUEL_SENSOR_RES>300) ANALOG_FUEL_SENSOR_RES -= 300; else ANALOG_FUEL_SENSOR_RES = 0; AnalogFuelSensorResValid = 1; } } } else { if ((ANALOG_KL15_VOLTAGE <= 6500) || \ (ANALOG_KL15_VOLTAGE >= 18000)) { ANALOG_FUEL_SENSOR_RES = 0; AnalogFuelSensorResValid = 0; } else { // if (ADCVoltage >= (uint32_t)(ADC_VREF * 0.98)) //�ѳ���ADC����������ֱ�Ӱ������ֵ���� if (ADCVoltage >= (uint32_t)(2500 * 0.98)) //�ѳ���ADC����������ֱ�Ӱ������ֵ���� //2020.02.18����Ϊ2500 { ANALOG_FUEL_SENSOR_RES = 65535; AnalogFuelSensorResValid = 1; } else { ADCVoltage *= (ANALOG_FUEL_EQU_CIRCIUT_RE3 + ANALOG_FUEL_EQU_CIRCIUT_RE4); ADCVoltage /= ANALOG_FUEL_EQU_CIRCIUT_RE4; hyqhyq = ADCVoltage ; if (ANALOG_KL15_VOLTAGE <= ADCVoltage) { ANALOG_FUEL_SENSOR_RES = 65535; AnalogFuelSensorResValid = 0; } else { //DeltaVoltage = (uint32_t)ANALOG_KL15_VOLTAGE; DeltaVoltage = 4900; //2021.2.18��5000��Ϊ4900 DeltaVoltage -= ADCVoltage; ConvRes = ADCVoltage * (ANALOG_FUEL_EQU_CIRCIUT_RE1 * 10); ConvRes /= DeltaVoltage; if (ConvRes > 65534) ANALOG_FUEL_SENSOR_RES = 65535; else ANALOG_FUEL_SENSOR_RES = (uint16_t)ConvRes; #if ANALOG_FUEL_EQU_CIRCIUT_RE2 if (ANALOG_FUEL_SENSOR_RES > (ANALOG_FUEL_EQU_CIRCIUT_RE2 * 10)) ANALOG_FUEL_SENSOR_RES -= (ANALOG_FUEL_EQU_CIRCIUT_RE2 * 10); else ANALOG_FUEL_SENSOR_RES = 0; #endif #if ANALOG_FUEL_RES_OFFSET if (ANALOG_FUEL_SENSOR_RES > ANALOG_FUEL_RES_OFFSET) ANALOG_FUEL_SENSOR_RES += ANALOG_FUEL_RES_OFFSET; else ANALOG_FUEL_SENSOR_RES = 0; #endif AnalogFuelSensorResValid = 1; } } } } break; #endif /**************************************************************************/ #if ANALOG_STANDARD_COOLING_SENSOR_RES_DET_ENABLE case ANALOG_SIG_STANDARD_COOLING_SENSOR_RES : if ((ANALOG_KL15_VOLTAGE <= ANALOG_COOLING_CONV_KL15_VOLTAGE_RANGE_LO) || \ (ANALOG_KL15_VOLTAGE >= ANALOG_COOLING_CONV_KL15_VOLTAGE_RANGE_HI)) { ANALOG_COOLING_SENSOR_RES = 0; AnalogCOOLINGSensorResValid = 0; } else { if (ADCVoltage >= (uint32_t)(ADC_VREF * 0.98)) //�ѳ���ADC����������ֱ�Ӱ������ֵ���� { ANALOG_COOLING_SENSOR_RES = 65535; AnalogCOOLINGSensorResValid = 1; } else { ADCVoltage *= (ANALOG_COOLING_EQU_CIRCIUT_RE3 + ANALOG_COOLING_EQU_CIRCIUT_RE4); ADCVoltage /= ANALOG_COOLING_EQU_CIRCIUT_RE4; if (ANALOG_KL15_VOLTAGE <= ADCVoltage) { ANALOG_COOLING_SENSOR_RES = 0; AnalogCOOLINGSensorResValid = 0; } else { DeltaCOOLINGVoltage = (uint32_t)ANALOG_KL15_VOLTAGE; DeltaCOOLINGVoltage -= ADCVoltage; ConvCOOLINGRes = ADCVoltage * (ANALOG_COOLING_EQU_CIRCIUT_RE1 * 10); ConvCOOLINGRes /= DeltaCOOLINGVoltage; if (ConvCOOLINGRes > 65534) ANALOG_COOLING_SENSOR_RES = 65535; else ANALOG_COOLING_SENSOR_RES = (uint16_t)ConvCOOLINGRes; #if ANALOG_COOLING_EQU_CIRCIUT_RE2 if (ANALOG_COOLING_SENSOR_RES > (ANALOG_COOLING_EQU_CIRCIUT_RE2 * 10)) ANALOG_COOLING_SENSOR_RES -= (ANALOG_COOLING_EQU_CIRCIUT_RE2 * 10); else ANALOG_COOLING_SENSOR_RES = 0; #endif #if ANALOG_COOLING_RES_OFFSET if (ANALOG_COOLING_SENSOR_RES > ANALOG_COOLING_RES_OFFSET) ANALOG_COOLING_SENSOR_RES -= ANALOG_COOLING_RES_OFFSET; else ANALOG_COOLING_SENSOR_RES = 0; #endif AnalogCOOLINGSensorResValid = 1; } } } break; #endif /*********************************��ѹ1**************************************/ #if ANALOG_GAS1_VOLTAGE_DET_ENABLE case ANALOG_SIG_GAS1_VOLTAGE : ADCVoltage *= (ANALOG_GAS1_EQU_CIRCIUT_RE1 + ANALOG_GAS1_EQU_CIRCIUT_RE2); ADCVoltage /= ANALOG_GAS1_EQU_CIRCIUT_RE2; ANALOG_GAS1_VOLTAGE = (uint16_t)ADCVoltage; #if ANALOG_GAS1_VOLTAGE_NEGATIVE_OFFSET if (ANALOG_GAS1_VOLTAGE > ANALOG_GAS1_VOLTAGE_OFFSET) ANALOG_GAS1_VOLTAGE -= ANALOG_GAS1_VOLTAGE_OFFSET; else ANALOG_GAS1_VOLTAGE = 0; #else if ((65535 - ANALOG_GAS1_VOLTAGE > ANALOG_GAS1_VOLTAGE_OFFSET)) ANALOG_GAS1_VOLTAGE += ANALOG_GAS1_VOLTAGE_OFFSET; else ANALOG_GAS1_VOLTAGE = 65535; #endif AnalogGAS1VoltageValid = 1; break; #endif /*********************************��ѹ2**************************************/ #if ANALOG_GAS2_VOLTAGE_DET_ENABLE case ANALOG_SIG_GAS2_VOLTAGE : ADCVoltage *= (ANALOG_GAS2_EQU_CIRCIUT_RE1 + ANALOG_GAS2_EQU_CIRCIUT_RE2); ADCVoltage /= ANALOG_GAS2_EQU_CIRCIUT_RE2; ANALOG_GAS2_VOLTAGE = (uint16_t)ADCVoltage; #if ANALOG_GAS2_VOLTAGE_NEGATIVE_OFFSET if (ANALOG_GAS2_VOLTAGE > ANALOG_GAS2_VOLTAGE_OFFSET) ANALOG_GAS2_VOLTAGE -= ANALOG_GAS2_VOLTAGE_OFFSET; else ANALOG_GAS2_VOLTAGE = 0; #else if ((65535 - ANALOG_GAS2_VOLTAGE > ANALOG_GAS2_VOLTAGE_OFFSET)) ANALOG_GAS2_VOLTAGE += ANALOG_GAS2_VOLTAGE_OFFSET; else ANALOG_GAS2_VOLTAGE = 65535; #endif AnalogGAS2VoltageValid = 1; break; #endif /*******************************����*******************************************/ #if ANALOG_KEY_VOLTAGE_DET_ENABLE case ANALOG_SIG_STANDARD_KEY_SENSOR_RES : if(NVM_CONFIG_POWER==1) { if ((ANALOG_KL15_VOLTAGE <= 16000) || \ (ANALOG_KL15_VOLTAGE >= 32000)) { AnalogKEYSensorVoltage = 0; AnalogKEYSensorVoltageValid = 0; } else { if (ADCVoltage >= (uint32_t)(ADC_VREF * 0.98)) //�ѳ���ADC����������ֱ�Ӱ����ֵ���� { ANALOG_KEY_SENSOR_Vol = 65535; AnalogKEYSensorVoltageValid = 1; } else { ANALOG_KEY_SENSOR_Vol = (uint16_t)ADCVoltage; ANALOG_KEY_SENSOR_Vol_VALID = 1; } } } else { if ((ANALOG_KL15_VOLTAGE <= 6500) || \ (ANALOG_KL15_VOLTAGE >= 18000)) { AnalogKEYSensorVoltage = 0; AnalogKEYSensorVoltageValid = 0; } else { if (ADCVoltage >= (uint32_t)(ADC_VREF * 0.98)) //�ѳ���ADC����������ֱ�Ӱ����ֵ���� { ANALOG_KEY_SENSOR_Vol = 65535; AnalogKEYSensorVoltageValid = 1; } else { ANALOG_KEY_SENSOR_Vol = (uint16_t)ADCVoltage; ANALOG_KEY_SENSOR_Vol_VALID = 1; } } } break; #endif /**************************************************************************/ default : Analog_Signal_Converter_Init(); break; } } /****************************************************************************** ��������Analog_KL30_Voltage_Conversion �� �ܣ�ǿ�ƶ�KL30��ѹ����һ�ε���ת�� �� ������ ����ֵ���� ******************************************************************************/ void Analog_KL30_Voltage_Conversion(void) { #if ANALOG_KL30_VOLTAGE_DET_ENABLE uint16_t ConvValue; uint32_t ADCVoltage; if (AnalogConv.Busy) //����ת�����ڽ����� { while (ADC_Get_Conversion_Status() != ADC_CONV_COMPLETE); AnalogConv.Busy = 0; //����ת������� } ADC_Start_Conversion(ANALOG_KL30_ADC_CH); while (ADC_Get_Conversion_Status() != ADC_CONV_COMPLETE); ConvValue = ADC_Get_Conversion_Result(); ADCVoltage = (uint32_t)ConvValue; ADCVoltage *= ADC_VREF; ADCVoltage /= ADC_CONV_VALUE_MAX; if(NVM_CONFIG_POWER==1) { ADCVoltage *= (ANALOG_KL30_EQU_CIRCIUT_RE1 + 47); ADCVoltage /= 47; } else { ADCVoltage *= (ANALOG_KL30_EQU_CIRCIUT_RE1 + 100); ADCVoltage /= 100; } ANALOG_KL30_VOLTAGE = (uint16_t)ADCVoltage; #if ANALOG_KL30_VOLTAGE_NEGATIVE_OFFSET if (ANALOG_KL30_VOLTAGE > ANALOG_KL30_VOLTAGE_OFFSET) ANALOG_KL30_VOLTAGE -= ANALOG_KL30_VOLTAGE_OFFSET; else ANALOG_KL30_VOLTAGE = 0; #else if ((65535 - ANALOG_KL30_VOLTAGE > ANALOG_KL30_VOLTAGE_OFFSET)) ANALOG_KL30_VOLTAGE += ANALOG_KL30_VOLTAGE_OFFSET; else ANALOG_KL30_VOLTAGE = 65535; #endif AnalogKL30VoltageValid = 1; #endif } /****************************************************************************** ��������Analog_KL15_Voltage_Conversion �� �ܣ�ǿ�ƶ�KL15��ѹ����һ�ε���ת�� �� ������ ����ֵ���� ******************************************************************************/ void Analog_KL15_Voltage_Conversion(void) { #if ANALOG_KL15_VOLTAGE_DET_ENABLE uint16_t ConvValue; uint32_t ADCVoltage; if (AnalogConv.Busy) //����ת�����ڽ����� { while (ADC_Get_Conversion_Status() != ADC_CONV_COMPLETE); AnalogConv.Busy = 0; //����ת������� } ADC_Start_Conversion(ANALOG_KL15_ADC_CH); while (ADC_Get_Conversion_Status() != ADC_CONV_COMPLETE); ConvValue = ADC_Get_Conversion_Result(); ADCVoltage = (uint32_t)ConvValue; ADCVoltage *= ADC_VREF; ADCVoltage /= ADC_CONV_VALUE_MAX; if(NVM_CONFIG_POWER==1) { ADCVoltage *= (ANALOG_KL15_EQU_CIRCIUT_RE1 + 47); ADCVoltage /= 47; } else { ADCVoltage *= (ANALOG_KL15_EQU_CIRCIUT_RE1 + 100); ADCVoltage /= 100; } ANALOG_KL15_VOLTAGE = (uint16_t)ADCVoltage; #if ANALOG_KL15_VOLTAGE_NEGATIVE_OFFSET if (ANALOG_KL15_VOLTAGE > ANALOG_KL15_VOLTAGE_OFFSET) ANALOG_KL15_VOLTAGE -= ANALOG_KL15_VOLTAGE_OFFSET; else ANALOG_KL15_VOLTAGE = 0; #else if ((65535 - ANALOG_KL15_VOLTAGE > ANALOG_KL15_VOLTAGE_OFFSET)) ANALOG_KL15_VOLTAGE += ANALOG_KL15_VOLTAGE_OFFSET; else ANALOG_KL15_VOLTAGE = 65535; #endif AnalogKL15VoltageValid = 1; #endif }