516 lines
16 KiB
JavaScript
516 lines
16 KiB
JavaScript
|
|
let Common = system.getScript("/driverlib/Common.js");
|
||
|
|
let Pinmux = system.getScript("/driverlib/pinmux.js");
|
||
|
|
|
||
|
|
/* Intro splash on GUI */
|
||
|
|
let longDescription = "CAN is a communication peripheral which is used " +
|
||
|
|
"when there is high noise in the signal bus. It uses a differential " +
|
||
|
|
"wire topology to reduce the common noise. This applicatoin provides " +
|
||
|
|
"a simplified interface to configure the different parameters of the " +
|
||
|
|
"peripheral such as bit rate, time quanta and test mode etc. ";
|
||
|
|
|
||
|
|
function onChangeUseLoopback(inst, ui)
|
||
|
|
{
|
||
|
|
if (inst.enableLoopback) {
|
||
|
|
ui.loopbackMode.hidden = false;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
ui.loopbackMode.hidden = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function onChangeEnableInterrupt(inst, ui)
|
||
|
|
{
|
||
|
|
if (inst.enableInterrupt) {
|
||
|
|
ui.registerInterrupts.hidden = false;
|
||
|
|
ui.interruptFlags.hidden = false;
|
||
|
|
ui.interruptLine.hidden = false;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
ui.registerInterrupts.hidden = true;
|
||
|
|
ui.interruptFlags.hidden = true;
|
||
|
|
ui.interruptLine.hidden = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var msgCountConfig = []
|
||
|
|
for (var msgCount = 1; msgCount <= 32; msgCount++)
|
||
|
|
{
|
||
|
|
msgCountConfig.push(
|
||
|
|
{
|
||
|
|
name: msgCount ,
|
||
|
|
displayName: msgCount.toString()
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
var SysClk_MHz = Common.SYSCLK_getMaxMHz();
|
||
|
|
var SysClk_Hz = SysClk_MHz * 1000000;
|
||
|
|
var bitTimeOptions = [];
|
||
|
|
for (var bitTime = 8; bitTime <= 25; bitTime++)
|
||
|
|
{
|
||
|
|
bitTimeOptions.push(
|
||
|
|
{
|
||
|
|
name: bitTime ,
|
||
|
|
displayName: bitTime.toString()
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
var tSeg1 = 0;
|
||
|
|
var tSeg2 = 0;
|
||
|
|
var sjw = 0;
|
||
|
|
var prescalerExtension = 0, prescaler = 0;
|
||
|
|
var bitTime = 8;
|
||
|
|
|
||
|
|
function calcBitTimeParam(bitRate)
|
||
|
|
{
|
||
|
|
for (var i = 17; i >= 0; i--)
|
||
|
|
{
|
||
|
|
bitTime = i + 8;
|
||
|
|
var brp = (SysClk_Hz/(bitRate*bitTime)), tProp = 2, tSync = 1, tPhase = bitTime - (tSync + tProp), phaseSeg1 = 0, phaseSeg2 = 0;
|
||
|
|
if((tPhase / 2) <= 8)
|
||
|
|
{
|
||
|
|
phaseSeg2 = tPhase / 2;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
phaseSeg2 = 8;
|
||
|
|
}
|
||
|
|
tSeg1 = ((tPhase - phaseSeg2) + tProp) - 1;
|
||
|
|
tSeg2 = phaseSeg2 - 1;
|
||
|
|
sjw = 0;
|
||
|
|
prescalerExtension = 0; prescaler = 0;
|
||
|
|
if(phaseSeg2 > 4)
|
||
|
|
{
|
||
|
|
sjw = 3;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
sjw = tSeg2;
|
||
|
|
}
|
||
|
|
prescalerExtension = parseInt((brp - 1) / 64);
|
||
|
|
prescaler = ((brp - 1) % 64);
|
||
|
|
if(Number.isInteger(brp))
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function onChangeBitRate(inst, ui)
|
||
|
|
{
|
||
|
|
SysClk_Hz = inst.sysClock*1000000;
|
||
|
|
calcBitTimeParam(inst.bitRate);
|
||
|
|
inst.bitTime = bitTime;
|
||
|
|
inst.bitRatePrescalerExtension = prescalerExtension;
|
||
|
|
inst.bitRatePrescaler = prescaler;
|
||
|
|
inst.bitTimeSeg1 = tSeg1;
|
||
|
|
inst.bitTimeSeg2 = tSeg2;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
calcBitTimeParam(500000);
|
||
|
|
|
||
|
|
function onChangeAutoCalc(inst, ui)
|
||
|
|
{
|
||
|
|
if(inst.bitTimeAutoCalc)
|
||
|
|
{
|
||
|
|
ui.bitTime.readOnly = true;
|
||
|
|
ui.bitTimeSeg1.readOnly = true;
|
||
|
|
ui.bitTimeSeg2.readOnly = true;
|
||
|
|
ui.bitRatePrescaler.readOnly = true;
|
||
|
|
ui.bitRatePrescalerExtension.readOnly = true;
|
||
|
|
ui.sjw.readOnly = true;
|
||
|
|
onChangeBitRate(inst, ui);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ui.bitTime.readOnly = false;
|
||
|
|
ui.bitTimeSeg1.readOnly = false;
|
||
|
|
ui.bitTimeSeg2.readOnly = false;
|
||
|
|
ui.bitRatePrescaler.readOnly = false;
|
||
|
|
ui.bitRatePrescalerExtension.readOnly = false;
|
||
|
|
ui.sjw.readOnly = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
let config = [
|
||
|
|
{
|
||
|
|
name: "GROUP_BR",
|
||
|
|
displayName: "Bit Rate Parameters",
|
||
|
|
config: [
|
||
|
|
{
|
||
|
|
name : "sysClock",
|
||
|
|
displayName : "Device SYSCLK MHz",
|
||
|
|
description : 'Device System Clock Frequency',
|
||
|
|
hidden : false,
|
||
|
|
default : SysClk_MHz,
|
||
|
|
onChange : onChangeBitRate,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "bitRate",
|
||
|
|
displayName : "Bit Rate Bps",
|
||
|
|
description : 'CAN bus bit rate',
|
||
|
|
hidden : false,
|
||
|
|
default : "500000",
|
||
|
|
onChange : onChangeBitRate,
|
||
|
|
options :[
|
||
|
|
{name: "1000000", displayName : "1000000"},
|
||
|
|
{name: "800000", displayName : "800000"},
|
||
|
|
{name: "500000", displayName : "500000"},
|
||
|
|
{name: "250000", displayName : "250000"},
|
||
|
|
{name: "125000", displayName : "125000"},
|
||
|
|
{name: "100000", displayName : "100000"},
|
||
|
|
{name: "50000", displayName : "50000"},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "bitTimeAutoCalc",
|
||
|
|
displayName : "Use Calculated Values for Bit Timing Parameters",
|
||
|
|
description : 'Use Calculated Values for Bit Timing Parameters',
|
||
|
|
hidden : false,
|
||
|
|
onChange : onChangeAutoCalc,
|
||
|
|
default : true,
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "bitTime",
|
||
|
|
displayName : "Bit Time Quanta (Tq)",
|
||
|
|
description : 'Number of time quanta per bit',
|
||
|
|
hidden : false,
|
||
|
|
default : bitTimeOptions[bitTime-8].name,
|
||
|
|
options : bitTimeOptions,
|
||
|
|
readOnly : true,
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "bitRatePrescalerExtension",
|
||
|
|
displayName : "Bit Rate Prescelar Extension",
|
||
|
|
description : 'Bit Rate Prescelar Extension',
|
||
|
|
hidden : false,
|
||
|
|
default : prescalerExtension,
|
||
|
|
readOnly : true,
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "bitRatePrescaler",
|
||
|
|
displayName : "Bit Rate Prescaler",
|
||
|
|
description : 'Bit Rate Prescaler',
|
||
|
|
hidden : false,
|
||
|
|
default : prescaler,
|
||
|
|
readOnly : true,
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "bitTimeSeg1",
|
||
|
|
displayName : "Bit Time segment before sample point (Tq)",
|
||
|
|
description : 'Bit Time segment before sample point (Tq)',
|
||
|
|
hidden : false,
|
||
|
|
default : tSeg1,
|
||
|
|
readOnly : true,
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "bitTimeSeg2",
|
||
|
|
displayName : "Bit Time segment after sample point (Tq)",
|
||
|
|
description : 'Bit Time segment after sample point (Tq)',
|
||
|
|
hidden : false,
|
||
|
|
default : tSeg2,
|
||
|
|
readOnly : true,
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "sjw",
|
||
|
|
displayName : "(Re)Synchronization Jump Width (Tq)",
|
||
|
|
description : '(Re)Synchronization Jump Width (Tq)',
|
||
|
|
hidden : false,
|
||
|
|
default : sjw,
|
||
|
|
readOnly : true,
|
||
|
|
|
||
|
|
},
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "enableLoopback",
|
||
|
|
displayName : "Enable Loopback",
|
||
|
|
description : 'Whether loopback mode to be enabled.',
|
||
|
|
hidden : false,
|
||
|
|
onChange : onChangeUseLoopback,
|
||
|
|
default : false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "loopbackMode",
|
||
|
|
displayName : "Loopback Mode",
|
||
|
|
description : 'Which loopback mode to use if enabled.',
|
||
|
|
hidden : true,
|
||
|
|
default : "CAN_TEST_SILENT",
|
||
|
|
options : [
|
||
|
|
{name: "CAN_TEST_SILENT", displayName : "Silent Mode"},
|
||
|
|
{name: "CAN_TEST_LBACK", displayName : "Internal Loopback Mode"},
|
||
|
|
{name: "CAN_TEST_EXL", displayName : "External Loopback Mode"},
|
||
|
|
],
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "GROUP_INT",
|
||
|
|
displayName: "Interrupts",
|
||
|
|
config: [
|
||
|
|
{
|
||
|
|
name : "enableInterrupt",
|
||
|
|
displayName : "Enable Interrupt",
|
||
|
|
description : 'To Enable CAN Interrupts.',
|
||
|
|
hidden : false,
|
||
|
|
onChange : onChangeEnableInterrupt,
|
||
|
|
default : false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "registerInterrupts",
|
||
|
|
displayName : "Register Interrupt Handler",
|
||
|
|
description : 'Whether or not to register interrupt handlers in the interrupt module.',
|
||
|
|
hidden : true,
|
||
|
|
default : false
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "interruptFlags",
|
||
|
|
displayName : "Enable Interrupts",
|
||
|
|
description : 'Which Interrupts to enable.',
|
||
|
|
hidden : true,
|
||
|
|
minSelections : 0,
|
||
|
|
default : [],
|
||
|
|
options : [
|
||
|
|
{name: "CAN_INT_ERROR", displayName : "Controller error condition "},
|
||
|
|
{name: "CAN_INT_STATUS", displayName : "Message transfer complete or bus error"},
|
||
|
|
{name: "CAN_INT_IE0", displayName : "Enable CAN line 0 Interrupts"},
|
||
|
|
{name: "CAN_INT_IE1", displayName : "Enable CAN line 1 Interrupts"},
|
||
|
|
],
|
||
|
|
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "interruptLine",
|
||
|
|
displayName : "Enable Global Interrupt Lines",
|
||
|
|
description : 'Which Interrupt lines to enable.',
|
||
|
|
hidden : true,
|
||
|
|
minSelections : 0,
|
||
|
|
default : [],
|
||
|
|
options : [
|
||
|
|
{name: "CAN_GLOBAL_INT_CANINT0", displayName : "Enable CAN Global Interrupt line 0"},
|
||
|
|
{name: "CAN_GLOBAL_INT_CANINT1", displayName : "Enable CAN Global Interrupt line 1"},
|
||
|
|
],
|
||
|
|
|
||
|
|
},
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
deprecated : true,
|
||
|
|
name : "msgObjs",
|
||
|
|
displayName : "Message Objects",
|
||
|
|
description : 'Message objects need to be configured',
|
||
|
|
hidden : false,
|
||
|
|
default : 0,
|
||
|
|
onChange : (inst, ui) => {
|
||
|
|
var convertedArray = []
|
||
|
|
for (var mO = 1; mO <= inst["msgObjs"]; mO++)
|
||
|
|
{
|
||
|
|
convertedArray.push(mO);
|
||
|
|
}
|
||
|
|
inst["msgObjsUsed"] = convertedArray;
|
||
|
|
}
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "msgObjsUsed",
|
||
|
|
displayName : "Message Objects used (1-32)",
|
||
|
|
description : 'Message objects need to be configured',
|
||
|
|
hidden : false,
|
||
|
|
minSelections : 0,
|
||
|
|
default : [],
|
||
|
|
options : msgCountConfig
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "useCase",
|
||
|
|
displayName : "PinMux Use Case",
|
||
|
|
description : 'Peripheral use case',
|
||
|
|
hidden : false,
|
||
|
|
default : 'ALL',
|
||
|
|
options : Pinmux.getPeripheralUseCaseNames("CAN"),
|
||
|
|
onChange : Pinmux.useCaseChanged,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name : "startModule",
|
||
|
|
displayName : "Start CAN module in CAN_init() function",
|
||
|
|
description : "Starts the CAN Module",
|
||
|
|
hidden : false,
|
||
|
|
default : true,
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
function moduleInstances(inst,ui)
|
||
|
|
{
|
||
|
|
let components = [];
|
||
|
|
|
||
|
|
var pinmuxQualMods = Pinmux.getGpioQualificationModInstDefinitions("CAN", inst)
|
||
|
|
for (var pinmuxQualMod of pinmuxQualMods)
|
||
|
|
{
|
||
|
|
pinmuxQualMod.args.padConfig = "PULLUP";
|
||
|
|
|
||
|
|
if(pinmuxQualMod.name.includes("rx"))
|
||
|
|
{
|
||
|
|
pinmuxQualMod.requiredArgs = {
|
||
|
|
qualMode : "GPIO_QUAL_ASYNC",
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
pinmuxQualMod.args.qualMode = "GPIO_QUAL_ASYNC";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
components = components.concat(pinmuxQualMods)
|
||
|
|
|
||
|
|
for(var i in inst.msgObjsUsed)
|
||
|
|
{
|
||
|
|
components = components.concat([
|
||
|
|
{
|
||
|
|
moduleName : "/driverlib/canMsgObj.js",
|
||
|
|
name : "msgObj"+inst.msgObjsUsed[i],
|
||
|
|
displayName: "Message Object "+inst.msgObjsUsed[i],
|
||
|
|
collapsed : true,
|
||
|
|
},
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
if (inst.enableInterrupt && inst.registerInterrupts)
|
||
|
|
{
|
||
|
|
components = components.concat([{
|
||
|
|
name: "can0Int",
|
||
|
|
displayName: "CAN Interrupt 0",
|
||
|
|
moduleName: "/driverlib/interrupt.js",
|
||
|
|
collapsed: true,
|
||
|
|
args: {
|
||
|
|
$name : inst.$name + "_0_INT",
|
||
|
|
int : "INT_" + inst.$name + "_0",
|
||
|
|
pinmuxPeripheralModule : "can",
|
||
|
|
driverlibInt: "INT_#0"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "can1Int",
|
||
|
|
displayName: "CAN Interrupt 1",
|
||
|
|
moduleName: "/driverlib/interrupt.js",
|
||
|
|
collapsed: true,
|
||
|
|
args: {
|
||
|
|
$name : inst.$name + "_1_INT",
|
||
|
|
int : "INT_" + inst.$name + "_1",
|
||
|
|
pinmuxPeripheralModule : "can",
|
||
|
|
driverlibInt: "INT_#1"
|
||
|
|
}
|
||
|
|
}]);
|
||
|
|
}
|
||
|
|
return components;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* ======== filterHardware ========
|
||
|
|
* Control RX, TX Pin usage by the user specified dataDirection.
|
||
|
|
*
|
||
|
|
* param component - hardware object describing signals and
|
||
|
|
* resources they're attached to
|
||
|
|
*
|
||
|
|
* returns Boolean indicating whether or not to allow the component to
|
||
|
|
* be assigned to an instance's $hardware config
|
||
|
|
*/
|
||
|
|
function filterHardware(component)
|
||
|
|
{
|
||
|
|
return (Common.typeMatches(component.type, ["CAN"]));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Common.onlyPinmux())
|
||
|
|
{
|
||
|
|
config = [config[config.length - 1]];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function onValidate(inst, validation) {
|
||
|
|
|
||
|
|
if ( inst.bitRatePrescaler >= 64 || inst.bitRatePrescaler < 0)
|
||
|
|
{
|
||
|
|
validation.logError(
|
||
|
|
"The Bit Rate Prescaler must be a number between 0 and 64",
|
||
|
|
inst, "bitRatePrescaler");
|
||
|
|
}
|
||
|
|
if ((inst.bitRatePrescalerExtension < 0) || (inst.bitRatePrescalerExtension >= 16))
|
||
|
|
{
|
||
|
|
validation.logError(
|
||
|
|
"The Bit Rate Prescaler Extension value must be a number between 0 and 16",
|
||
|
|
inst, "bitRatePrescalerExtension");
|
||
|
|
}
|
||
|
|
if ( inst.bitTimeSeg1 >= 16 || inst.bitTimeSeg1 <= 0)
|
||
|
|
{
|
||
|
|
validation.logError(
|
||
|
|
"The Bit Time segment before sampling must be a number between 1 and 16",
|
||
|
|
inst, "bitTimeSeg1");
|
||
|
|
}
|
||
|
|
if ( inst.bitTimeSeg2 >= 8 || inst.bitTimeSeg1 < 0)
|
||
|
|
{
|
||
|
|
validation.logError(
|
||
|
|
"The Bit Time segment after sampling must be a number between 0 and 8",
|
||
|
|
inst, "bitTimeSeg2");
|
||
|
|
}
|
||
|
|
if ( inst.sjw >= 4 || inst.sjw < 0)
|
||
|
|
{
|
||
|
|
validation.logError(
|
||
|
|
"(Re)Synchronization Jump Width must be a number between 0 and 4",
|
||
|
|
inst, "sjw");
|
||
|
|
}
|
||
|
|
if ( inst.sysClock != SysClk_MHz)
|
||
|
|
{
|
||
|
|
validation.logWarning(
|
||
|
|
"Sysclk Frequency is not the default value of " + String(SysClk_MHz),
|
||
|
|
inst, "sysClock");
|
||
|
|
}
|
||
|
|
if((String(inst.interruptFlags).includes("CAN_INT_IE0") || String(inst.interruptFlags).includes("CAN_INT_STATUS") || String(inst.interruptFlags).includes("CAN_INT_ERROR")) && !String(inst.interruptLine).includes("CAN_GLOBAL_INT_CANINT0"))
|
||
|
|
{
|
||
|
|
validation.logWarning("Line 0 Interrupts Enabled but Global Line 0 Not Enabled",
|
||
|
|
inst, "interruptLine");
|
||
|
|
}
|
||
|
|
if(String(inst.interruptFlags).includes("CAN_INT_IE1") && !String(inst.interruptLine).includes("CAN_GLOBAL_INT_CANINT1"))
|
||
|
|
{
|
||
|
|
validation.logWarning("Line 1 Interrupt Enabled but Global Line 1 Not Enabled",
|
||
|
|
inst, "interruptLine");
|
||
|
|
}
|
||
|
|
|
||
|
|
var pinmuxQualMods = Pinmux.getGpioQualificationModInstDefinitions("CAN", inst)
|
||
|
|
for (var pinmuxQualMod of pinmuxQualMods)
|
||
|
|
{
|
||
|
|
if ((inst[pinmuxQualMod.name].padConfig.includes("OD")) || (inst[pinmuxQualMod.name].padConfig.includes("INVERT")))
|
||
|
|
{
|
||
|
|
validation.logError("The open-drain and inverted pad configurations should not be used for the CAN module.", inst);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var canModule = {
|
||
|
|
peripheralName: "CAN",
|
||
|
|
displayName: "CAN",
|
||
|
|
maxInstances: Common.peripheralCount("CAN"),
|
||
|
|
defaultInstanceName: "myCAN",
|
||
|
|
description: "Controller Area Network Peripheral",
|
||
|
|
longDescription: (Common.getCollateralFindabilityList("DCAN")),
|
||
|
|
filterHardware : filterHardware,
|
||
|
|
moduleInstances : moduleInstances,
|
||
|
|
config: config,
|
||
|
|
templates: {
|
||
|
|
boardc : "/driverlib/can/can.board.c.xdt",
|
||
|
|
boardh : "/driverlib/can/can.board.h.xdt"
|
||
|
|
},
|
||
|
|
validate: onValidate,
|
||
|
|
pinmuxRequirements : Pinmux.canPinmuxRequirements
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
if (canModule.maxInstances <= 0)
|
||
|
|
{
|
||
|
|
delete canModule.pinmuxRequirements;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Pinmux.addCustomPinmuxEnumToConfig(canModule)
|
||
|
|
Pinmux.addPinMuxQualGroupToConfig(canModule)
|
||
|
|
}
|
||
|
|
|
||
|
|
exports = canModule;
|