Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
TianYing_ty100
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
TY
TianYing_ty100
Commits
229176e1
Commit
229176e1
authored
Sep 10, 2024
by
李俭双
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
🐞
fix:代码评审问题:更改AD采集表格,重新生成代码
parent
5d5b9970
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
483 additions
and
13 deletions
+483
-13
Analog_Signals.c
Firmware/Source/Component/Analog/Analog_Signals.c
+13
-13
Analog_Signals_TianYing100.xlsm
Firmware/utility/MCU_Cfg/cfg/Analog_Signals_TianYing100.xlsm
+0
-0
Analog_Signals.h
Firmware/utility/MCU_Cfg/inc/Analog_Signals.h
+61
-0
Analog_Signals.c
Firmware/utility/MCU_Cfg/src/Analog_Signals.c
+409
-0
No files found.
Firmware/Source/Component/Analog/Analog_Signals.c
View file @
229176e1
...
...
@@ -15,7 +15,7 @@
#include "Analog_Signals.h"
/* Private typedef ----------------------------------------------------------*/
typedef
struct
typedef
__attribute__
((
aligned
(
4
)))
struct
{
uint8_t
u8Ch
;
uint8_t
u8RefType
;
...
...
@@ -26,7 +26,7 @@ typedef struct
ADC_Circuit_Calc_Func
pfProcFunc
;
}
ADC_Ch_Cfg_st_t
;
typedef
enum
ASigConvStat
typedef
__attribute__
((
aligned
(
4
)))
enum
ASigConvStat
{
ADC_STAT_IDLE
=
0
,
ADC_STAT_INIT
,
...
...
@@ -36,7 +36,7 @@ typedef enum ASigConvStat
ADC_STAT_ERR
,
}
ADC_Stat_en_t
;
typedef
struct
typedef
__attribute__
((
aligned
(
4
)))
struct
{
ADC_Stat_en_t
enStatus
;
uint8_t
u8CurrentCh
;
...
...
@@ -44,7 +44,7 @@ typedef struct
uint8_t
u8Timer
;
}
ADC_Ctrl_st_t
;
typedef
struct
typedef
__attribute__
((
aligned
(
4
)))
struct
{
uint8_t
u8Valid
;
uint8_t
u8Rsvd
;
...
...
@@ -72,20 +72,20 @@ ADC_Ctrl_st_t stADCCtrl;
uint16_t
u16ADCSample
[
ADC_CONV_CH_NUMBER
];
ADC_Data_st_t
stADCData
[
ADC_SIGNAL_CH_NUMBER
];
const
uint8_t
u8ADCChList
[
ADC_CONV_CH_NUMBER
]
=
const
uint8_t
__attribute__
((
aligned
(
4
)))
u8ADCChList
[
ADC_CONV_CH_NUMBER
]
=
{
2U
,
3U
,
7U
,
5U
,
};
const
ADC_Ch_Cfg_st_t
stADCChCfg
[
ADC_SIGNAL_CH_NUMBER
]
=
const
__attribute__
((
aligned
(
4
)))
ADC_Ch_Cfg_st_t
stADCChCfg
[
ADC_SIGNAL_CH_NUMBER
]
=
{
{
0U
,
0U
,
0U
,
0U
,
70
0U
,
1U
,
ADC_Voltage_Calc_Circuit102
,},
{
0U
,
0U
,
0U
,
0U
,
0U
,
1U
,
ADC_Voltage_Calc_Circuit102
,},
{
1U
,
0U
,
0U
,
0U
,
0U
,
1U
,
ADC_Voltage_Calc_Circuit102
,},
{
2U
,
0U
,
0U
,
0U
,
0U
,
1U
,
ADC_Voltage_Calc_Circuit101
,},
{
3U
,
2U
,
0U
,
2U
,
18
U
,
1U
,
ADC_Res_Calc_Circuit101
,},
{
3U
,
2U
,
0U
,
2U
,
0
U
,
1U
,
ADC_Res_Calc_Circuit101
,},
};
const
ADC_Res_List_st_t
stADCResList
[
ADC_SIGNAL_CH_NUMBER
]
=
const
__attribute__
((
aligned
(
4
)))
ADC_Res_List_st_t
stADCResList
[
ADC_SIGNAL_CH_NUMBER
]
=
{
{
3300000U
,
1000000U
,
0U
,
0U
,},
{
3300000U
,
1000000U
,
0U
,
0U
,},
...
...
@@ -115,10 +115,10 @@ void Analog_Signal_Conv_Init(void)
}
}
RTE_ADC_Init
(
0
,
2
);
RTE_ADC_Init
(
0
,
3
);
RTE_ADC_Init
(
0
,
5
);
RTE_ADC_Init
(
0
,
7
);
for
(
i
=
0U
;
i
<
ADC_CONV_CH_NUMBER
;
i
++
)
{
RTE_ADC_Init
(
0
,
u8ADCChList
[
i
]
);
}
for
(
i
=
0U
;
i
<
ADC_SIGNAL_CH_NUMBER
;
i
++
)
{
...
...
Firmware/utility/MCU_Cfg/cfg/Analog_Signals_TianYing
2
00.xlsm
→
Firmware/utility/MCU_Cfg/cfg/Analog_Signals_TianYing
1
00.xlsm
View file @
229176e1
No preview for this file type
Firmware/utility/MCU_Cfg/inc/Analog_Signals.h
0 → 100644
View file @
229176e1
/**************************************************************************//**
* \file Analog_Signals.h
* \brief Analog signal processing
* \attention
*
* This file is automatically generated by analog signals configuration tool.
* Date : 2024/9/10 15:16:25
* Cfg Tool Ver : 1.1.0
* Engineer :
* (c) Heilongjiang TYW electronics co., LTD
*
******************************************************************************/
#ifndef ANALOG_SIGNALS_H__
#define ANALOG_SIGNALS_H__
/* Includes -----------------------------------------------------------------*/
#include "ADC.h"
#include "Analog_Circuits.h"
#include "RTE.h"
/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern
{
#endif
/*! @{ */
/* Exported types ------------------------------------------------------------*/
enum
ADCChName
{
ADC_CH_KL30_VOLTAGE
=
0
,
ADC_CH_KL15_VOLTAGE
,
ADC_CH_FUEL_VREF
,
ADC_CH_FUEL1
,
};
/* Exported macro ------------------------------------------------------------*/
#define ADC_TOTAL_CH_NUMBER (4U)
#define ADC_SIGNAL_CH_NUMBER (4U)
#define ADC_REF_VOLTAGE u16ADCRefVoltage
/* Exported variables --------------------------------------------------------*/
extern
volatile
uint16_t
u16ADCRefVoltage
;
extern
const
uint8_t
u8ADCChList
[];
/* Exported functions --------------------------------------------------------*/
extern
void
Analog_Signal_Conv_Init
(
void
);
extern
void
Analog_Signal_Conv_Stop
(
void
);
extern
void
Analog_Signal_Conv_Service
(
void
);
extern
uint16_t
ADC_Read_Signal
(
uint8_t
u8ADCCh
);
extern
uint8_t
ADC_Read_Signal_Valid
(
uint8_t
u8ADCCh
);
extern
uint16_t
ADC_Conv_Single_Channel
(
uint8_t
u8ADCCh
);
/*! @} */
#ifdef __cplusplus
}
#endif
#endif
/* ANALOG_SIGNALS_H__ */
Firmware/utility/MCU_Cfg/src/Analog_Signals.c
0 → 100644
View file @
229176e1
/**************************************************************************//**
* \file Analog_Signals.c
* \brief Analog signal processing
* \attention
*
* This file is automatically generated by analog signals configuration tool.
* Date : 2024/9/10 15:16:25
* Cfg Tool Ver : 1.1.0
* Engineer :
* (c) Heilongjiang TYW electronics co., LTD
*
******************************************************************************/
/* Includes -----------------------------------------------------------------*/
#include "Analog_Signals.h"
/* Private typedef ----------------------------------------------------------*/
typedef
struct
__attribute__
((
aligned
(
4
)))
{
uint8_t
u8Ch
;
uint8_t
u8RefType
;
uint8_t
u8CalMode
;
uint16_t
u16Reference
;
uint16_t
u16CalData
;
uint16_t
u16Resolution
;
ADC_Circuit_Calc_Func
pfProcFunc
;
}
ADC_Ch_Cfg_st_t
;
typedef
__attribute__
((
aligned
(
4
)))
enum
ASigConvStat
{
ADC_STAT_IDLE
=
0
,
ADC_STAT_INIT
,
ADC_STAT_WAIT
,
ADC_STAT_CONV
,
ADC_STAT_PROC
,
ADC_STAT_ERR
,
}
ADC_Stat_en_t
;
typedef
struct
__attribute__
((
aligned
(
4
)))
{
ADC_Stat_en_t
enStatus
;
uint8_t
u8CurrentCh
;
uint8_t
u8DebounceCnt
;
uint8_t
u8Timer
;
}
ADC_Ctrl_st_t
;
typedef
struct
__attribute__
((
aligned
(
4
)))
{
uint8_t
u8Valid
;
uint8_t
u8Rsvd
;
uint16_t
u16Value
;
}
ADC_Data_st_t
;
/* Private macro -------------------------------------------------------------*/
#define ADC_DEFAULT_REF_VOLTAGE (5000U)
#define ADC_CONV_CH_NUMBER (ADC_TOTAL_CH_NUMBER)
#define ADC_SAMPLE_INTERVAL (2U)
#define ADC_MAX_SAMPLE_WAIT (10U)
#define ADC_PWR_UP_DEBOUNCE (10U)
#define ADC_CONV_WAIT (50000U)
#define ADC_REF_TYPE_V_NONE (0x00U)
#define ADC_REF_TYPE_V_VREF (0x01U)
#define ADC_REF_TYPE_V_CH (0x02U)
#define ADC_REF_TYPE_V_FIXED (0x03U)
#define ADC_REF_TYPE_I_FIXED (0x13U)
/* Private variables --------------------------------------------------------*/
volatile
uint16_t
u16ADCRefVoltage
;
ADC_Ctrl_st_t
stADCCtrl
;
uint16_t
u16ADCSample
[
ADC_CONV_CH_NUMBER
];
ADC_Data_st_t
stADCData
[
ADC_SIGNAL_CH_NUMBER
];
const
uint8_t
__attribute__
((
aligned
(
4
)))
u8ADCChList
[
ADC_CONV_CH_NUMBER
]
=
{
2U
,
3U
,
7U
,
5U
,
};
const
__attribute__
((
aligned
(
4
)))
ADC_Ch_Cfg_st_t
stADCChCfg
[
ADC_SIGNAL_CH_NUMBER
]
=
{
{
0U
,
0U
,
0U
,
0U
,
0U
,
1U
,
ADC_Voltage_Calc_Circuit102
,},
{
1U
,
0U
,
0U
,
0U
,
0U
,
1U
,
ADC_Voltage_Calc_Circuit102
,},
{
2U
,
0U
,
0U
,
0U
,
0U
,
1U
,
ADC_Voltage_Calc_Circuit101
,},
{
3U
,
2U
,
0U
,
2U
,
0U
,
1U
,
ADC_Res_Calc_Circuit101
,},
};
const
__attribute__
((
aligned
(
4
)))
ADC_Res_List_st_t
stADCResList
[
ADC_SIGNAL_CH_NUMBER
]
=
{
{
3300000U
,
1000000U
,
0U
,
0U
,},
{
3300000U
,
1000000U
,
0U
,
0U
,},
{
0U
,
0U
,
0U
,
0U
,},
{
0U
,
0U
,
2000U
,
300U
,},
};
/* Private function prototypes ----------------------------------------------*/
/* Private functions --------------------------------------------------------*/
void
Analog_Signal_Conv_Init
(
void
)
{
uint8_t
i
;
uint32_t
u32Timer_Init
=
0
;
while
(
RTE_ADC_Get_Conversion_Status
())
{
u32Timer_Init
++
;
if
(
u32Timer_Init
<
ADC_CONV_WAIT
)
{
RTE_ADC_Stop_Conversion
();
}
else
{
u32Timer_Init
=
0
;
break
;
}
}
for
(
i
=
0U
;
i
<
ADC_CONV_CH_NUMBER
;
i
++
)
{
RTE_ADC_Init
(
0
,
u8ADCChList
[
i
]);
}
for
(
i
=
0U
;
i
<
ADC_SIGNAL_CH_NUMBER
;
i
++
)
{
stADCData
[
i
].
u8Valid
=
0U
;
stADCData
[
i
].
u16Value
=
0U
;
}
stADCCtrl
.
enStatus
=
ADC_STAT_INIT
;
stADCCtrl
.
u8CurrentCh
=
0U
;
stADCCtrl
.
u8DebounceCnt
=
ADC_PWR_UP_DEBOUNCE
/
ADC_SAMPLE_INTERVAL
;
stADCCtrl
.
u8Timer
=
0U
;
u16ADCRefVoltage
=
ADC_DEFAULT_REF_VOLTAGE
;
}
void
Analog_Signal_Conv_Stop
(
void
)
{
uint8_t
i
;
RTE_ADC_DeInit
();
for
(
i
=
0U
;
i
<
ADC_SIGNAL_CH_NUMBER
;
i
++
)
{
stADCData
[
i
].
u8Valid
=
0U
;
}
stADCCtrl
.
enStatus
=
ADC_STAT_IDLE
;
stADCCtrl
.
u8DebounceCnt
=
ADC_PWR_UP_DEBOUNCE
/
ADC_SAMPLE_INTERVAL
;
u16ADCRefVoltage
=
ADC_DEFAULT_REF_VOLTAGE
;
}
void
Analog_Signal_Conv_Service
(
void
)
{
uint8_t
u8Valid
;
uint16_t
u16Voltage
;
uint16_t
u16Reference
;
uint16_t
u16Result
;
switch
(
stADCCtrl
.
enStatus
)
{
case
ADC_STAT_IDLE
:
break
;
case
ADC_STAT_INIT
:
RTE_ADC_Start_Conversion
();
stADCCtrl
.
u8Timer
=
0U
;
stADCCtrl
.
u8CurrentCh
=
0U
;
if
(
stADCCtrl
.
u8DebounceCnt
==
0U
)
{
stADCCtrl
.
enStatus
=
ADC_STAT_CONV
;
}
else
{
stADCCtrl
.
enStatus
=
ADC_STAT_WAIT
;
}
break
;
case
ADC_STAT_WAIT
:
if
(
stADCCtrl
.
u8DebounceCnt
)
{
stADCCtrl
.
u8DebounceCnt
--
;
}
if
(
RTE_ADC_Get_Conversion_Status
()
==
0U
)
{
RTE_ADC_Start_Conversion
();
stADCCtrl
.
u8Timer
=
0U
;
if
(
stADCCtrl
.
u8DebounceCnt
==
0U
)
{
stADCCtrl
.
enStatus
=
ADC_STAT_CONV
;
}
}
else
{
stADCCtrl
.
u8Timer
++
;
if
(
stADCCtrl
.
u8Timer
>=
ADC_MAX_SAMPLE_WAIT
/
ADC_SAMPLE_INTERVAL
)
{
stADCCtrl
.
enStatus
=
ADC_STAT_ERR
;
RTE_ADC_Stop_Conversion
();
}
}
break
;
case
ADC_STAT_CONV
:
if
(
RTE_ADC_Get_Conversion_Status
()
==
0U
)
{
RTE_ADC_Get_Conversion_Result
(
u16ADCSample
,
ADC_CONV_CH_NUMBER
);
stADCCtrl
.
u8Timer
=
0U
;
stADCCtrl
.
u8CurrentCh
=
0U
;
u16ADCRefVoltage
=
ADC_DEFAULT_REF_VOLTAGE
;
stADCCtrl
.
enStatus
=
ADC_STAT_PROC
;
}
else
{
stADCCtrl
.
u8Timer
++
;
if
(
stADCCtrl
.
u8Timer
>=
ADC_MAX_SAMPLE_WAIT
/
ADC_SAMPLE_INTERVAL
)
{
stADCCtrl
.
enStatus
=
ADC_STAT_ERR
;
RTE_ADC_Stop_Conversion
();
}
}
break
;
case
ADC_STAT_PROC
:
u16Voltage
=
ADC_Input_Voltage_Calc
(
u16ADCSample
[
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u8Ch
],
ADC_RESOLUTION
,
u16ADCRefVoltage
);
u8Valid
=
1U
;
if
(
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u8RefType
==
ADC_REF_TYPE_V_NONE
)
{
u16Reference
=
0U
;
}
else
if
(
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u8RefType
==
ADC_REF_TYPE_V_VREF
)
{
u16Reference
=
u16ADCRefVoltage
;
}
else
if
(
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u8RefType
==
ADC_REF_TYPE_V_CH
)
{
u16Reference
=
ADC_Read_Signal
((
uint8_t
)
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u16Reference
);
u8Valid
=
ADC_Read_Signal_Valid
((
uint8_t
)
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u16Reference
);
}
else
if
((
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u8RefType
==
ADC_REF_TYPE_V_FIXED
)
||
\
(
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u8RefType
==
ADC_REF_TYPE_I_FIXED
))
{
u16Reference
=
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u16Reference
;
}
else
{
u8Valid
=
0U
;
}
if
(
u8Valid
)
{
u16Result
=
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
pfProcFunc
(
u16Voltage
,
u16Reference
,
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u16Resolution
,
&
stADCResList
[
stADCCtrl
.
u8CurrentCh
]);
u16Result
=
ADC_Data_Calibrate
(
u16Result
,
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u8CalMode
,
stADCChCfg
[
stADCCtrl
.
u8CurrentCh
].
u16CalData
);
stADCData
[
stADCCtrl
.
u8CurrentCh
].
u16Value
=
u16Result
;
stADCData
[
stADCCtrl
.
u8CurrentCh
].
u8Valid
=
1U
;
}
else
{
stADCData
[
stADCCtrl
.
u8CurrentCh
].
u16Value
=
0U
;
stADCData
[
stADCCtrl
.
u8CurrentCh
].
u8Valid
=
0U
;
}
stADCCtrl
.
u8CurrentCh
++
;
if
(
stADCCtrl
.
u8CurrentCh
>=
ADC_SIGNAL_CH_NUMBER
)
{
RTE_ADC_Start_Conversion
();
stADCCtrl
.
u8CurrentCh
=
0U
;
stADCCtrl
.
enStatus
=
ADC_STAT_CONV
;
}
break
;
case
ADC_STAT_ERR
:
if
(
RTE_ADC_Get_Conversion_Status
()
==
0U
)
{
stADCCtrl
.
enStatus
=
ADC_STAT_INIT
;
}
else
{
RTE_ADC_Stop_Conversion
();
}
break
;
default
:
Analog_Signal_Conv_Init
();
break
;
}
}
uint16_t
ADC_Read_Signal
(
uint8_t
u8ADCCh
)
{
uint16_t
u16Value
;
if
(
u8ADCCh
<
ADC_SIGNAL_CH_NUMBER
)
{
u16Value
=
stADCData
[
u8ADCCh
].
u16Value
;
}
else
{
u16Value
=
0U
;
}
return
u16Value
;
}
uint8_t
ADC_Read_Signal_Valid
(
uint8_t
u8ADCCh
)
{
uint8_t
u8Valid
;
if
(
u8ADCCh
<
ADC_SIGNAL_CH_NUMBER
)
{
u8Valid
=
stADCData
[
u8ADCCh
].
u8Valid
;
}
else
{
u8Valid
=
0U
;
}
return
u8Valid
;
}
uint16_t
ADC_Conv_Single_Channel
(
uint8_t
u8ADCCh
)
{
uint8_t
u8RefCh
;
uint8_t
u8Valid
;
uint8_t
u8ConvResult
;
uint16_t
u16Voltage
;
uint16_t
u16Reference
;
uint16_t
u16Result
;
uint32_t
u32Timer
;
u16Result
=
0U
;
if
(
u8ADCCh
<
ADC_SIGNAL_CH_NUMBER
)
{
if
(
RTE_ADC_Get_Conversion_Status
()
==
0U
)
{
RTE_ADC_Start_Conversion
();
}
u32Timer
=
0U
;
do
{
u32Timer
++
;
u8ConvResult
=
RTE_ADC_Get_Conversion_Status
();
}
while
((
u8ConvResult
!=
0U
)
&&
(
u32Timer
<
ADC_CONV_WAIT
));
if
(
u8ConvResult
==
0U
)
{
RTE_ADC_Get_Conversion_Result
(
u16ADCSample
,
ADC_CONV_CH_NUMBER
);
u16ADCRefVoltage
=
ADC_DEFAULT_REF_VOLTAGE
;
u16Voltage
=
ADC_Input_Voltage_Calc
(
u16ADCSample
[
stADCChCfg
[
u8ADCCh
].
u8Ch
],
ADC_RESOLUTION
,
u16ADCRefVoltage
);
u8Valid
=
1U
;
if
(
stADCChCfg
[
u8ADCCh
].
u8RefType
==
ADC_REF_TYPE_V_NONE
)
{
u16Reference
=
0U
;
}
else
if
(
stADCChCfg
[
u8ADCCh
].
u8RefType
==
ADC_REF_TYPE_V_VREF
)
{
u16Reference
=
u16ADCRefVoltage
;
}
else
if
(
stADCChCfg
[
u8ADCCh
].
u8RefType
==
ADC_REF_TYPE_V_CH
)
{
u8RefCh
=
(
uint8_t
)
stADCChCfg
[
u8ADCCh
].
u16Reference
;
u16Reference
=
ADC_Input_Voltage_Calc
(
u16ADCSample
[
stADCChCfg
[
u8RefCh
].
u8Ch
],
ADC_RESOLUTION
,
u16ADCRefVoltage
);
u16Reference
=
stADCChCfg
[
u8RefCh
].
pfProcFunc
(
u16Reference
,
0U
,
stADCChCfg
[
u8RefCh
].
u16Resolution
,
&
stADCResList
[
u8RefCh
]);
u16Reference
=
ADC_Data_Calibrate
(
u16Reference
,
stADCChCfg
[
u8RefCh
].
u8CalMode
,
stADCChCfg
[
u8RefCh
].
u16CalData
);
}
else
if
((
stADCChCfg
[
u8ADCCh
].
u8RefType
==
ADC_REF_TYPE_V_FIXED
)
||
\
(
stADCChCfg
[
u8ADCCh
].
u8RefType
==
ADC_REF_TYPE_I_FIXED
))
{
u16Reference
=
stADCChCfg
[
u8ADCCh
].
u16Reference
;
}
else
{
u8Valid
=
0U
;
}
if
(
u8Valid
)
{
u16Result
=
stADCChCfg
[
u8ADCCh
].
pfProcFunc
(
u16Voltage
,
u16Reference
,
stADCChCfg
[
u8ADCCh
].
u16Resolution
,
&
stADCResList
[
u8ADCCh
]);
u16Result
=
ADC_Data_Calibrate
(
u16Result
,
stADCChCfg
[
u8ADCCh
].
u8CalMode
,
stADCChCfg
[
u8ADCCh
].
u16CalData
);
}
}
}
return
u16Result
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment