-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtwc.h
375 lines (329 loc) · 11.9 KB
/
twc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
/*
twc : Trace Width Calculator.
Copyright (C) 2024 Yiannis Michael (ymich9963)
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <float.h>
#include <time.h>
/* Constants */
#define k_INT 0.024f
#define k_EXT 0.048f
#define VAL_MAX 999999999.999999999f
#define VAL_MIN 0.0f
#define STD_NAME_LEN 8
#define OUT_FILE_LEN 30
#define DEST_LEN 100
#define PATH_LEN DEST_LEN - OUT_FILE_LEN
#define WELCOME_STR "\nTrace Width Calculator, Made by Yiannis Michael (2024). \n\nPlease 'type twc.exe <Current [A]> <Copper Weight [oz/ft^2]>' to get output results. Use '--help' for explanation of the flags and more advanced usage, for different units, optional inputs, etc.\n\nThis tool should only be used to assist design decisions and not be used to replace professional advice. Developer(s) have no liability whatsoever.\n\n" "This program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n"
#define FEW_ARGS_STR "\nAn input of at least Current [A] and Copper Weight [oz/ft^2] is required. Use no arguments to get the welcome message and either '-h' or '--help' to get the list of commands.\n"
#define VERSION_STR "\nTrace Width Calculator (TWC)\nVersion 1.0.6\n"
#define DISCLAIMER_STR "\nDesign assistance by the TWC tool is provided with no liability whatsover. For final decisions on electronics designs, please consult an actual qualified person.\n"
/* Conversion macros */
#define CONV_MIL2_TO_CM2(x) ((x) * 0.00254 * 0.00254)
#define CONV_MIL2_TO_MM2(x) ((x) * 0.0254 * 0.0254)
#define CONV_MM2_TO_MIL2(x) ((x) / 0.0254 / 0.0254)
#define CONV_CM2_TO_INCH2(x) ((x) / (2.54 * 2.54))
#define CONV_MIL_TO_OZFT2(x) ((x) / 1.378) // most sources say 1.37, few others say 1.378.
#define CONV_MM_TO_OZFT2(x) ((x) * 39.37007874 / 1.378)
#define CONV_UM_TO_OZFT2(x) ((x) * 39.37007874 / 1.378 * 1e-3)
#define CONV_OZFT2_TO_MIL(x) ((x) * 1.378)
#define CONV_OZFT2_TO_MM(x) ((x) * 1.378 * 0.0254)
#define CONV_OZFT2_TO_UM(x) ((x) * 1.378 * 0.0254 * 1e3)
#define CONV_MM_TO_MIL(x) ((x) * 39.37007874)
#define CONV_MIL_TO_MM(x) ((x) * 0.0254)
#define CONV_FAHR_TO_CELS(x) (((x) - 32) / 1.8)
#define CONV_CELS_TO_FAHR(x) (((x) * 1.8) + 32)
#define CONV_WmK_TO_BTUhftF(x) ((x) / 1.730735)
#define CONV_BTUhftF_TO_WmK(x) ((x) * 1.730735)
/* Check macros */
/* Check response from sscanf */
#define CHECK_RES(x) ({ if (!(x)) { \
fprintf(stderr, "Argument entered was wrong...\n"); \
return 1; \
} \
})
/* Check if value is between numerical limits */
#define CHECK_LIMITS(x) ({ if ((x) > VAL_MAX || (x) < VAL_MIN) { \
fprintf(stderr, "Detected numbers out of range. Please check inputs and enter numbers between, \n%.15lf and %.15lf", VAL_MIN, VAL_MAX); \
return 1; \
} \
})
/* Check if an error occured to exit program */
#define CHECK_ERR(x) ({ if ((x)) { \
exit(EXIT_FAILURE); \
} \
})
/* Check if a function returns failure */
#define CHECK_RET(x) ({ if ((x)) { \
return 1; \
} \
})
typedef struct Dbl {
double val;
double outval;
char* units;
} dbl_t; /* Struct for inputs of type double */
typedef struct Std {
char str[STD_NAME_LEN];
uint16_t num;
} std_t; /* Struct for the standards */
typedef struct Layer {
dbl_t trace_width; // [mils]
dbl_t resistance; // [Ohms]
dbl_t voltage_drop; // [V]
dbl_t power_loss; // [W]
dbl_t trace_temperature; // [Celsius]
dbl_t cs_area; // [mils^2]
dbl_t corr_cs_area; // [mils^2]
dbl_t corr_trace_width; // [mils]
} layer_t; /* Outputs Structures */
typedef layer_t extl_t;
typedef layer_t intl_t;
typedef struct OFile {
char fname[OUT_FILE_LEN];
char path[PATH_LEN - OUT_FILE_LEN];
char dest[PATH_LEN];
uint8_t oflag; // Output file flag
} ofile_t; /* Output file strcture */
typedef struct OP {
intl_t intl;
extl_t extl;
layer_t layer;
} op_t; /* Output layer struct */
typedef struct CF {
double copper_weight;
double pcb_thickness;
double plane_area;
double plane_distance;
double temperature_rise;
double pcb_thermal_cond;
} cf_t; /* Correction Factors Struct */
typedef struct IP ip_t;
/* Input Structure */
typedef struct IP {
/* Mandatory Inputs */
dbl_t current; // [A]
dbl_t copper_weight; // [oz/ft^2]
/* Optional Inputs */
std_t standard; // IPC standard
char method; // Method to use for calculations
dbl_t temperature_rise; // [Celsius]
dbl_t temperature_ambient; // [Celsius]
dbl_t trace_length; // [cm]
dbl_t resistivity; // [Ohm*cm]
dbl_t pcb_thickness; // [mm]
dbl_t pcb_thermal_cond; // [W/mK]
dbl_t plane_area; // [in^2]
dbl_t plane_distance; // [mils]
dbl_t a; // [1/C] :resistivity temperature coefficient
cf_t cf; // Correction Factors
ofile_t ofile; // Output file properties
char uflag; // Units flag
void (*defv)(ip_t*); // Set default values
void (*proc)(ip_t*, op_t*); // Calculation procedure
int (*outp)(ip_t*, op_t*, FILE* file); // Output function
int (*outu)(ip_t*, op_t*); // Set output units
} ip_t;
enum {
IPC2152 = 2152,
IPC2221 = 2221,
}; /* Standards Enumeration */
/**
* @brief Get the options and arguments provided.
*
* @param argc Argument count.
* @param argv Argument vector.
* @param ip Input struct to store the inputs.
*
* @return Success or failure.
*/
int get_options(int* argc, char** argv, ip_t* ip);
/**
* @brief Calculate using the IPC2221 standard, sourced from http://circuitcalculator.com/wordpress/2006/03/12/pcb-via-calculator/.
*
* @param ip Input struct to store the inputs.
* @param op Output struct to store the outputs.
*/
void calcs_IPC2221(ip_t* ip, op_t* op);
/**
* @brief Calculate using the IPC2152 standard, Method A which is sourced from https://www.smps.us/pcb-calculator.html.
*
* @param ip Input struct to store the inputs.
* @param op Output struct to store the outputs.
*/
void calcs_IPC2152_A(ip_t* ip, op_t* op);
/**
* @brief Calculate using the IPC2152 standard, Method B which is sourced from https://ninjacalc.mbedded.ninja/calculators/electronics/pcb-design/track-current-ipc2152.
*
* @param ip Input struct to store the inputs.
* @param op Output struct to store the outputs.
*/
void calcs_IPC2152_B(ip_t* ip, op_t* op);
/**
* @brief Set default values needed for the IPC2221 calculations.
*
* @param ip Input struct to store the inputs.
*/
void set_defv_IPC2221(ip_t* ip);
/**
* @brief Set default values needed for the IPC2152, Method A calculations.
*
* @param ip Input struct to store the inputs.
*/
void set_defv_IPC2152_A(ip_t* ip);
/**
* @brief Set default values needed for the IPC2152, Method B calculations.
*
* @param ip Input struct to store the inputs.
*/
void set_defv_IPC2152_B(ip_t* ip);
/**
* @brief Set the units for the IPC2221 outputs.
*
* @param ip Input struct to store the inputs.
* @param op Output struct to store the outputs.
*
* @return Success or failure.
*/
int set_outu_IPC2221(ip_t* ip, op_t* op);
/**
* @brief Set the units for the IPC2152 outputs.
*
* @param ip Input struct to store the inputs.
* @param op Output struct to store the outputs.
*
* @return Success or failure.
*/
int set_outu_IPC2152(ip_t* ip, op_t* op);
/**
* @brief Get the chosen standard and method from the input options. Called before get_options() so that the correct default variables are set.
*
* @param argc Argument count.
* @param argv Argument vector.
* @param ip Input struct to store the inputs.
*
* @return Success or failure.
*/
int get_standard_method(int* argc, char** argv, ip_t* ip);
/**
* @brief Used to check the inputted standard option string, with the array containing the names of the standards. Index is used to set the standard numerical representation.
*
* @param strval String value to compare to the array containing the standard names.
* @param standard_arr Array containing the standard names.
* @param size Size of the array.
* @param index Index when the string value matches an entry in the array.
*
* @return Success or failure.
*/
int check_standard(char* strval, const char** standard_arr, const unsigned int size, unsigned char* index);
/**
* @brief Used to check the inputted method agains an array containing the existing method codes/characters. No need to use the index since it's just characters.
*
* @param chrval Inputted character argumen.
* @param method_arr Array containing the method characters.
* @param size Size of the array.
*
* @return Success or failure.
*/
int check_method(char chrval, const char* method_arr, unsigned int size);
/**
* @brief Set the default, process, output unit, and output print set functions based on the standard and the method chosen.
*
* @param ip Input struct to check the method and the standard.
*
* @return Success or failure.
*/
int sel_functions(ip_t* ip);
/**
* @brief Set the path and file for the outputs to be saved in.
*
* @param ofile Output file struct containing everything necessary to save the file.
* @param optarg Input used by the option.
*/
void set_output_file(ofile_t* ofile, char* optarg);
/**
* @brief Auto-generate the file name using the current date and time. Concatinate the strings together to form the full name.
*
* @param fname File name to use in the concatination.
*/
void autogen_file_name(char* fname);
/**
* @brief Get the date in time as a string.
*
* @return String of the date and time joined together.
*/
char* get_time();
/**
* @brief Calculate Resistance, Voltage drop, and Power loss.
*
* @param ip Input struct to get the inputs used in the calculation.
* @param layer Output layer struct to store the results.
*/
void calc_w_r_vd_pl(ip_t* ip, layer_t* layer);
/**
* @brief Used to calculate the width of the trace.
*
* @param ip Input struct to get the required values.
* @param cs_area Cross sectional area of the trace.
* @return Trace width in type double.
*/
double calc_trace_width_mils(ip_t* ip, double* cs_area);
/**
* @brief Calculate the resistance of the trace. Resistivity gets converted to Ohm cm.
*
* @param ip Input struct to get the required values.
* @param cs_area Cross sectional area of the trace.
* @return Resistance in type double.
*/
double calc_resistance(ip_t* ip, double* cs_area);
/**
* @brief Calculate the Voltage drop.
*
* @param ip Input struct to get the values.
* @param resistance Resistance in Ohms.
* @return Voltage drop in type double.
*/
double calc_vdrop(ip_t* ip, double* resistance);
/**
* @brief Calculate the power loss.
*
* @param ip Input struct to get the values.
* @param vdrop Voltage drop in V.
* @return Power loss in type double.
*/
double calc_power_loss(ip_t* ip, double* vdrop);
/**
* @brief Outputted results when using the IPC2221.
*
* @param ip Input struct to store the inputs.
* @param op Output struct to store the outputs.
* @param file Buffer to output the strings.
*/
int output_results_IPC2221(ip_t* ip, op_t* op, FILE* file);
/**
* @brief Outputted results when using the IPC2152, Method A.
*
* @param ip Input struct to store the inputs.
* @param op Output struct to store the outputs.
* @param file Buffer to output the strings.
*/
int output_results_IPC2152_A(ip_t* ip, op_t* op, FILE* file);
/**
* @brief Outputted results when using the IPC2152, Method B.
*
* @param ip Input struct to store the inputs.
* @param op Output struct to store the outputs.
* @param file Buffer to output the strings.
*/
int output_results_IPC2152_B(ip_t* ip, op_t* op, FILE* file);
/**
* @brief Output the help string to the terminal.
*/
int output_help();