I just read the IP408 manual. It looks to me that it uses 8 different interrupt vectors, one for each line that can interrupt. They can all point to the same interrupt function. That means you need to put this call in a loop.
for (i=0; i<8; i++) {
if (ipmIntConnect(carrier, slot, intVec+i, intFuncC, numCards-1)) {
}
Mark
________________________________
From: Wang, SuYin Grass <grass at anl.gov>
Sent: Wednesday, March 31, 2021 2:51 PM
To: Mark Rivers
Cc: tech-talk at aps.anl.gov
Subject: Re: Question about ACROMAG IP-408
Hi Mark,
Thanks for the hint.
I added IP408 to the interrupt support list and adding the proper register map (1 and 2as listed below)
And I also change the interrupt Vector to 0xe1. As the IP408 only allow user to program the D7-D3.
initIpUnidig("Unidig1", 0, 0, 1, 0xe1, 0x0, 0x1)
It looks like the VxWorks always freeze if I have " writeIntEnableRegs();" (3 below)
There are no error from "ipmIntConnect(carrier, slot, intVec, intFuncC, numCards-1)"
But when I put some debugging printing in "IpUnidig::intFunc", there were nothing printed, so it looks like it didn't call the "IpUnidig::intFunc"
I am wondering if I missed anything?
Thanks!
Grass
====1. adding it to suportInterrupt==============
switch (model_) {
case UNIDIG_I_O_24I:
case UNIDIG_I_E:
case UNIDIG_I:
case UNIDIG_I_D:
case UNIDIG_I_O_24IO:
case UNIDIG_I_HV_16I8O:
case UNIDIG_I_O_12I12O:
case UNIDIG_I_HV_8I16O:
case ACROMAG_IP408_32:
supportsInterrupts_ = 1;
break;
default:
supportsInterrupts_ = 0;
break;
}
====2. adding the register map=====
case ACROMAG_ID:
switch (model_) {
case ACROMAG_IP408_32:
/* Different register layout */
regs_.inputRegisterLow = base;
regs_.inputRegisterHigh = base + 0x1;
regs_.outputRegisterLow = base + 0x2;
regs_.outputRegisterHigh = base + 0x3;
regs_.intEnableRegisterLow = base + 0x4;
regs_.intEnableRegisterHigh = NULL;
/*The controlRegister controls the interrupt type,
D0-D7 each bit is Ch0-Ch7. All bit set to 0 after reset.
1 means COS, 0 means H/L depends on the Poloarty */
regs_.controlRegister0 = base + 0x5;
*regs_.controlRegister0 = 0;
regs_.intPolarityRegisterLow = base + 0x6;
regs_.intPolarityRegisterHigh = NULL;
regs_.intPendingRegisterLow = base + 0x7;
regs_.intPendingRegisterHigh = NULL;
regs_.intClearRegisterLow = base + 0x7;
regs_.intClearRegisterHigh = NULL;
regs_.intVecRegister = base + 0x8;
break;
}
=====3. the VxWork would freeze if we have " writeIntEnableRegs();"below =====================================
if (supportsInterrupts_ && (intVec !=0)) {
/* Interrupt support */
/* Write to the interrupt polarity and enable registers */
*regs_.intVecRegister = intVec;
driverTable[numCards] = this;
numCards++;
if (ipmIntConnect(carrier, slot, intVec, intFuncC, numCards-1)) {
errlogPrintf("ipUnidig interrupt connect failure\n");
}
*regs_.intPolarityRegisterLow = (epicsUInt16)polarityMask_;
*regs_.intPolarityRegisterHigh = (epicsUInt16)(polarityMask_ >> 16);
writeIntEnableRegs();
/* Enable IPAC module interrupts and set module status. */
ipmIrqCmd(carrier, slot, 0, ipac_irqEnable);
ipmIrqCmd(carrier, slot, 0, ipac_statActive);
}
epicsAtExit(rebootCallbackC, this);
}
===============================================
________________________________
From: Mark Rivers <rivers at cars.uchicago.edu>
Sent: Monday, March 29, 2021 6:26 PM
To: Wang, SuYin Grass <grass at anl.gov>
Cc: tech-talk at aps.anl.gov <tech-talk at aps.anl.gov>
Subject: RE: Question about ACROMAG IP-408
Hi Grass,
The Acromag IP408 is a 32-channel card. The datasheet says the following:
Interrupts: Change-of-state and level on channels 0-7
Your model is defined in the driver with this line:
#define ACROMAG_IP408_32 0x03 /*ACROMAG IP408 32 CHANNEL DIGITAL IO */
In the constructor for the driver is this code:
switch (model_) {
case UNIDIG_I_O_24I:
case UNIDIG_I_E:
case UNIDIG_I:
case UNIDIG_I_D:
case UNIDIG_I_O_24IO:
case UNIDIG_I_HV_16I8O:
case UNIDIG_I_O_12I12O:
case UNIDIG_I_HV_8I16O:
supportsInterrupts_ = 1;
break;
default:
supportsInterrupts_ = 0;
break;
}
So you can see that your model falls into the “default” part of that switch statement, meaning the driver does not support interrupts for it.
So the card does support interrupts on the first 8 channels, but the driver does not currently support this. It would not be hard to add that support to the driver.
Mark
From: Tech-talk <tech-talk-bounces at aps.anl.gov> On Behalf Of Wang, SuYin Grass via Tech-talk
Sent: Monday, March 29, 2021 1:30 PM
To: tech-talk at aps.anl.gov
Subject: Question about ACROMAG IP-408
Hi,
I am wondering is anyone using ip-Unidig with ACROMAG IP-408 to get interrupt.
We are trying to use IP-408 to get an interrupt from a 1us TTL pulse with 1Hz rate.
We are running IP408 with TVME200, and using the example "EXAMPLE_ipUnidig.substitutions" came with ipUnidig module.
https://github.com/epics-modules/ipUnidig/blob/master/ipUnidigApp/iocsh/EXAMPLE_ipUnidig.substitutions
We found that the default setting turned the output on, so we cannot read the input.
therefore, I also turn the output off by changing the "STest:Unidig1Bo0.VAL" to 0.
After we turn the output off, we were able to see the input level change, if we change the input level for 5V to 0V, We can see the Unidig1Bi0 changed from High to Low, and vice versa.
However, with camonitor the "STest:Unidig1Bi0", We still cannot see the interrupt from the 1us pulse.
Now we are using a pulse generator to make the 1us pulse to a 10us pulse, but it doesn't help.
Is there anything that needs to be changed for IP408 to get an interrupt?
Thanks,
Grass
=============st.cmd ==============
ipacAddTVME200("602FB0")
ipacReport(2)
initIpUnidig("Unidig1", 0, 0, 1, 116, 0xffffff, 0xffffffff)
dbLoadTemplate("db/EXAMPLE_ipUnidig.substitutions", "P=STest:, PORT=Unidig1")
======================================
===ipacReport(2)==========================
IP Carrier 0: TEWS TVME200, 4 slots
C0 S0 : 0xa3/0x03 - Int0: level 4 Int1: level 5
ID = 0xd2006080, I/O = 0xd2006000, Mem = 0xb0000000
C0 S1 : No Module - Int0: level 2 Int1: level 1
ID = 0xd2006180, I/O = 0xd2006100, Mem = 0xb0800000
C0 S2 : No Module - Int0: level 4 Int1: level 5
ID = 0xd2006280, I/O = 0xd2006200, Mem = 0xb1000000
C0 S3 : No Module - Int0: level 2 Int1: level 1
ID = 0xd2006380, I/O = 0xd2006300, Mem = 0xb1800000
value = 0 = 0x0
=============================================