@mchp-mcc/scf-pic8-opamp-v2 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +8 -0
- package/LICENSE.txt +21 -0
- package/Readme.md +15 -0
- package/lib/generated_module/src/index.js +11 -0
- package/output/autoCreator.js +1995 -0
- package/output/autoCreator.js.map +1 -0
- package/output/autoProcessor.js +1997 -0
- package/output/autoProcessor.js.map +1 -0
- package/output/creator.js +6851 -0
- package/output/creator.js.map +1 -0
- package/output/header-template.h.ftl +353 -0
- package/output/nullPrototype.json +43 -0
- package/output/processor.js +6851 -0
- package/output/processor.js.map +1 -0
- package/output/reducer.js +29783 -0
- package/output/reducer.js.map +1 -0
- package/output/source-template.c.ftl +149 -0
- package/package.json +172 -0
- package/src/Calculations.test.tsx +83 -0
- package/src/Calculations.tsx +20 -0
- package/src/CreatorFunctions.test.ts +214 -0
- package/src/CreatorFunctions.ts +48 -0
- package/src/DerivedData.test.tsx +1601 -0
- package/src/DerivedData.ts +507 -0
- package/src/GeneratorModel.ts +80 -0
- package/src/ImageDataURLs.ts +8 -0
- package/src/PinsLogic.test.ts +983 -0
- package/src/PinsLogic.ts +293 -0
- package/src/catalog.json +24 -0
- package/src/moduleConfig.json +650 -0
- package/src/opa-output-parameters.test.tsx +22 -0
- package/src/opa-output-parameters.tsx +95 -0
- package/src/pinsdata.json +81 -0
- package/src/reducer.test.ts +177 -0
- package/src/reducer.ts +29 -0
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import * as Processor from "@microchip/scf-common/lib/Processor";
|
|
2
|
+
import { ModuleConfig } from "@microchip/melody-automodule-interface";
|
|
3
|
+
import { Calculations } from "./Calculations";
|
|
4
|
+
import {
|
|
5
|
+
AppModel,
|
|
6
|
+
DerivedData,
|
|
7
|
+
DerivedFunctions,
|
|
8
|
+
} from "../generated_module/src/types/AutoModuleTypes";
|
|
9
|
+
import * as InterfaceTypes from "@microchip/scf-interface";
|
|
10
|
+
import * as opa from "./opa-output-parameters";
|
|
11
|
+
import { MyTemplateData, getGeneratorModel } from "./GeneratorModel";
|
|
12
|
+
import * as initializer_system from "@microchip/initializer-system";
|
|
13
|
+
import { intf_args, QueryAdapterKey } from "@microchip/pin-standard/lib/pin-standard";
|
|
14
|
+
import { Option } from "@microchip/scf-device";
|
|
15
|
+
import { getInputPinsData } from "./PinsLogic";
|
|
16
|
+
import { MyComponentNames } from "../generated_module/src/types";
|
|
17
|
+
import * as image from "./ImageDataURLs";
|
|
18
|
+
import { getPinsLogic } from "../generated_module/src/pins/PCPHelper";
|
|
19
|
+
import { getCFunctionValidator, PatternValidator } from "@microchip/scf-validators/lib";
|
|
20
|
+
|
|
21
|
+
export const getDerivedData = (dataModel: AppModel): DerivedData => {
|
|
22
|
+
if (dataModel) {
|
|
23
|
+
return new MyDerivedData(dataModel);
|
|
24
|
+
}
|
|
25
|
+
return new EmptyDerivedData();
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
//This data will be used at the creator stage and relies on only the state
|
|
29
|
+
export class EmptyDerivedData implements DerivedData {
|
|
30
|
+
getMyFunctions = (): DerivedFunctions => {
|
|
31
|
+
return {};
|
|
32
|
+
};
|
|
33
|
+
getModel = (): AppModel | undefined => {
|
|
34
|
+
return undefined;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//This data will be used at the processor stage
|
|
39
|
+
export class MyDerivedData implements DerivedData {
|
|
40
|
+
private dataModel: AppModel;
|
|
41
|
+
private myTemplateData: MyTemplateData<opa.API>;
|
|
42
|
+
private gainCalc: Calculations;
|
|
43
|
+
private cValidator: PatternValidator = getCFunctionValidator();
|
|
44
|
+
|
|
45
|
+
constructor(dataModel: AppModel) {
|
|
46
|
+
this.dataModel = dataModel;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getGainCalculator = (): Calculations => {
|
|
50
|
+
if (!this.gainCalc) {
|
|
51
|
+
this.gainCalc = new Calculations();
|
|
52
|
+
}
|
|
53
|
+
return this.gainCalc;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
getMyFunctions = (): DerivedFunctions => {
|
|
57
|
+
return {
|
|
58
|
+
getDynamicConfigData: this.getDynamicConfigData,
|
|
59
|
+
moduleName: this.getModuleName,
|
|
60
|
+
templateData: this.getMyTemplateData,
|
|
61
|
+
alerts: this.getMyAlerts,
|
|
62
|
+
["opa-output-parameters_payload"]: this.getOpaInterfaceProcessedPayload,
|
|
63
|
+
nonInvGain: this.calcNonInvGain,
|
|
64
|
+
invGain: this.calcInvGain,
|
|
65
|
+
initializer_system_results: this.initializer_system_results,
|
|
66
|
+
pin_standard_args: this.getPinstandardArgs,
|
|
67
|
+
doNotShow: (): boolean => false,
|
|
68
|
+
overrideDefaultValues: this.overrideDefaultValue,
|
|
69
|
+
customNameValidator: this.customNameValidator,
|
|
70
|
+
getCustomUiErrors: this.getCustomUiErrors,
|
|
71
|
+
isEnabled: this.isEnabled,
|
|
72
|
+
isVisible: this.isVisible,
|
|
73
|
+
getPinsLogic: getPinsLogic,
|
|
74
|
+
importName: this.friendlyImportName,
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
public getModel = (): AppModel => {
|
|
79
|
+
return this.dataModel;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
public getModuleName = (): string => {
|
|
83
|
+
return this.getModel().getHardware()?.getName() ?? "OPA";
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
private friendlyImportName = (importKey: string): string => {
|
|
87
|
+
if (importKey === "scf_pic8_opamp_v2") return "OpAmp Hardware";
|
|
88
|
+
if (importKey === "initializer_system") return "system.c Initialize()";
|
|
89
|
+
if (importKey === "pin_standard") return "Pins";
|
|
90
|
+
return importKey;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
private customNameValidator = (): any => {
|
|
94
|
+
return {
|
|
95
|
+
pattern: this.cValidator.getRjsfValidation().pattern,
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
private getCustomUiErrors = (componentName: string): Error[] | undefined => {
|
|
100
|
+
switch (componentName) {
|
|
101
|
+
case "customName":
|
|
102
|
+
return [
|
|
103
|
+
{
|
|
104
|
+
name: "pattern",
|
|
105
|
+
message: this.cValidator.getCustomErrorMessage(),
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
default:
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
private isEnabled = (componentName: string): any => {
|
|
114
|
+
if (componentName === "nssOpacon1") {
|
|
115
|
+
const customConfig = this.getModel().getComponentValue("customConfig");
|
|
116
|
+
const negChannel = this.getModel().getComponentValue("nchOpacon2");
|
|
117
|
+
if (
|
|
118
|
+
(customConfig === "Non-Inverting Programmable Gain Amplifier" ||
|
|
119
|
+
customConfig === "Inverting Programmable Gain Amplifier") &&
|
|
120
|
+
negChannel === "GSEL"
|
|
121
|
+
)
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return undefined;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
private isVisible = (componentName: string): any => {
|
|
128
|
+
if (componentName === "ptresOpacon4") {
|
|
129
|
+
const hwch = this.getModel().getComponentValue("hwchOpahwc") ?? "";
|
|
130
|
+
const hwcl = this.getModel().getComponentValue("hwclOpahwc") ?? "";
|
|
131
|
+
if (hwch.indexOf("detect") != -1 || hwcl.indexOf("detect") != -1) return true;
|
|
132
|
+
else return false;
|
|
133
|
+
}
|
|
134
|
+
return undefined;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
private getDynamicConfigData = (
|
|
138
|
+
config: ModuleConfig.MyModuleConfig<MyComponentNames>,
|
|
139
|
+
): ModuleConfig.MyModuleConfig<MyComponentNames> => {
|
|
140
|
+
const links: MyComponentNames[] = ["mindiLink"];
|
|
141
|
+
links.forEach((name) => {
|
|
142
|
+
const component = config.softwareData?.[name];
|
|
143
|
+
if (component?.type === "string" && component?.format === "url") {
|
|
144
|
+
component.urlDescription = "Mindi\u2122 Schematic";
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return config;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
private overrideDefaultValue = (componentName: string): any => {
|
|
151
|
+
const module: string = this.getModuleName();
|
|
152
|
+
if (componentName === "customName") return this.getModuleName();
|
|
153
|
+
|
|
154
|
+
if (componentName === "schematic") {
|
|
155
|
+
switch (this.getModel().getComponentValue("customConfig")) {
|
|
156
|
+
case "Direct Connection to Pins":
|
|
157
|
+
return image.DIRECT_CONN;
|
|
158
|
+
case "Unity Gain Buffer":
|
|
159
|
+
return image.UNITY_GAIN;
|
|
160
|
+
case "Non-Inverting Programmable Gain Amplifier":
|
|
161
|
+
return image.NON_INV_PGA;
|
|
162
|
+
case "Inverting Programmable Gain Amplifier":
|
|
163
|
+
return image.INV_PGA;
|
|
164
|
+
default:
|
|
165
|
+
return image.DIRECT_CONN;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (componentName === "mindiLink") {
|
|
169
|
+
switch (this.getModel().getComponentValue("customConfig")) {
|
|
170
|
+
case "Direct Connection to Pins":
|
|
171
|
+
return "https://kits.microchip.com/redirect/4/PIC18Q71-00";
|
|
172
|
+
case "Unity Gain Buffer":
|
|
173
|
+
return "https://kits.microchip.com/redirect/4/PIC18Q71-01";
|
|
174
|
+
case "Non-Inverting Programmable Gain Amplifier":
|
|
175
|
+
return "https://kits.microchip.com/redirect/4/PIC18Q71-02";
|
|
176
|
+
case "Inverting Programmable Gain Amplifier":
|
|
177
|
+
return "https://kits.microchip.com/redirect/4/PIC18Q71-03";
|
|
178
|
+
default:
|
|
179
|
+
return "https://kits.microchip.com/redirect/4/PIC18Q71-00";
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (componentName === "pchOpacon2") {
|
|
183
|
+
switch (this.getModel().getComponentValue("customConfig")) {
|
|
184
|
+
case "Direct Connection to Pins":
|
|
185
|
+
return module + "IN+";
|
|
186
|
+
case "Unity Gain Buffer":
|
|
187
|
+
return module + "IN+";
|
|
188
|
+
case "Non-Inverting Programmable Gain Amplifier":
|
|
189
|
+
return module + "IN+";
|
|
190
|
+
case "Inverting Programmable Gain Amplifier":
|
|
191
|
+
return "Vdd/2";
|
|
192
|
+
case "Custom Configuration":
|
|
193
|
+
return "Vss";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (componentName === "pssOpacon3") {
|
|
197
|
+
if (this.getModel().getComponentValue("customConfig")) return module + "IN0+";
|
|
198
|
+
}
|
|
199
|
+
if (componentName === "nchOpacon2") {
|
|
200
|
+
switch (this.getModel().getComponentValue("customConfig")) {
|
|
201
|
+
case "Direct Connection to Pins":
|
|
202
|
+
return module + "IN-";
|
|
203
|
+
case "Unity Gain Buffer":
|
|
204
|
+
return "No Connection";
|
|
205
|
+
case "Non-Inverting Programmable Gain Amplifier":
|
|
206
|
+
return "GSEL";
|
|
207
|
+
case "Inverting Programmable Gain Amplifier":
|
|
208
|
+
return "GSEL";
|
|
209
|
+
case "Custom Configuration":
|
|
210
|
+
return "No Connection";
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (componentName === "nssOpacon1") {
|
|
214
|
+
return this.getModel().getComponentValue("customConfig") ===
|
|
215
|
+
"Non-Inverting Programmable Gain Amplifier"
|
|
216
|
+
? "Vss"
|
|
217
|
+
: module + "IN0-";
|
|
218
|
+
}
|
|
219
|
+
if (componentName === "resonOpacon1") {
|
|
220
|
+
switch (this.getModel().getComponentValue("customConfig")) {
|
|
221
|
+
case "Non-Inverting Programmable Gain Amplifier":
|
|
222
|
+
return "Enabled";
|
|
223
|
+
case "Inverting Programmable Gain Amplifier":
|
|
224
|
+
return "Enabled";
|
|
225
|
+
default:
|
|
226
|
+
return "Disabled";
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (componentName === "gselOpacon1") {
|
|
230
|
+
if (this.getModel().getComponentValue("customConfig"))
|
|
231
|
+
return "R1 = 15R and R2 = 1R, R2/R1 = 0.07";
|
|
232
|
+
}
|
|
233
|
+
if (componentName === "fmsOpacon3") {
|
|
234
|
+
switch (this.getModel().getComponentValue("customConfig")) {
|
|
235
|
+
case "Non-Inverting Programmable Gain Amplifier":
|
|
236
|
+
return module + "OUT";
|
|
237
|
+
case "Inverting Programmable Gain Amplifier":
|
|
238
|
+
return module + "OUT";
|
|
239
|
+
default:
|
|
240
|
+
return "No Connection";
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (componentName === "ugOpacon0") {
|
|
244
|
+
return this.getModel().getComponentValue("customConfig") ===
|
|
245
|
+
"Unity Gain Buffer"
|
|
246
|
+
? "OPA Output"
|
|
247
|
+
: "OPAIN- pin";
|
|
248
|
+
}
|
|
249
|
+
return undefined;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
private getOpaInterfaceProcessedPayload = (): opa.ProcessedPayload => {
|
|
253
|
+
return {
|
|
254
|
+
moduleName: this.getModuleName(),
|
|
255
|
+
customName: this.dataModel.getComponentValue("customName"),
|
|
256
|
+
hasInterrupts: false,
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
private calcNonInvGain = (): string => {
|
|
261
|
+
const resSelect: string | undefined =
|
|
262
|
+
this.getModel().getComponentValue("gselOpacon1");
|
|
263
|
+
return this.getGainCalculator().calcNonInvGain(resSelect);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
private calcInvGain = (): string => {
|
|
267
|
+
const resSelect: string | undefined =
|
|
268
|
+
this.getModel().getComponentValue("gselOpacon1");
|
|
269
|
+
return this.getGainCalculator().calcInvGain(resSelect);
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
private getMyAlerts = (): Processor.Alert[] => {
|
|
273
|
+
const alerts: Processor.Alert[] = [];
|
|
274
|
+
const module: string = this.getModuleName();
|
|
275
|
+
const customConfigValue = this.getModel().getComponentValue("customConfig");
|
|
276
|
+
const posChannel = this.getModel().getComponentValue("pchOpacon2");
|
|
277
|
+
const negChannel = this.getModel().getComponentValue("nchOpacon2");
|
|
278
|
+
const posSrc = this.getModel().getComponentValue("pssOpacon3");
|
|
279
|
+
const posSrc0 = posSrc?.substring(0, posSrc.length - 1);
|
|
280
|
+
const negSrc = this.getModel().getComponentValue("nssOpacon1");
|
|
281
|
+
const negSrc0 = negSrc?.substring(0, negSrc.length - 1);
|
|
282
|
+
const feedbackMode = this.getModel().getComponentValue("fmsOpacon3");
|
|
283
|
+
|
|
284
|
+
switch (customConfigValue) {
|
|
285
|
+
case "Direct Connection to Pins": {
|
|
286
|
+
if (posChannel === "GSEL") {
|
|
287
|
+
alerts.push({
|
|
288
|
+
type: Processor.AlertTypes.Warning,
|
|
289
|
+
text: "Invalid selection for Positive Channel in this configuration",
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
if (negChannel === "GSEL") {
|
|
293
|
+
alerts.push({
|
|
294
|
+
type: Processor.AlertTypes.Warning,
|
|
295
|
+
text: "Invalid selection for Negative Channel in this configuration",
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
if (posChannel === module + "IN+" && negChannel === module + "IN-") {
|
|
299
|
+
if (posSrc0 === negSrc0) {
|
|
300
|
+
alerts.push({
|
|
301
|
+
type: Processor.AlertTypes.Warning,
|
|
302
|
+
text: "Both the Positive and Negative Sources are mapped to the same pin",
|
|
303
|
+
});
|
|
304
|
+
} else {
|
|
305
|
+
//do nothing
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
case "Unity Gain Buffer": {
|
|
311
|
+
if (posChannel === "GSEL") {
|
|
312
|
+
alerts.push({
|
|
313
|
+
type: Processor.AlertTypes.Warning,
|
|
314
|
+
text: "Invalid selection for Positive Channel in this configuration",
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
case "Non-Inverting Programmable Gain Amplifier": {
|
|
320
|
+
if (posChannel === "GSEL" || posChannel === "Vss") {
|
|
321
|
+
alerts.push({
|
|
322
|
+
type: Processor.AlertTypes.Warning,
|
|
323
|
+
text: "Invalid selection for Positive Channel in this configuration",
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
if (negChannel !== "GSEL") {
|
|
327
|
+
alerts.push({
|
|
328
|
+
type: Processor.AlertTypes.Warning,
|
|
329
|
+
text: "Invalid selection for Negative Channel in this configuration",
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
if (negSrc !== "Vss") {
|
|
333
|
+
alerts.push({
|
|
334
|
+
type: Processor.AlertTypes.Warning,
|
|
335
|
+
text: "Invalid selection for Negative Source in this configuration",
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
if (feedbackMode !== module + "OUT") {
|
|
339
|
+
alerts.push({
|
|
340
|
+
type: Processor.AlertTypes.Warning,
|
|
341
|
+
text: "Invalid selection for Feedback Mode Selection in this configuration",
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
case "Inverting Programmable Gain Amplifier": {
|
|
347
|
+
if (posChannel === "GSEL" || posChannel === "Vss") {
|
|
348
|
+
alerts.push({
|
|
349
|
+
type: Processor.AlertTypes.Warning,
|
|
350
|
+
text: "Invalid selection for Positive Channel in this configuration",
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
if (negChannel !== "GSEL") {
|
|
354
|
+
alerts.push({
|
|
355
|
+
type: Processor.AlertTypes.Warning,
|
|
356
|
+
text: "Invalid selection for Negative Channel in this configuration",
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
if (feedbackMode !== module + "OUT") {
|
|
360
|
+
alerts.push({
|
|
361
|
+
type: Processor.AlertTypes.Warning,
|
|
362
|
+
text: "Invalid selection for Feedback Mode Selection in this configuration",
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (posChannel?.indexOf("DAC") !== -1) {
|
|
370
|
+
const regexpNumber = /\d/;
|
|
371
|
+
const inst = posChannel?.match(regexpNumber);
|
|
372
|
+
if (!this.dataModel.getAssignedImport("DAC")) {
|
|
373
|
+
alerts.push({
|
|
374
|
+
type: Processor.AlertTypes.Warning,
|
|
375
|
+
text:
|
|
376
|
+
this.dataModel.getName() +
|
|
377
|
+
" uses DAC" +
|
|
378
|
+
inst +
|
|
379
|
+
" as Positive Channel. Ensure DAC" +
|
|
380
|
+
inst +
|
|
381
|
+
" has been configured.",
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (negChannel?.indexOf("DAC") !== -1) {
|
|
386
|
+
const regexpNumber = /\d/;
|
|
387
|
+
const inst = negChannel?.match(regexpNumber);
|
|
388
|
+
if (!this.dataModel.getAssignedImport("DAC")) {
|
|
389
|
+
alerts.push({
|
|
390
|
+
type: Processor.AlertTypes.Warning,
|
|
391
|
+
text:
|
|
392
|
+
this.dataModel.getName() +
|
|
393
|
+
" uses DAC" +
|
|
394
|
+
inst +
|
|
395
|
+
" as Negative Channel. Ensure DAC" +
|
|
396
|
+
inst +
|
|
397
|
+
" has been configured.",
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const hwOverrideSrc = this.dataModel.getComponentValue("orsOpaors") ?? "LFINTOSC";
|
|
403
|
+
const moduleIgnoreList = [
|
|
404
|
+
"OPAxORPPS",
|
|
405
|
+
"LFINTOSC",
|
|
406
|
+
"SOSC",
|
|
407
|
+
"Logic low",
|
|
408
|
+
"Logic high",
|
|
409
|
+
];
|
|
410
|
+
|
|
411
|
+
if (moduleIgnoreList.indexOf(hwOverrideSrc) != -1) {
|
|
412
|
+
//do nothing
|
|
413
|
+
} else {
|
|
414
|
+
alerts.push({
|
|
415
|
+
type: Processor.AlertTypes.Hint,
|
|
416
|
+
text: "Ensure that the module selected as Hardware Override Source is configured.",
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return alerts;
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
private getMyTemplateData = (): MyTemplateData<opa.API> => {
|
|
424
|
+
if (this.myTemplateData == undefined) {
|
|
425
|
+
this.myTemplateData = getGeneratorModel(
|
|
426
|
+
this.getModel(),
|
|
427
|
+
this.getPositiveSources(),
|
|
428
|
+
this.getNegativeSources(),
|
|
429
|
+
this.getHeaderFiles(),
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
return this.myTemplateData;
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
private getHeaderFiles = (): InterfaceTypes.HeaderFile[] => {
|
|
436
|
+
return [
|
|
437
|
+
{
|
|
438
|
+
name: this.getModuleName().toLowerCase() + ".h",
|
|
439
|
+
path: "../",
|
|
440
|
+
},
|
|
441
|
+
];
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
private getPinstandardArgs = (): intf_args => ({
|
|
445
|
+
queryAdapterMap: {
|
|
446
|
+
[QueryAdapterKey.ALLPINS]: "^OPA[0-9]$",
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
private initializer_system_results = (): initializer_system.Results => {
|
|
451
|
+
return {
|
|
452
|
+
initializer: {
|
|
453
|
+
name: this.getModuleName() + "_Initialize",
|
|
454
|
+
header: {
|
|
455
|
+
name: this.getModuleName().toLowerCase() + ".h",
|
|
456
|
+
path: "opa/",
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
private getPositiveSources = (): sourceSelect[] => {
|
|
463
|
+
const posSource = this.dataModel.getHardware()?.getPeripheral().registers.OPACON3
|
|
464
|
+
.settings.PSS.options;
|
|
465
|
+
|
|
466
|
+
let pinAttribs = this.dataModel.getComponentValue("cnameAttribforPosPins") ?? "";
|
|
467
|
+
if (typeof pinAttribs === "string") pinAttribs = JSON.parse(pinAttribs);
|
|
468
|
+
|
|
469
|
+
const pinPayload = this.dataModel.getImportValue("pin_standard");
|
|
470
|
+
const allPins = pinPayload?.[QueryAdapterKey.ALLPINS] ?? {};
|
|
471
|
+
const allPinsData = getInputPinsData(allPins, this.getModuleName());
|
|
472
|
+
|
|
473
|
+
const posSourceList = (posSource ?? []).map((o: Option) => ({
|
|
474
|
+
customName:
|
|
475
|
+
pinAttribs[allPinsData[o.alias]?.pinName]?.cname ??
|
|
476
|
+
allPinsData[o.alias]?.customName,
|
|
477
|
+
source: o.alias ?? "",
|
|
478
|
+
}));
|
|
479
|
+
return posSourceList;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
private getNegativeSources = (): sourceSelect[] => {
|
|
483
|
+
const negSource = this.dataModel.getHardware()?.getPeripheral().registers.OPACON1
|
|
484
|
+
.settings.NSS.options;
|
|
485
|
+
|
|
486
|
+
let pinAttribs = this.dataModel.getComponentValue("cnameAttribforNegPins") ?? "";
|
|
487
|
+
if (typeof pinAttribs === "string") pinAttribs = JSON.parse(pinAttribs);
|
|
488
|
+
|
|
489
|
+
const pinPayload = this.dataModel.getImportValue("pin_standard");
|
|
490
|
+
const allPins = pinPayload?.[QueryAdapterKey.ALLPINS] ?? {};
|
|
491
|
+
const allPinsData = getInputPinsData(allPins, this.getModuleName());
|
|
492
|
+
|
|
493
|
+
const negSourceList = (negSource ?? []).map((o: Option) => ({
|
|
494
|
+
customName:
|
|
495
|
+
pinAttribs[allPinsData[o.alias]?.pinName]?.cname ??
|
|
496
|
+
allPinsData[o.alias]?.customName ??
|
|
497
|
+
"Vss",
|
|
498
|
+
source: o.alias ?? "",
|
|
499
|
+
}));
|
|
500
|
+
return negSourceList;
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
export type sourceSelect = {
|
|
505
|
+
customName: string;
|
|
506
|
+
source: string;
|
|
507
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { AppModel } from "../generated_module/src/types/AutoModuleTypes";
|
|
2
|
+
import * as InterfaceTypes from "@microchip/scf-interface";
|
|
3
|
+
import { getOptionByAlias } from "@microchip/scf-device/lib/Setting";
|
|
4
|
+
|
|
5
|
+
export type MyTemplateData<API extends InterfaceTypes.CFunctions> = {
|
|
6
|
+
header: InterfaceTypes.HeaderFile;
|
|
7
|
+
moduleNameUpperCase: string;
|
|
8
|
+
moduleNameLowerCase: string;
|
|
9
|
+
componentName: string | undefined;
|
|
10
|
+
compiler: string;
|
|
11
|
+
tool: string;
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const getGeneratorModel = <API extends InterfaceTypes.CFunctions>(
|
|
16
|
+
model: AppModel,
|
|
17
|
+
posSourceModel: sourceSelect[],
|
|
18
|
+
negSourceModel1: sourceSelect[],
|
|
19
|
+
header: InterfaceTypes.HeaderFile[],
|
|
20
|
+
): MyTemplateData<API> => {
|
|
21
|
+
const customName_1 = model.getComponentValue("customName");
|
|
22
|
+
const moduleName = model.getName();
|
|
23
|
+
const registers = model.getRegisterValues();
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
moduleNameLowerCase: moduleName.toLowerCase(),
|
|
27
|
+
moduleNameUpperCase: moduleName.toUpperCase(),
|
|
28
|
+
componentName: customName_1,
|
|
29
|
+
moduleInstance: moduleName,
|
|
30
|
+
posSources: convertToTemplatePosSrc(model, posSourceModel),
|
|
31
|
+
negSources: convertToTemplateNegSrc(model, negSourceModel1),
|
|
32
|
+
|
|
33
|
+
header: header?.[0],
|
|
34
|
+
compiler: "XC8 v2.32",
|
|
35
|
+
tool: "MPLAB X v5.50",
|
|
36
|
+
...registers,
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type sourceTemplate = {
|
|
41
|
+
name: string;
|
|
42
|
+
value: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type sourceSelect = {
|
|
46
|
+
customName: string;
|
|
47
|
+
source: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const convertToTemplatePosSrc = (
|
|
51
|
+
model: AppModel,
|
|
52
|
+
source: sourceSelect[],
|
|
53
|
+
): sourceTemplate[] => {
|
|
54
|
+
const pss = model.getHardware()?.getPeripheral().registers.OPACON3.settings.PSS;
|
|
55
|
+
if (pss == undefined) {
|
|
56
|
+
return [];
|
|
57
|
+
} else {
|
|
58
|
+
return source.map((sourceData) => ({
|
|
59
|
+
name: sourceData.customName + "_pos",
|
|
60
|
+
value: getOptionByAlias(sourceData.source, pss)?.value ?? "",
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const convertToTemplateNegSrc = (
|
|
66
|
+
model: AppModel,
|
|
67
|
+
source: sourceSelect[],
|
|
68
|
+
): sourceTemplate[] => {
|
|
69
|
+
const nss = model.getHardware()?.getPeripheral().registers.OPACON1.settings.NSS;
|
|
70
|
+
if (nss == undefined) {
|
|
71
|
+
return [];
|
|
72
|
+
} else {
|
|
73
|
+
return source.map((sourceData) => ({
|
|
74
|
+
name: sourceData.customName.match(/Vss/)
|
|
75
|
+
? sourceData.customName
|
|
76
|
+
: sourceData.customName + "_neg",
|
|
77
|
+
value: getOptionByAlias(sourceData.source, nss)?.value ?? "",
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const DIRECT_CONN =
|
|
2
|
+
"data:image/png;base64,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";
|
|
3
|
+
export const UNITY_GAIN =
|
|
4
|
+
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATAAAABeBAMAAABWXFVeAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqUExURf///z09PQICAqqqqtTU1CUlJVlZWefn5xISEomJiZubm729vfb29nV1dR8w18cAAASySURBVGje7dnvSxtnAAfwb5ZLziQXSKpxlbYv4qxaQiFdqHPK4LShMjbBNkSs7sVFR9yUA+mcrmO+sFWJq4VoyzCuL651dk4txLSuP8IgnYjaTVDnHGP6v+y5xGgyY7W1xmflvkSRPLnkk+f3PQJKlChRokSJEiV0hXW2z0ZohKly5fh8brfZbM72ekVx/e/A0NiwozT80FlR0f7NocFWnM5w2OEYGwsE1tdFr9dLgBZ3je9qbjybajGtMP+ORVx7a2ui2muhBBZNYv8boQkGBabAFJgCe4NgxbTCRpUa+5/AuAZKYWxuFqUwW30jnbA85sganTCoa/x0wjDfbacThg4rTycM5/Nb6IRh6nSEThjOfkspjBusoxMGtj6LAtgfDjnD5KckD62t0f7FHGk8fJgvmkL5l40zm6Xos4aatcOGJWSzKUn03RKdMCxYg9te8JgGGNryty0B71IBQ9m2iTZEBwxneyN0wjDqorIpyRPLx+isMTDJe+1k2EjhGizuHBiPA2oBCxcvQcOjaMbtrj5wGAxJe+0kmLGO9aDWOWWfywTuCvDwZcJbPO4w57oqDh6WvNfehFWS2fcyjxm7C0bhzBnoTwiGPrBdMgyGKqQBlrTXjsO4tadkzJJKE1x45s+c4zm9oDMBn6cThrZCN0m3OzETRhABdILb0jnbp12EXjAKgJhOGLd8YozkpiMhJf6F6PqkXbzkjBhP1vQhVmM5GTy+SxOMG61N8crAX8CcHV8FyUSnea+9lsDIxUyBxg4xTbCp3lQ3AKw8YHsfVIPApoB+AsPg+KhfV/ukKz2wsp1vmVCZbccKMEa6YYvBD4OnGSjK5sEsHjys7QU3mYc58893Bl/93b5wlG7W9kPS8glf0RAI4qPtV0xH9gjT+6R9fM2Q+eip+N+iQVBtvRd71NsZ6d9+RfkeYan3/XuHRTAQr7Lf9SZu61NVx/Hl4qvDmF0Oy/YAK+c7soPcUhNulvUYwwLO416OXNICtdR/JxPznka22eNXD2UHUZQTicF+41PCIltbnizsF3Z3tueJTdtcbBc76lQ/5mHV6JokQ/ZPuXigYZn3hC2staRX1/NBge7apBCD/fN9KhgjxCfWQdc+h1LI6zmlq8KSao3hRb1JJYnc9V+DTAGwJBcPIsN+CyHWBq+uD9cy7GxeFMZI2hLH8NZjiCw7P+Xh6bGW+LZ6v2M8FBjitQKKDb4GEJhGeqyuKjebbRs11g+N9NxzlS3AKlnNXJfN5nc2YCpzYi7I/6K3cavVsb3E5I4nPi/TlJBhmP5sMVpjGT/7y0vDj2J9zCTDLLdCm7Dx8KNYU66kbkoTdjkjeymY/hN4tEFdlaiv0kjG+pY5O/M2MCOQB4GRXjcwuwHLkNisGGw6ZefnojNqhzWI1wLjLty/bqwd8YuG088kxgpd7wjpxEz3upvMY5qJnvcvtm/A1DdGTLtOF89fdA6753wYXTtEHvcaUIr7X/MYB35pkj/8ijiBc9DzlU3zH9/GA8aOH+SSK7vA1DW3QVdisF3O+g8NxtZ/Chph3H/ucamBpdxJUwCbuhGhElb2GibWg4BZ83lQCTsZBJ3hoUSJEiVKlLxp+RcOfYAxQu3JIwAAAABJRU5ErkJggg==";
|
|
5
|
+
export const NON_INV_PGA =
|
|
6
|
+
"data:image/png;base64,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";
|
|
7
|
+
export const INV_PGA =
|
|
8
|
+
"data:image/png;base64,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";
|